From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-yb1-xb2d.google.com (mail-yb1-xb2d.google.com [IPv6:2607:f8b0:4864:20::b2d]) by sourceware.org (Postfix) with ESMTPS id EF1C43858D37 for ; Sat, 10 Feb 2024 16:23:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EF1C43858D37 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org EF1C43858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::b2d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707582222; cv=none; b=JZdpotWCKqI3km4L/xpujrl/fagzcz16fgIbvZBNYotiYjqorOkPSeYGehkUTgUDd1gbUGfEHXp2mtyUvC69TRGTLEhrDS+rpDT8YQVq3esvRsMMVd99RelM4iP4zWL980iO0XmOcnJHc8tNGjbpme2M36gRGqxI0AIxoWJyYBM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707582222; c=relaxed/simple; bh=Ys2f13yU5cksDyqa0UCMwyvRpUfDpQXkkiL2zB8PpQQ=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=EG0pvLNQOL2kzaAWBXueUPcBlv9H9rGos7JBT50BsZ99LNj1hl0KFUge5UQVIQljIVhZob+AWY08QLT8x1FAc0M7VEI4l4WG+jHKs5fDNWfZOhNHISfSzFLTJeq9o1mittvX9KaagSQFzGFR8kviH/MemRP90CIE9+sWD+wDy4o= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-yb1-xb2d.google.com with SMTP id 3f1490d57ef6-dc754853524so1386776276.3 for ; Sat, 10 Feb 2024 08:23:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707582215; x=1708187015; darn=sourceware.org; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=nWkTFRznYsNNVmRZ+IKuT41CCiCnD4UMuLdALXB4oKU=; b=O76Vzi14IVjYO7Ng77cF3WEFYdbgLRcNGJjypTzW3LMhgh7vFxGRp3HZ6J9qUf3+7K jN7eS4DF0v3v49pHCtTmKdUWCKSPQd18ZpD75fD+9P1fawW2bxfJNKTwm6xnc8Alhfs+ F0oWTotncPUZcWoh6WCQfqU630+Ul+vqQGCwLO8QJuLfJl0R7qEO5TgC2+Be9x/unfTm zmGiZlImH6cJf6h5eAd4L7XoFZys2xTv7ikhImjJj7CkG2ULrnZkEjerKfpYZptoS1Nt xY+/Mdd/SOjSyrp8n8Rw54sFtCcUtqxc08Ybge1b+TUhX7uQrTZnB6NJ48hLTipsDNEj X0rA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707582215; x=1708187015; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nWkTFRznYsNNVmRZ+IKuT41CCiCnD4UMuLdALXB4oKU=; b=OIae3v8BVT55bAorSFcCbJYMSBLCI3wjqTTkAdzdY8i8ViNHMwdS76BR+BLCvayl/P HyvJpLZBK53kr+V2LtiGqKLAo9CY+P4WT75cg8YwiUVDZ+VjQzpW1zA8oo4PMnY7Pn3w KVryg2TYD4nMgsp39jrUXIv60tkMeQuKtFQFIrn79jANT3tlmGihd7/0owonOPsWSeLS IgRRUyzy5ASMAUaFd3eeudwUVGmUOlJxLrtllYUlcuEMRvuWWu7Uhk5FpqLw5hWiF/5I 0C+pMs1dVWvTwq8ZZDhbu5/SYF2+Qkp/lmSirfW5GTfQvbYRSekNDOQ80Z1gs4cl+K3g EztQ== X-Gm-Message-State: AOJu0YxaekYittD+XlT2MdLgpLqRyMgj51afk3eyd0NDO4xWI3zDaLUo amLiSKqjHYczQLaH3ould4KnBBkeXkG79OnAVL4noIOKynIXauCqQj2r6rDWVuEUjcvAKNQArmm mY5ZHae1xoCSgfDyHCxmvyh6vW/EBNXn2 X-Google-Smtp-Source: AGHT+IEFV7eegwzM7mwW/T7LrcZZGhhA0nlMFLsxNkzg0X950nUJQadKR8fwSDUI+LXGN+Pv96ROoPs+o7xSaycrCDs= X-Received: by 2002:a0d:e6c4:0:b0:604:b08c:348d with SMTP id p187-20020a0de6c4000000b00604b08c348dmr1838264ywe.1.1707582214471; Sat, 10 Feb 2024 08:23:34 -0800 (PST) MIME-Version: 1.0 References: <20240207124245.1797095-1-hjl.tools@gmail.com> In-Reply-To: From: "H.J. Lu" Date: Sat, 10 Feb 2024 08:22:58 -0800 Message-ID: Subject: Re: [PATCH v2] x86-64: Add R_X86_64_CODE_6_GOTTPOFF To: binutils@sourceware.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-3020.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Thu, Feb 8, 2024 at 3:41=E2=80=AFAM H.J. Lu wrote: > > On Wed, Feb 7, 2024 at 4:42=E2=80=AFAM H.J. Lu wrot= e: > > > > Changes in v2: > > > > Rewrite fx_tcbit, fx_tcbit2 and fx_tcbit3 usage to generate > > R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX, R_X86_64_CODE_4_GOTPCRELX, > > R_X86_64_CODE_4_GOTTPOFF, R_X86_64_CODE_4_GOTPC32_TLSDESC and > > R_X86_64_CODE_6_GOTTPOFF. > > > > --- > > For > > > > add %reg1, name@gottpoff(%rip), %reg2 > > add name@gottpoff(%rip), %reg1, %reg2 > > > > add > > > > #define R_X86_64_CODE_6_GOTTPOFF 50 > > > > if the instruction starts at 6 bytes before the relocation offset. > > They are similar to R_X86_64_GOTTPOFF. Linker can covert GOTTPOFF to > > > > add $name@tpoff, %reg1, %reg2 > > > > Rewrite fx_tcbit, fx_tcbit2 and fx_tcbit3 usage to generate > > R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX, R_X86_64_CODE_4_GOTPCRELX, > > R_X86_64_CODE_4_GOTTPOFF, R_X86_64_CODE_4_GOTPC32_TLSDESC and > > R_X86_64_CODE_6_GOTTPOFF. > > > > NB: There is no need to check BFD_RELOC_X86_64_CODE_4_GOTTPOFF in > > md_assemble since there is only BFD_RELOC_X86_64_GOTTPOFF at this > > stage, which will be converted to BFD_RELOC_X86_64_CODE_4_GOTTPOFF > > or BFD_RELOC_X86_64_CODE_6_GOTTPOFF in i386_validate_fix. > > > > 5 relocations: > > > > #define R_X86_64_CODE_5_GOTPCRELX 46 > > #define R_X86_64_CODE_5_GOTTPOFF 47 > > #define R_X86_64_CODE_5_GOTPC32_TLSDESC 48 > > #define R_X86_64_CODE_6_GOTPCRELX 49 > > #define R_X86_64_CODE_6_GOTPC32_TLSDESC 51 > > > > are added for completeness and they are unused. > > > > bfd/ > > > > * elf64-x86-64.c (x86_64_elf_howto_table): Add > > R_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTTPOFF, > > R_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPCRELX, > > R_X86_64_CODE_6_GOTTPOFF and R_X86_64_CODE_6_GOTPC32_TLSDESC. > > (R_X86_64_standard): Updated. > > (x86_64_reloc_map): Add R_X86_64_CODE_5_GOTPCRELX, > > R_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTPC32_TLSDESC, > > R_X86_64_CODE_6_GOTPCRELX, R_X86_64_CODE_6_GOTTPOFF and > > R_X86_64_CODE_6_GOTPC32_TLSDESC. > > (elf_x86_64_check_tls_transition): Handle > > R_X86_64_CODE_6_GOTTPOFF. > > (elf_x86_64_tls_transition): Likewise. > > (elf_x86_64_scan_relocs): Handle R_X86_64_CODE_6_GOTTPOFF. > > Issue an error for R_X86_64_CODE_5_GOTPCRELX, > > R_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTPC32_TLSDESC, > > R_X86_64_CODE_6_GOTPCRELX and R_X86_64_CODE_6_GOTPC32_TLSDESC. > > (elf_x86_64_relocate_section): Handle R_X86_64_CODE_6_GOTTPOFF. > > * reloc.c (bfd_reloc_code_real): Add > > BFD_RELOC_X86_64_CODE_5_GOTPCRELX, > > BFD_RELOC_X86_64_CODE_5_GOTTPOFF, > > BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC, > > BFD_RELOC_X86_64_CODE_6_GOTPCRELX, > > BFD_RELOC_X86_64_CODE_6_GOTTPOFF and > > BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC. > > * bfd-in2.h: Regenerated. > > * libbfd.h: Likewise. > > > > elfcpp/ > > > > * x86_64.h (R_X86_64_CODE_5_GOTPCRELX): New. > > (R_X86_64_CODE_5_GOTTPOFF): Likewise. > > (R_X86_64_CODE_5_GOTPC32_TLSDESC): Likewise. > > (R_X86_64_CODE_6_GOTPCRELX): Likewise. > > (R_X86_64_CODE_6_GOTTPOFF): Likewise. > > (R_X86_64_CODE_6_GOTPC32_TLSDESC): Likewise. > > > > gas/ > > > > * config/tc-i386.c (tc_i386_fix_adjustable): Handle > > BFD_RELOC_X86_64_CODE_6_GOTTPOFF. > > (md_assemble): Don't check BFD_RELOC_X86_64_CODE_4_GOTTPOFF. > > Allow "add %reg1, foo@gottpoff(%rip), %reg2". > > (output_disp): Handle BFD_RELOC_X86_64_CODE_6_GOTTPOFF. Rewrit= e > > setting fx_tcbitX bits for BFD_RELOC_X86_64_GOTTPOFF, > > BFD_RELOC_X86_64_GOTPC32_TLSDESC and BFD_RELOC_32_PCREL. > > (md_apply_fix): Handle BFD_RELOC_X86_64_CODE_6_GOTTPOFF. > > (i386_validate_fix): Rewrite fx_tcbitX bit checking for > > BFD_RELOC_X86_64_GOTTPOFF, BFD_RELOC_X86_64_GOTPC32_TLSDESC and > > BFD_RELOC_32_PCREL. > > (tc_gen_reloc): Handle BFD_RELOC_X86_64_CODE_6_GOTTPOFF. > > * testsuite/gas/i386/x86-64-gottpoff.d: Updated. > > * testsuite/gas/i386/x86-64-gottpoff.s: Add tests for > > "add %reg1, foo@gottpoff(%rip), %reg2" and > > "add foo@gottpoff(%rip), %reg, %reg2". > > > > gold/ > > > > * x86_64.cc (Target_x86_64::optimize_tls_reloc): Handle > > R_X86_64_CODE_6_GOTTPOFF. > > (Target_x86_64::Scan::get_reference_flags): Likewise. > > (Target_x86_64::Scan::local): Likewise. > > (Target_x86_64::Scan::global): Likewise. > > (Target_x86_64::Relocate::relocate): Likewise. > > (Target_x86_64::Relocate::relocate_tls): Likewise. > > (Target_x86_64::Relocate::tls_ie_to_le): Handle. > > R_X86_64_CODE_6_GOTTPOFF. > > * testsuite/x86_64_ie_to_le.s: Add tests for > > "add %reg1, foo@gottpoff(%rip), %reg2" and > > "add foo@gottpoff(%rip), %reg, %reg2". > > * testsuite/x86_64_ie_to_le.sh: Updated. > > > > include/ > > > > * elf/x86-64.h (elf_x86_64_reloc_type): Add > > R_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTTPOFF, > > R_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPCRELX, > > R_X86_64_CODE_6_GOTTPOFF and R_X86_64_CODE_6_GOTPC32_TLSDESC. > > > > ld/ > > > > * testsuite/ld-x86-64/tlsbindesc.s: Add R_X86_64_CODE_6_GOTTPOF= F > > tests. > > * testsuite/ld-x86-64/tlsbindesc.d: Updated. > > * testsuite/ld-x86-64/tlsbindesc.rd: Likewise. > > --- > > bfd/bfd-in2.h | 6 ++ > > bfd/elf64-x86-64.c | 113 ++++++++++++++++++++++- > > bfd/libbfd.h | 6 ++ > > bfd/reloc.c | 12 +++ > > elfcpp/x86_64.h | 24 +++++ > > gas/config/tc-i386.c | 102 +++++++++++++++----- > > gas/testsuite/gas/i386/x86-64-gottpoff.d | 4 + > > gas/testsuite/gas/i386/x86-64-gottpoff.s | 10 ++ > > gold/testsuite/x86_64_ie_to_le.s | 2 + > > gold/testsuite/x86_64_ie_to_le.sh | 2 + > > gold/x86_64.cc | 47 +++++++++- > > include/elf/x86-64.h | 20 ++++ > > ld/testsuite/ld-x86-64/tlsbindesc.dd | 24 +++++ > > ld/testsuite/ld-x86-64/tlsbindesc.rd | 36 ++++---- > > ld/testsuite/ld-x86-64/tlsbindesc.s | 8 ++ > > 15 files changed, 371 insertions(+), 45 deletions(-) > > > > diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h > > index 581d8fe0b3e..dbafcf8da36 100644 > > --- a/bfd/bfd-in2.h > > +++ b/bfd/bfd-in2.h > > @@ -3894,6 +3894,12 @@ enum bfd_reloc_code_real > > BFD_RELOC_X86_64_CODE_4_GOTPCRELX, > > BFD_RELOC_X86_64_CODE_4_GOTTPOFF, > > BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC, > > + BFD_RELOC_X86_64_CODE_5_GOTPCRELX, > > + BFD_RELOC_X86_64_CODE_5_GOTTPOFF, > > + BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC, > > + BFD_RELOC_X86_64_CODE_6_GOTPCRELX, > > + BFD_RELOC_X86_64_CODE_6_GOTTPOFF, > > + BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC, > > > > /* ns32k relocations. */ > > BFD_RELOC_NS32K_IMM_8, > > diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c > > index f1253751bbd..2ed120af780 100644 > > --- a/bfd/elf64-x86-64.c > > +++ b/bfd/elf64-x86-64.c > > @@ -179,12 +179,30 @@ static reloc_howto_type x86_64_elf_howto_table[] = =3D > > HOWTO(R_X86_64_CODE_4_GOTPC32_TLSDESC, 0, 4, 32, true, 0, > > complain_overflow_bitfield, bfd_elf_generic_reloc, > > "R_X86_64_CODE_4_GOTPC32_TLSDESC", false, 0, 0xffffffff, true), > > + HOWTO(R_X86_64_CODE_5_GOTPCRELX, 0, 4, 32, true, 0, > > + complain_overflow_signed, bfd_elf_generic_reloc, > > + "R_X86_64_CODE_5_GOTPCRELX", false, 0, 0xffffffff, true), > > + HOWTO(R_X86_64_CODE_5_GOTTPOFF, 0, 4, 32, true, 0, > > + complain_overflow_signed, bfd_elf_generic_reloc, > > + "R_X86_64_CODE_5_GOTTPOFF", false, 0, 0xffffffff, true), > > + HOWTO(R_X86_64_CODE_5_GOTPC32_TLSDESC, 0, 4, 32, true, 0, > > + complain_overflow_bitfield, bfd_elf_generic_reloc, > > + "R_X86_64_CODE_5_GOTPC32_TLSDESC", false, 0, 0xffffffff, true), > > + HOWTO(R_X86_64_CODE_6_GOTPCRELX, 0, 4, 32, true, 0, > > + complain_overflow_signed, bfd_elf_generic_reloc, > > + "R_X86_64_CODE_6_GOTPCRELX", false, 0, 0xffffffff, true), > > + HOWTO(R_X86_64_CODE_6_GOTTPOFF, 0, 4, 32, true, 0, > > + complain_overflow_signed, bfd_elf_generic_reloc, > > + "R_X86_64_CODE_6_GOTTPOFF", false, 0, 0xffffffff, true), > > + HOWTO(R_X86_64_CODE_6_GOTPC32_TLSDESC, 0, 4, 32, true, 0, > > + complain_overflow_bitfield, bfd_elf_generic_reloc, > > + "R_X86_64_CODE_6_GOTPC32_TLSDESC", false, 0, 0xffffffff, true), > > > > /* We have a gap in the reloc numbers here. > > R_X86_64_standard counts the number up to this point, and > > R_X86_64_vt_offset is the value to subtract from a reloc type of > > R_X86_64_GNU_VT* to form an index into this table. */ > > -#define R_X86_64_standard (R_X86_64_CODE_4_GOTPC32_TLSDESC + 1) > > +#define R_X86_64_standard (R_X86_64_CODE_6_GOTPC32_TLSDESC + 1) > > #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard= ) > > > > /* GNU extension to record C++ vtable hierarchy. */ > > @@ -256,6 +274,12 @@ static const struct elf_reloc_map x86_64_reloc_map= [] =3D > > { BFD_RELOC_X86_64_CODE_4_GOTPCRELX, R_X86_64_CODE_4_GOTPCRELX, }, > > { BFD_RELOC_X86_64_CODE_4_GOTTPOFF, R_X86_64_CODE_4_GOTTPOFF, }, > > { BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC, R_X86_64_CODE_4_GOTPC32_T= LSDESC, }, > > + { BFD_RELOC_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTPCRELX, }, > > + { BFD_RELOC_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTTPOFF, }, > > + { BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_5_GOTPC32_T= LSDESC, }, > > + { BFD_RELOC_X86_64_CODE_6_GOTPCRELX, R_X86_64_CODE_6_GOTPCRELX, }, > > + { BFD_RELOC_X86_64_CODE_6_GOTTPOFF, R_X86_64_CODE_6_GOTTPOFF, }, > > + { BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPC32_T= LSDESC, }, > > { BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, }, > > { BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, }, > > }; > > @@ -1283,6 +1307,23 @@ elf_x86_64_check_tls_transition (bfd *abfd, > > > > goto check_gottpoff; > > > > + case R_X86_64_CODE_6_GOTTPOFF: > > + /* Check transition from IE access model: > > + add %reg1, foo@gottpoff(%rip), %reg2 > > + where reg1/reg2 are one of r16 to r31. */ > > + > > + if (offset < 6 > > + || (offset + 4) > sec->size > > + || contents[offset - 6] !=3D 0x62) > > + return false; > > + > > + val =3D bfd_get_8 (abfd, contents + offset - 2); > > + if (val !=3D 0x01 && val !=3D 0x03) > > + return false; > > + > > + val =3D bfd_get_8 (abfd, contents + offset - 1); > > + return (val & 0xc7) =3D=3D 5; > > + > > case R_X86_64_GOTTPOFF: > > /* Check transition from IE access model: > > mov foo@gottpoff(%rip), %reg > > @@ -1417,6 +1458,7 @@ elf_x86_64_tls_transition (struct bfd_link_info *= info, bfd *abfd, > > case R_X86_64_TLSDESC_CALL: > > case R_X86_64_GOTTPOFF: > > case R_X86_64_CODE_4_GOTTPOFF: > > + case R_X86_64_CODE_6_GOTTPOFF: > > if (bfd_link_executable (info)) > > { > > if (h =3D=3D NULL) > > @@ -1464,6 +1506,8 @@ elf_x86_64_tls_transition (struct bfd_link_info *= info, bfd *abfd, > > /* Return TRUE if there is no transition. */ > > if (from_type =3D=3D to_type > > || (from_type =3D=3D R_X86_64_CODE_4_GOTTPOFF > > + && to_type =3D=3D R_X86_64_GOTTPOFF) > > + || (from_type =3D=3D R_X86_64_CODE_6_GOTTPOFF > > && to_type =3D=3D R_X86_64_GOTTPOFF)) > > return true; > > > > @@ -2177,6 +2221,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_lin= k_info *info, > > > > case R_X86_64_GOTTPOFF: > > case R_X86_64_CODE_4_GOTTPOFF: > > + case R_X86_64_CODE_6_GOTTPOFF: > > if (!bfd_link_executable (info)) > > info->flags |=3D DF_STATIC_TLS; > > /* Fall through */ > > @@ -2214,6 +2259,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_lin= k_info *info, > > break; > > case R_X86_64_GOTTPOFF: > > case R_X86_64_CODE_4_GOTTPOFF: > > + case R_X86_64_CODE_6_GOTTPOFF: > > tls_type =3D GOT_TLS_IE; > > break; > > case R_X86_64_GOTPC32_TLSDESC: > > @@ -2503,6 +2549,26 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_li= nk_info *info, > > } > > break; > > > > + case R_X86_64_CODE_5_GOTPCRELX: > > + case R_X86_64_CODE_5_GOTTPOFF: > > + case R_X86_64_CODE_5_GOTPC32_TLSDESC: > > + case R_X86_64_CODE_6_GOTPCRELX: > > + case R_X86_64_CODE_6_GOTPC32_TLSDESC: > > + { > > + /* These relocations are added only for completeness and > > + aren't be used. */ > > + if (h) > > + name =3D h->root.root.string; > > + else > > + name =3D bfd_elf_sym_name (abfd, symtab_hdr, isym, > > + NULL); > > + _bfd_error_handler > > + /* xgettext:c-format */ > > + (_("%pB: unsupported relocation %s against symbol `%s'"= ), > > + abfd, x86_64_elf_howto_table[r_type].name, name); > > + } > > + break; > > + > > /* This relocation describes the C++ object vtable hierarchy. > > Reconstruct it for later use during GC. */ > > case R_X86_64_GNU_VTINHERIT: > > @@ -3570,6 +3636,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, > > case R_X86_64_TLSDESC_CALL: > > case R_X86_64_GOTTPOFF: > > case R_X86_64_CODE_4_GOTTPOFF: > > + case R_X86_64_CODE_6_GOTTPOFF: > > tls_type =3D GOT_UNKNOWN; > > if (h =3D=3D NULL && local_got_offsets) > > tls_type =3D elf_x86_local_got_tls_type (input_bfd) [r_symn= dx]; > > @@ -3920,6 +3987,50 @@ elf_x86_64_relocate_section (bfd *output_bfd, > > contents + roff); > > continue; > > } > > + else if (r_type =3D=3D R_X86_64_CODE_6_GOTTPOFF) > > + { > > + /* IE->LE transition: > > + Originally it is > > + add %reg1, foo@gottpoff(%rip), %reg2 > > + or > > + add foo@gottpoff(%rip), %reg1, %reg2 > > + We change it into: > > + add $foo@tpoff, %reg1, %reg2 > > + */ > > + unsigned int reg, byte1; > > + unsigned int updated_byte1; > > + > > + if (roff < 6) > > + goto corrupt_input; > > + > > + /* Move the R bits to the B bits in EVEX payload > > + byte 1. */ > > + byte1 =3D bfd_get_8 (input_bfd, contents + roff - 5); > > + updated_byte1 =3D byte1; > > + > > + /* Set the R bits since they is inverted. */ > > + updated_byte1 |=3D 1 << 7 | 1 << 4; > > + > > + /* Update the B bits from the R bits. */ > > + if ((byte1 & (1 << 7)) =3D=3D 0) > > + updated_byte1 &=3D ~(1 << 5); > > + if ((byte1 & (1 << 4)) =3D=3D 0) > > + updated_byte1 |=3D 1 << 3; > > + > > + reg =3D bfd_get_8 (input_bfd, contents + roff - 1); > > + reg >>=3D 3; > > + > > + bfd_put_8 (output_bfd, updated_byte1, > > + contents + roff - 5); > > + bfd_put_8 (output_bfd, 0x81, > > + contents + roff - 2); > > + bfd_put_8 (output_bfd, 0xc0 | reg, > > + contents + roff - 1); > > + bfd_put_32 (output_bfd, > > + elf_x86_64_tpoff (info, relocation), > > + contents + roff); > > + continue; > > + } > > else > > BFD_ASSERT (false); > > } > > diff --git a/bfd/libbfd.h b/bfd/libbfd.h > > index ebd4f24149b..40bbe6a3886 100644 > > --- a/bfd/libbfd.h > > +++ b/bfd/libbfd.h > > @@ -1463,6 +1463,12 @@ static const char *const bfd_reloc_code_real_nam= es[] =3D { "@@uninitialized@@", > > "BFD_RELOC_X86_64_CODE_4_GOTPCRELX", > > "BFD_RELOC_X86_64_CODE_4_GOTTPOFF", > > "BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC", > > + "BFD_RELOC_X86_64_CODE_5_GOTPCRELX", > > + "BFD_RELOC_X86_64_CODE_5_GOTTPOFF", > > + "BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC", > > + "BFD_RELOC_X86_64_CODE_6_GOTPCRELX", > > + "BFD_RELOC_X86_64_CODE_6_GOTTPOFF", > > + "BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC", > > "BFD_RELOC_NS32K_IMM_8", > > "BFD_RELOC_NS32K_IMM_16", > > "BFD_RELOC_NS32K_IMM_32", > > diff --git a/bfd/reloc.c b/bfd/reloc.c > > index e74cbd75e96..7583b7fd552 100644 > > --- a/bfd/reloc.c > > +++ b/bfd/reloc.c > > @@ -2481,6 +2481,18 @@ ENUMX > > BFD_RELOC_X86_64_CODE_4_GOTTPOFF > > ENUMX > > BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC > > +ENUMX > > + BFD_RELOC_X86_64_CODE_5_GOTPCRELX > > +ENUMX > > + BFD_RELOC_X86_64_CODE_5_GOTTPOFF > > +ENUMX > > + BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC > > +ENUMX > > + BFD_RELOC_X86_64_CODE_6_GOTPCRELX > > +ENUMX > > + BFD_RELOC_X86_64_CODE_6_GOTTPOFF > > +ENUMX > > + BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC > > ENUMDOC > > x86-64/elf relocations. > > > > diff --git a/elfcpp/x86_64.h b/elfcpp/x86_64.h > > index 135f339fccf..5d254ce483b 100644 > > --- a/elfcpp/x86_64.h > > +++ b/elfcpp/x86_64.h > > @@ -110,6 +110,30 @@ enum > > // descriptor in GOT if the > > // instruction starts at 4 byte= s > > // before the relocation offset= . > > + R_X86_64_CODE_5_GOTPCRELX =3D 46, // 32 bit signed PC relative offse= t to > > + // GOT if the instruction starts at 5 > > + // bytes before the relocation offset= , > > + // relaxable. > > + R_X86_64_CODE_5_GOTTPOFF =3D 47, // 32 bit signed PC relative offse= t to > > + // GOT entry for IE symbol if the > > + // instruction starts at 5 bytes befo= re > > + // the relocation offset. > > + R_X86_64_CODE_5_GOTPC32_TLSDESC =3D 48, // 32-bit PC relative to TLS > > + // descriptor in GOT if the > > + // instruction starts at 5 byte= s > > + // before the relocation offset= . > > + R_X86_64_CODE_6_GOTPCRELX =3D 49, // 32 bit signed PC relative offse= t to > > + // GOT if the instruction starts at 6 > > + // bytes before the relocation offset= , > > + // relaxable. > > + R_X86_64_CODE_6_GOTTPOFF =3D 50, // 32 bit signed PC relative offse= t to > > + // GOT entry for IE symbol if the > > + // instruction starts at 6 bytes befo= re > > + // the relocation offset. > > + R_X86_64_CODE_6_GOTPC32_TLSDESC =3D 51, // 32-bit PC relative to TLS > > + // descriptor in GOT if the > > + // instruction starts at 6 byte= s > > + // before the relocation offset= . > > // GNU vtable garbage collection extensions. > > R_X86_64_GNU_VTINHERIT =3D 250, > > R_X86_64_GNU_VTENTRY =3D 251 > > diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c > > index 50d890c4481..9e7bb1dd4d6 100644 > > --- a/gas/config/tc-i386.c > > +++ b/gas/config/tc-i386.c > > @@ -3648,6 +3648,7 @@ tc_i386_fix_adjustable (fixS *fixP) > > || fixP->fx_r_type =3D=3D BFD_RELOC_X86_64_DTPOFF64 > > || fixP->fx_r_type =3D=3D BFD_RELOC_X86_64_GOTTPOFF > > || fixP->fx_r_type =3D=3D BFD_RELOC_X86_64_CODE_4_GOTTPOFF > > + || fixP->fx_r_type =3D=3D BFD_RELOC_X86_64_CODE_6_GOTTPOFF > > || fixP->fx_r_type =3D=3D BFD_RELOC_X86_64_TPOFF32 > > || fixP->fx_r_type =3D=3D BFD_RELOC_X86_64_TPOFF64 > > || fixP->fx_r_type =3D=3D BFD_RELOC_X86_64_GOTOFF64 > > @@ -6795,10 +6796,19 @@ md_assemble (char *line) > > for (j =3D i.imm_operands; j < i.operands; ++j) > > switch (i.reloc[j]) > > { > > + case BFD_RELOC_X86_64_GOTTPOFF: > > + if (i.tm.mnem_off =3D=3D MN_add > > + && i.tm.opcode_space =3D=3D SPACE_EVEXMAP4 > > + && i.mem_operands =3D=3D 1 > > + && i.base_reg > > + && i.base_reg->reg_num =3D=3D RegIP > > + && i.tm.operand_types[0].bitfield.class =3D=3D Reg > > + && i.tm.operand_types[2].bitfield.class =3D=3D Reg) > > + /* Allow APX: add %reg1, foo@gottpoff(%rip), %reg2. */ > > + break; > > + /* Fall through. */ > > case BFD_RELOC_386_TLS_GOTIE: > > case BFD_RELOC_386_TLS_LE_32: > > - case BFD_RELOC_X86_64_GOTTPOFF: > > - case BFD_RELOC_X86_64_CODE_4_GOTTPOFF: > > case BFD_RELOC_X86_64_TLSLD: > > as_bad (_("TLS relocation cannot be used with `%s'"), insn_= name (&i.tm)); > > return; > > @@ -12040,6 +12050,7 @@ output_disp (fragS *insn_start_frag, offsetT in= sn_start_off) > > case BFD_RELOC_X86_64_TLSLD: > > case BFD_RELOC_X86_64_GOTTPOFF: > > case BFD_RELOC_X86_64_CODE_4_GOTTPOFF: > > + case BFD_RELOC_X86_64_CODE_6_GOTTPOFF: > > case BFD_RELOC_X86_64_GOTPC32_TLSDESC: > > case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC: > > case BFD_RELOC_X86_64_TLSDESC_CALL: > > @@ -12056,9 +12067,30 @@ output_disp (fragS *insn_start_frag, offsetT i= nsn_start_off) > > && !i.prefix[ADDR_PREFIX]) > > fixP->fx_signed =3D 1; > > > > - /* Set fx_tcbit3 for REX2 prefix. */ > > - if (is_apx_rex2_encoding ()) > > - fixP->fx_tcbit3 =3D 1; > > + if (reloc_type =3D=3D BFD_RELOC_X86_64_GOTTPOFF > > + && i.tm.opcode_space =3D=3D SPACE_EVEXMAP4) > > + { > > + /* Only "add %reg1, foo@gottpoff(%rip), %reg2" is > > + allowed in md_assemble. Set fx_tcbit2 for EVEX > > + prefix. */ > > + fixP->fx_tcbit2 =3D 1; > > + continue; > > + } > > + > > + if (i.base_reg && i.base_reg->reg_num =3D=3D RegIP) > > + { > > + if (reloc_type =3D=3D BFD_RELOC_X86_64_GOTPC32_TLSDES= C) > > + { > > + /* Set fx_tcbit for REX2 prefix. */ > > + if (is_apx_rex2_encoding ()) > > + fixP->fx_tcbit =3D 1; > > + continue; > > + } > > + } > > + /* In 64-bit, i386_validate_fix updates only (%rip) > > + relocations. */ > > + else if (object_64bit) > > + continue; > > > > /* Check for "call/jmp *mem", "mov mem, %reg", > > "test %reg, mem" and "binop mem, %reg" where binop > > @@ -12083,10 +12115,22 @@ output_disp (fragS *insn_start_frag, offsetT = insn_start_off) > > { > > if (object_64bit) > > { > > - fixP->fx_tcbit =3D i.rex !=3D 0; > > - if (i.base_reg > > - && (i.base_reg->reg_num =3D=3D RegIP)) > > - fixP->fx_tcbit2 =3D 1; > > + if (reloc_type =3D=3D BFD_RELOC_X86_64_GOTTPOFF) > > + { > > + /* Set fx_tcbit for REX2 prefix. */ > > + if (is_apx_rex2_encoding ()) > > + fixP->fx_tcbit =3D 1; > > + } > > + else > > + { > > + /* Set fx_tcbit3 for REX2 prefix. */ > > + if (is_apx_rex2_encoding ()) > > + fixP->fx_tcbit3 =3D 1; > > + else if (i.rex) > > + fixP->fx_tcbit2 =3D 1; > > + else > > + fixP->fx_tcbit =3D 1; > > + } > > } > > else > > fixP->fx_tcbit2 =3D 1; > > @@ -15563,6 +15607,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT se= g ATTRIBUTE_UNUSED) > > case BFD_RELOC_X86_64_TLSLD: > > case BFD_RELOC_X86_64_GOTTPOFF: > > case BFD_RELOC_X86_64_CODE_4_GOTTPOFF: > > + case BFD_RELOC_X86_64_CODE_6_GOTTPOFF: > > case BFD_RELOC_X86_64_GOTPC32_TLSDESC: > > case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC: > > value =3D 0; /* Fully resolved at runtime. No addend. */ > > @@ -17144,13 +17189,27 @@ i386_validate_fix (fixS *fixp) > > && (!S_IS_DEFINED (fixp->fx_addsy) > > || S_IS_EXTERNAL (fixp->fx_addsy)); > > > > - if (fixp->fx_tcbit3) > > + /* BFD_RELOC_X86_64_GOTTPOFF: > > + 1. fx_tcbit -> BFD_RELOC_X86_64_CODE_4_GOTTPOFF > > + 2. fx_tcbit2 -> BFD_RELOC_X86_64_CODE_6_GOTTPOFF > > + BFD_RELOC_X86_64_GOTPC32_TLSDESC: > > + 1. fx_tcbit -> BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC > > + BFD_RELOC_32_PCREL: > > + 1. fx_tcbit -> BFD_RELOC_X86_64_GOTPCRELX > > + 2. fx_tcbit2 -> BFD_RELOC_X86_64_REX_GOTPCRELX > > + 3. fx_tcbit3 -> BFD_RELOC_X86_64_CODE_4_GOTPCRELX > > + 4. else -> BFD_RELOC_X86_64_GOTPCREL > > + */ > > + if (fixp->fx_r_type =3D=3D BFD_RELOC_X86_64_GOTTPOFF) > > { > > - if (fixp->fx_r_type =3D=3D BFD_RELOC_X86_64_GOTTPOFF) > > + if (fixp->fx_tcbit) > > fixp->fx_r_type =3D BFD_RELOC_X86_64_CODE_4_GOTTPOFF; > > - else if (fixp->fx_r_type =3D=3D BFD_RELOC_X86_64_GOTPC32_TLSDESC= ) > > - fixp->fx_r_type =3D BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC; > > + else if (fixp->fx_tcbit2) > > + fixp->fx_r_type =3D BFD_RELOC_X86_64_CODE_6_GOTTPOFF; > > } > > + else if (fixp->fx_r_type =3D=3D BFD_RELOC_X86_64_GOTPC32_TLSDESC > > + && fixp->fx_tcbit) > > + fixp->fx_r_type =3D BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC; > > #endif > > > > if (fixp->fx_subsy) > > @@ -17162,15 +17221,12 @@ i386_validate_fix (fixS *fixp) > > if (!object_64bit) > > abort (); > > #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) > > - if (fixp->fx_tcbit2) > > - { > > - if (fixp->fx_tcbit3) > > - fixp->fx_r_type =3D BFD_RELOC_X86_64_CODE_4_GOTPCRE= LX; > > - else > > - fixp->fx_r_type =3D (fixp->fx_tcbit > > - ? BFD_RELOC_X86_64_REX_GOTPCRELX > > - : BFD_RELOC_X86_64_GOTPCRELX); > > - } > > + if (fixp->fx_tcbit) > > + fixp->fx_r_type =3D BFD_RELOC_X86_64_GOTPCRELX; > > + else if (fixp->fx_tcbit2) > > + fixp->fx_r_type =3D BFD_RELOC_X86_64_REX_GOTPCRELX; > > + else if (fixp->fx_tcbit3) > > + fixp->fx_r_type =3D BFD_RELOC_X86_64_CODE_4_GOTPCRELX; > > else > > #endif > > fixp->fx_r_type =3D BFD_RELOC_X86_64_GOTPCREL; > > @@ -17296,6 +17352,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSE= D, fixS *fixp) > > case BFD_RELOC_X86_64_DTPOFF64: > > case BFD_RELOC_X86_64_GOTTPOFF: > > case BFD_RELOC_X86_64_CODE_4_GOTTPOFF: > > + case BFD_RELOC_X86_64_CODE_6_GOTTPOFF: > > case BFD_RELOC_X86_64_TPOFF32: > > case BFD_RELOC_X86_64_TPOFF64: > > case BFD_RELOC_X86_64_GOTOFF64: > > @@ -17440,6 +17497,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSE= D, fixS *fixp) > > case BFD_RELOC_X86_64_TLSLD: > > case BFD_RELOC_X86_64_GOTTPOFF: > > case BFD_RELOC_X86_64_CODE_4_GOTTPOFF: > > + case BFD_RELOC_X86_64_CODE_6_GOTTPOFF: > > case BFD_RELOC_X86_64_GOTPC32_TLSDESC: > > case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC: > > case BFD_RELOC_X86_64_TLSDESC_CALL: > > diff --git a/gas/testsuite/gas/i386/x86-64-gottpoff.d b/gas/testsuite/g= as/i386/x86-64-gottpoff.d > > index d42abccc6d9..f2c039abe72 100644 > > --- a/gas/testsuite/gas/i386/x86-64-gottpoff.d > > +++ b/gas/testsuite/gas/i386/x86-64-gottpoff.d > > @@ -16,4 +16,8 @@ Disassembly of section .text: > > +[a-f0-9]+: 48 8b 05 00 00 00 00 mov 0x0\(%rip\),%rax = # 2c <_start\+0x2c> 28: R_X86_64_GOTTPOFF foo-0x4 > > +[a-f0-9]+: d5 48 03 05 00 00 00 00 add 0x0\(%rip\),%r16= # 34 <_start\+0x34> 30: R_X86_64_CODE_4_GOTTPOFF foo-0x4 > > +[a-f0-9]+: d5 48 8b 25 00 00 00 00 mov 0x0\(%rip\),%r20= # 3c <_start\+0x3c> 38: R_X86_64_CODE_4_GOTTPOFF foo-0x4 > > + +[a-f0-9]+: 62 74 fc 10 01 05 00 00 00 00 add %r8,0x0\(%rip\),= %r16 # 46 <_start\+0x46> 42: R_X86_64_CODE_6_GOTTPOFF foo-0x4 > > + +[a-f0-9]+: 62 f4 9c 18 03 05 00 00 00 00 add 0x0\(%rip\),%rax= ,%r12 # 50 <_start\+0x50> 4c: R_X86_64_CODE_6_GOTTPOFF foo-0x4 > > + +[a-f0-9]+: 62 74 fc 10 01 05 00 00 00 00 add %r8,0x0\(%rip\),= %r16 # 5a <_start\+0x5a> 56: R_X86_64_CODE_6_GOTTPOFF foo-0x4 > > + +[a-f0-9]+: 62 f4 9c 18 03 05 00 00 00 00 add 0x0\(%rip\),%rax= ,%r12 # 64 <_start\+0x64> 60: R_X86_64_CODE_6_GOTTPOFF foo-0x4 > > #pass > > diff --git a/gas/testsuite/gas/i386/x86-64-gottpoff.s b/gas/testsuite/g= as/i386/x86-64-gottpoff.s > > index 6f8f9d1480c..0335ec5debf 100644 > > --- a/gas/testsuite/gas/i386/x86-64-gottpoff.s > > +++ b/gas/testsuite/gas/i386/x86-64-gottpoff.s > > @@ -13,3 +13,13 @@ _start: > > > > addq r16, QWORD PTR [rip + foo@GOTTPOFF] > > movq r20, QWORD PTR [rip + foo@GOTTPOFF] > > + > > + .att_syntax prefix > > + > > + addq %r8, foo@GOTTPOFF(%rip), %r16 > > + addq foo@GOTTPOFF(%rip), %rax, %r12 > > + > > + .intel_syntax noprefix > > + > > + addq r16, QWORD PTR [rip + foo@GOTTPOFF], r8 > > + addq r12, rax, QWORD PTR [rip + foo@GOTTPOFF] > > diff --git a/gold/testsuite/x86_64_ie_to_le.s b/gold/testsuite/x86_64_i= e_to_le.s > > index c5752068866..bd0643dc87f 100644 > > --- a/gold/testsuite/x86_64_ie_to_le.s > > +++ b/gold/testsuite/x86_64_ie_to_le.s > > @@ -7,6 +7,8 @@ _start: > > movq foo@gottpoff(%rip), %rax > > addq foo@gottpoff(%rip), %r16 > > movq foo@gottpoff(%rip), %r20 > > + addq %r30, foo@gottpoff(%rip), %r8 > > + addq foo@gottpoff(%rip), %rax, %r20 > > .size _start, .-_start > > .section .tdata,"awT",@progbits > > .align 4 > > diff --git a/gold/testsuite/x86_64_ie_to_le.sh b/gold/testsuite/x86_64_= ie_to_le.sh > > index 9d2e082f3e0..5308712ddbd 100755 > > --- a/gold/testsuite/x86_64_ie_to_le.sh > > +++ b/gold/testsuite/x86_64_ie_to_le.sh > > @@ -27,3 +27,5 @@ grep -q "add[ \t]\+\$0x[a-f0-9]\+,%r12" x86_64_ie_to_= le.stdout > > grep -q "mov[ \t]\+\$0x[a-f0-9]\+,%rax" x86_64_ie_to_le.stdout > > grep -q "add[ \t]\+\$0x[a-f0-9]\+,%r16" x86_64_ie_to_le.stdout > > grep -q "mov[ \t]\+\$0x[a-f0-9]\+,%r20" x86_64_ie_to_le.stdout > > +grep -q "add[ \t]\+\$0x[a-f0-9]\+,%r30,%r8" x86_64_ie_to_le.stdout > > +grep -q "add[ \t]\+\$0x[a-f0-9]\+,%rax,%r20" x86_64_ie_to_le.stdout > > diff --git a/gold/x86_64.cc b/gold/x86_64.cc > > index 58e191a055a..f77430bfb3d 100644 > > --- a/gold/x86_64.cc > > +++ b/gold/x86_64.cc > > @@ -2920,6 +2920,11 @@ Target_x86_64::optimize_tls_reloc(bool is_= final, int r_type, > > // Another Local-Dynamic reloc. > > return tls::TLSOPT_TO_LE; > > > > + case elfcpp::R_X86_64_CODE_6_GOTTPOFF: > > + if (r_offset <=3D 6 || *(reloc_view - 6) !=3D 0x62) > > + return tls::TLSOPT_NONE; > > + goto handle_gottpoff; > > + > > case elfcpp::R_X86_64_CODE_4_GOTTPOFF: > > if (r_offset <=3D 4 || *(reloc_view - 4) !=3D 0xd5) > > return tls::TLSOPT_NONE; > > @@ -2929,6 +2934,7 @@ Target_x86_64::optimize_tls_reloc(bool is_f= inal, int r_type, > > // from the GOT. If we know that we are linking against the > > // local symbol, we can switch to Local-Exec, which links the > > // thread offset into the instruction. > > +handle_gottpoff: > > if (is_final) > > return tls::TLSOPT_TO_LE; > > return tls::TLSOPT_NONE; > > @@ -2997,6 +3003,7 @@ Target_x86_64::Scan::get_reference_flags(un= signed int r_type) > > case elfcpp::R_X86_64_DTPOFF64: > > case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec > > case elfcpp::R_X86_64_CODE_4_GOTTPOFF: > > + case elfcpp::R_X86_64_CODE_6_GOTTPOFF: > > case elfcpp::R_X86_64_TPOFF32: // Local-exec > > return Symbol::TLS_REF; > > > > @@ -3362,6 +3369,7 @@ need_got: > > // These are initial tls relocs, which are expected when linking > > case elfcpp::R_X86_64_CODE_4_GOTPC32_TLSDESC: > > case elfcpp::R_X86_64_CODE_4_GOTTPOFF: > > + case elfcpp::R_X86_64_CODE_6_GOTTPOFF: > > { > > section_size_type stype; > > reloc_view =3D object->section_contents(data_shndx, &stype, tru= e); > > @@ -3464,6 +3472,7 @@ need_got: > > > > case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec > > case elfcpp::R_X86_64_CODE_4_GOTTPOFF: > > + case elfcpp::R_X86_64_CODE_6_GOTTPOFF: > > layout->set_has_static_tls(); > > if (optimized_type =3D=3D tls::TLSOPT_NONE) > > { > > @@ -3902,6 +3911,7 @@ Target_x86_64::Scan::global(Symbol_table* s= ymtab, > > // These are initial tls relocs, which are expected for global() > > case elfcpp::R_X86_64_CODE_4_GOTPC32_TLSDESC: > > case elfcpp::R_X86_64_CODE_4_GOTTPOFF: > > + case elfcpp::R_X86_64_CODE_6_GOTTPOFF: > > { > > section_size_type stype; > > reloc_view =3D object->section_contents(data_shndx, &stype, tru= e); > > @@ -3920,7 +3930,8 @@ Target_x86_64::Scan::global(Symbol_table* s= ymtab, > > // when building an executable. > > const bool is_final =3D (gsym->final_value_is_known() || > > ((r_type =3D=3D elfcpp::R_X86_64_GOTTPOF= F || > > - r_type =3D=3D elfcpp::R_X86_64_CODE_4_= GOTTPOFF) && > > + r_type =3D=3D elfcpp::R_X86_64_CODE_4_= GOTTPOFF|| > > + r_type =3D=3D elfcpp::R_X86_64_CODE_6_= GOTTPOFF) && > > gsym->is_undefined() && > > parameters->options().output_is_executa= ble())); > > size_t r_offset =3D reloc.get_r_offset(); > > @@ -4006,6 +4017,7 @@ Target_x86_64::Scan::global(Symbol_table* s= ymtab, > > > > case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec > > case elfcpp::R_X86_64_CODE_4_GOTTPOFF: > > + case elfcpp::R_X86_64_CODE_6_GOTTPOFF: > > layout->set_has_static_tls(); > > if (optimized_type =3D=3D tls::TLSOPT_NONE) > > { > > @@ -4608,6 +4620,7 @@ Target_x86_64::Relocate::relocate( > > case elfcpp::R_X86_64_DTPOFF64: > > case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec > > case elfcpp::R_X86_64_CODE_4_GOTTPOFF: > > + case elfcpp::R_X86_64_CODE_6_GOTTPOFF: > > case elfcpp::R_X86_64_TPOFF32: // Local-exec > > this->relocate_tls(relinfo, target, relnum, rela, r_type, gsym, = psymval, > > view, address, view_size); > > @@ -4894,6 +4907,7 @@ Target_x86_64::Relocate::relocate_tls( > > > > case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec > > case elfcpp::R_X86_64_CODE_4_GOTTPOFF: > > + case elfcpp::R_X86_64_CODE_6_GOTTPOFF: > > if (gsym !=3D NULL > > && gsym->is_undefined() > > && parameters->options().output_is_executable()) > > @@ -5308,11 +5322,19 @@ Target_x86_64::Relocate::tls_ie_to_le( > > > > // movq foo@gottpoff(%rip),%reg =3D=3D> movq $YY,%reg > > // addq foo@gottpoff(%rip),%reg =3D=3D> addq $YY,%reg > > + // addq %reg1,foo@gottpoff(%rip),%reg2 =3D=3D> addq $YY,%reg1,%reg= 2 > > + // addq foo@gottpoff(%rip),%reg1,%reg2 =3D=3D> addq $YY,%reg1,%reg= 2 > > > > - tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, -3= ); > > + int off1; > > + if (r_type =3D=3D elfcpp::R_X86_64_CODE_6_GOTTPOFF) > > + off1 =3D -5; > > + else > > + off1 =3D -3; > > + > > + tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, of= f1); > > tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 4)= ; > > > > - unsigned char op1 =3D view[-3]; > > + unsigned char op1 =3D view[off1]; > > unsigned char op2 =3D view[-2]; > > unsigned char op3 =3D view[-1]; > > unsigned char reg =3D op3 >> 3; > > @@ -5350,7 +5372,7 @@ Target_x86_64::Relocate::tls_ie_to_le( > > view[-1] =3D 0x80 | reg | (reg << 3); > > } > > } > > - else > > + else if (r_type =3D=3D elfcpp::R_X86_64_CODE_4_GOTTPOFF) > > { > > if (op2 =3D=3D 0x8b) > > op2 =3D 0xc7; > > @@ -5362,6 +5384,23 @@ Target_x86_64::Relocate::tls_ie_to_le( > > view[-2] =3D op2; > > view[-1] =3D 0xc0 | reg; > > } > > + else > > + { > > + unsigned char updated_op1 =3D op1; > > + > > + // Set the R bits since they is inverted. > > + updated_op1 |=3D 1 << 7 | 1 << 4; > > + > > + // Update the B bits from the R bits. > > + if ((op1 & (1 << 7)) =3D=3D 0) > > + updated_op1 &=3D ~(1 << 5); > > + if ((op1 & (1 << 4)) =3D=3D 0) > > + updated_op1 |=3D 1 << 3; > > + > > + view[-5] =3D updated_op1; > > + view[-2] =3D 0x81; > > + view[-1] =3D 0xc0 | reg; > > + } > > > > if (tls_segment !=3D NULL) > > value -=3D tls_segment->memsz(); > > diff --git a/include/elf/x86-64.h b/include/elf/x86-64.h > > index 33a824620a6..ea5036a8bbf 100644 > > --- a/include/elf/x86-64.h > > +++ b/include/elf/x86-64.h > > @@ -92,6 +92,26 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_type) > > /* 32 bit signed pc relative offset to TLS descriptor in the GOT = if > > instruction starts at 4 bytes before the relocation offset. */ > > RELOC_NUMBER (R_X86_64_CODE_4_GOTPC32_TLSDESC, 45) > > + /* Load from 32 bit signed pc relative offset to GOT entry if the > > + instruction starts at 5 bytes before the relocation offset, > > + relaxable. */ > > + RELOC_NUMBER (R_X86_64_CODE_5_GOTPCRELX, 46) > > + /* 32 bit signed pc relative offset to TLS descriptor in the GOT = if > > + instruction starts at 5 bytes before the relocation offset. */ > > + RELOC_NUMBER (R_X86_64_CODE_5_GOTPC32_TLSDESC, 47) > > + /* PC relative offset to IE GOT entry if the instruction starts at > > + 5 bytes before the relocation offset. */ > > + RELOC_NUMBER (R_X86_64_CODE_5_GOTTPOFF, 48) > > + /* Load from 32 bit signed pc relative offset to GOT entry if the > > + instruction starts at 6 bytes before the relocation offset, > > + relaxable. */ > > + RELOC_NUMBER (R_X86_64_CODE_6_GOTPCRELX, 49) > > + /* PC relative offset to IE GOT entry if the instruction starts at > > + 6 bytes before the relocation offset. */ > > + RELOC_NUMBER (R_X86_64_CODE_6_GOTTPOFF, 50) > > + /* 32 bit signed pc relative offset to TLS descriptor in the GOT = if > > + instruction starts at 6 bytes before the relocation offset. */ > > + RELOC_NUMBER (R_X86_64_CODE_6_GOTPC32_TLSDESC, 51) > > RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250) /* GNU C++ hack = */ > > RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251) /* GNU C++ hack = */ > > END_RELOC_NUMBERS (R_X86_64_max) > > diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.dd b/ld/testsuite/ld-x86= -64/tlsbindesc.dd > > index 4587cc751b4..be89f38199d 100644 > > --- a/ld/testsuite/ld-x86-64/tlsbindesc.dd > > +++ b/ld/testsuite/ld-x86-64/tlsbindesc.dd > > @@ -169,18 +169,42 @@ Disassembly of section .text: > > +[0-9a-f]+: d5 48 03 05 ([0-9a-f]{2} ){3}[ ]+add 0x[0-9a-f]+\(%= rip\),%r16 +# [0-9a-f]+ > > # -> R_X86_64_TPOFF64 sG2 > > +[0-9a-f]+: 00 * > > + +[0-9a-f]+: 62 f4 fc 10 01 ([0-9a-f]{2} ){2}[ ]+add %rax,0= x[0-9a-f]+\(%rip\),%r16 +# [0-9a-f]+ > > +# -> R_X86_64_TPOFF64 sG2 > > + +[0-9a-f]+: ([0-9a-f]{2} ){3} * > > + +[0-9a-f]+: 62 f4 fc 10 03 ([0-9a-f]{2} ){2}[ ]+add 0x[0-9= a-f]+\(%rip\),%rax,%r16 +# [0-9a-f]+ > > +# -> R_X86_64_TPOFF64 sG2 > > + +[0-9a-f]+: ([0-9a-f]{2} ){3} * > > # IE -> LE against global var defined in exec > > +[0-9a-f]+: d5 18 81 c1 60 ff ff[ ]+add \$0xf+60,%r17 > > # sg1 > > +[0-9a-f]+: ff * > > + +[0-9a-f]+: 62 d4 f4 10 81 ([0-9a-f]{2} ){2}[ ]+add \$0x[0= -9a-f]+,%r8,%r17 > > +# sg1 > > + +[0-9a-f]+: ff ff ff * > > + +[0-9a-f]+: 62 d4 f4 10 81 ([0-9a-f]{2} ){2}[ ]+add \$0x[0= -9a-f]+,%r8,%r17 > > +# sg1 > > + +[0-9a-f]+: ff ff ff * > > # IE -> LE against local var > > +[0-9a-f]+: d5 18 81 c2 80 ff ff[ ]+add \$0xf+80,%r18 > > # sl1 > > +[0-9a-f]+: ff * > > + +[0-9a-f]+: 62 d4 fc 18 81 ([0-9a-f]{2} ){2}[ ]+add \$0x[0= -9a-f]+,%r8,%rax > > +# sl1 > > + +[0-9a-f]+: ff ff ff * > > + +[0-9a-f]+: 62 d4 fc 18 81 ([0-9a-f]{2} ){2}[ ]+add \$0x[0= -9a-f]+,%r8,%rax > > +# sl1 > > + +[0-9a-f]+: ff ff ff * > > # IE -> LE against hidden var > > +[0-9a-f]+: d5 18 81 c3 a0 ff ff[ ]+add \$0xf+a0,%r19 > > # sh1 > > +[0-9a-f]+: ff * > > + +[0-9a-f]+: 62 fc bc 18 81 ([0-9a-f]{2} ){2}[ ]+add \$0x[0= -9a-f]+,%r19,%r8 > > +# sh1 > > + +[0-9a-f]+: ff ff ff * > > + +[0-9a-f]+: 62 fc bc 18 81 ([0-9a-f]{2} ){2}[ ]+add \$0x[0= -9a-f]+,%r19,%r8 > > +# sh1 > > + +[0-9a-f]+: ff ff ff * > > # Direct access through %fs > > # IE against global var > > +[0-9a-f]+: d5 48 8b 25 ([0-9a-f]{2} ){3}[ ]+mov 0x[0-9a-f]+\(%= rip\),%r20 +# [0-9a-f]+ > > diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.rd b/ld/testsuite/ld-x86= -64/tlsbindesc.rd > > index daaea7a5371..59325b04e19 100644 > > --- a/ld/testsuite/ld-x86-64/tlsbindesc.rd > > +++ b/ld/testsuite/ld-x86-64/tlsbindesc.rd > > @@ -15,12 +15,12 @@ Section Headers: > > +\[[ 0-9]+\] .dynsym +.* > > +\[[ 0-9]+\] .dynstr +.* > > +\[[ 0-9]+\] .rela.dyn +.* > > - +\[[ 0-9]+\] .text +PROGBITS +0+401000 0+1000 0+25d 00 +AX +0 +0 +409= 6 > > - +\[[ 0-9]+\] .tdata +PROGBITS +0+60125d 0+125d 0+60 00 WAT +0 +0 +1 > > - +\[[ 0-9]+\] .tbss +NOBITS +0+6012bd 0+12bd 0+40 00 WAT +0 +0 +1 > > - +\[[ 0-9]+\] .dynamic +DYNAMIC +0+6012c0 0+12c0 0+100 10 +WA +4 +0 +8 > > - +\[[ 0-9]+\] .got +PROGBITS +0+6013c0 0+13c0 0+20 08 +WA +0 +0 +8 > > - +\[[ 0-9]+\] .got.plt +PROGBITS +0+6013e0 0+13e0 0+18 08 +WA +0 +0 +8 > > + +\[[ 0-9]+\] .text +PROGBITS +0+401000 0+1000 0+2ad 00 +AX +0 +0 +409= 6 > > + +\[[ 0-9]+\] .tdata +PROGBITS +0+6012ad 0+12ad 0+60 00 WAT +0 +0 +1 > > + +\[[ 0-9]+\] .tbss +NOBITS +0+60130d 0+130d 0+40 00 WAT +0 +0 +1 > > + +\[[ 0-9]+\] .dynamic +DYNAMIC +0+601310 0+1310 0+100 10 +WA +4 +0 +8 > > + +\[[ 0-9]+\] .got +PROGBITS +0+601410 0+1410 0+20 08 +WA +0 +0 +8 > > + +\[[ 0-9]+\] .got.plt +PROGBITS +0+601430 0+1430 0+18 08 +WA +0 +0 +8 > > +\[[ 0-9]+\] .symtab +.* > > +\[[ 0-9]+\] .strtab +.* > > +\[[ 0-9]+\] .shstrtab +.* > > @@ -28,7 +28,7 @@ Key to Flags: > > #... > > > > Elf file type is EXEC \(Executable file\) > > -Entry point 0x401165 > > +Entry point 0x4011b5 > > There are [0-9]+ program headers, starting at offset [0-9]+ > > > > Program Headers: > > @@ -36,10 +36,10 @@ Program Headers: > > +PHDR.* > > +INTERP.* > > .*Requesting program interpreter.* > > - +LOAD +0x0+ 0x0+400000 0x0+400000 0x0+125d 0x0+125d R E 0x200000 > > - +LOAD +0x0+125d 0x0+60125d 0x0+60125d 0x0+19b 0x0+19b RW +0x200000 > > - +DYNAMIC +0x0+12c0 0x0+6012c0 0x0+6012c0 0x0+100 0x0+100 RW +0x8 > > - +TLS +0x0+125d 0x0+60125d 0x0+60125d 0x0+60 0x0+a0 R +0x1 > > + +LOAD +0x0+ 0x0+400000 0x0+400000 0x0+12ad 0x0+12ad R E 0x200000 > > + +LOAD +0x0+12ad 0x0+6012ad 0x0+6012ad 0x0+19b 0x0+19b RW +0x200000 > > + +DYNAMIC +0x0+1310 0x0+601310 0x0+601310 0x0+100 0x0+100 RW +0x8 > > + +TLS +0x0+12ad 0x0+6012ad 0x0+6012ad 0x0+60 0x0+a0 R +0x1 > > > > Section to Segment mapping: > > +Segment Sections... > > @@ -52,10 +52,10 @@ Program Headers: > > > > Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 4 entrie= s: > > +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend > > -0+6013c0 +0+100000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0 > > -0+6013c8 +0+200000012 R_X86_64_TPOFF64 +0+ sG2 \+ 0 > > -0+6013d0 +0+300000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0 > > -0+6013d8 +0+400000012 R_X86_64_TPOFF64 +0+ sG1 \+ 0 > > +0+601410 +0+100000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0 > > +0+601418 +0+200000012 R_X86_64_TPOFF64 +0+ sG2 \+ 0 > > +0+601420 +0+300000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0 > > +0+601428 +0+400000012 R_X86_64_TPOFF64 +0+ sG1 \+ 0 > > > > Symbol table '\.dynsym' contains [0-9]+ entries: > > +Num: +Value +Size +Type +Bind +Vis +Ndx +Name > > @@ -88,8 +88,8 @@ Symbol table '\.symtab' contains [0-9]+ entries: > > +[0-9]+: 0+9c +0 +TLS +LOCAL +DEFAULT +8 bl8 > > .* FILE +LOCAL +DEFAULT +ABS > > +[0-9]+: 0+a0 +0 +TLS +LOCAL +DEFAULT +7 _TLS_MODULE_BASE_ > > - +[0-9]+: 0+6012c0 +0 +OBJECT +LOCAL +DEFAULT +9 _DYNAMIC > > - +[0-9]+: 0+6013e0 +0 +OBJECT +LOCAL +DEFAULT +11 _GLOBAL_OFFSET_TABLE= _ > > + +[0-9]+: 0+601310 +0 +OBJECT +LOCAL +DEFAULT +9 _DYNAMIC > > + +[0-9]+: 0+601430 +0 +OBJECT +LOCAL +DEFAULT +11 _GLOBAL_OFFSET_TABLE= _ > > +[0-9]+: 0+1c +0 +TLS +GLOBAL +DEFAULT +7 sg8 > > +[0-9]+: 0+7c +0 +TLS +GLOBAL +DEFAULT +8 bg8 > > +[0-9]+: 0+74 +0 +TLS +GLOBAL +DEFAULT +8 bg6 > > @@ -104,7 +104,7 @@ Symbol table '\.symtab' contains [0-9]+ entries: > > +[0-9]+: 0+58 +0 +TLS +GLOBAL +HIDDEN +7 sh7 > > +[0-9]+: 0+5c +0 +TLS +GLOBAL +HIDDEN +7 sh8 > > +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +7 sg1 > > - +[0-9]+: 0+401165 +0 +FUNC +GLOBAL +DEFAULT +6 _start > > + +[0-9]+: 0+4011b5 +0 +FUNC +GLOBAL +DEFAULT +6 _start > > +[0-9]+: 0+4c +0 +TLS +GLOBAL +HIDDEN +7 sh4 > > +[0-9]+: 0+78 +0 +TLS +GLOBAL +DEFAULT +8 bg7 > > +[0-9]+: 0+50 +0 +TLS +GLOBAL +HIDDEN +7 sh5 > > diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.s b/ld/testsuite/ld-x86-= 64/tlsbindesc.s > > index b80e5f192c0..4747fc1bc30 100644 > > --- a/ld/testsuite/ld-x86-64/tlsbindesc.s > > +++ b/ld/testsuite/ld-x86-64/tlsbindesc.s > > @@ -129,15 +129,23 @@ fn2: > > > > /* IE against global var */ > > addq sG2@gottpoff(%rip), %r16 > > + addq %rax, sG2@gottpoff(%rip), %r16 > > + addq sG2@gottpoff(%rip), %rax, %r16 > > > > /* IE -> LE against global var defined in exec */ > > addq sg1@gottpoff(%rip), %r17 > > + addq %r8, sg1@gottpoff(%rip), %r17 > > + addq sg1@gottpoff(%rip), %r8, %r17 > > > > /* IE -> LE against local var */ > > addq sl1@gottpoff(%rip), %r18 > > + addq %r8, sl1@gottpoff(%rip), %rax > > + addq sl1@gottpoff(%rip), %r8, %rax > > > > /* IE -> LE against hidden var */ > > addq sh1@gottpoff(%rip), %r19 > > + addq %r19, sh1@gottpoff(%rip), %r8 > > + addq sh1@gottpoff(%rip), %r19, %r8 > > > > /* Direct access through %fs */ > > > > -- > > 2.43.0 > > > > I am checking it in. > > -- > H.J. I am backporting it to 2.42 branch. --=20 H.J.