From patchwork Thu Aug 17 18:08:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tatsuyuki Ishi X-Patchwork-Id: 135933 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b82d:0:b0:3f2:4152:657d with SMTP id z13csp886061vqi; Thu, 17 Aug 2023 11:12:53 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHjeulPMya9Xc0AaiU7XuFmrdjjTm2lb6n06m0HR5MK087N0MuRBgJx9a5EBPpWNQjRsi5m X-Received: by 2002:aa7:d90c:0:b0:525:6666:3551 with SMTP id a12-20020aa7d90c000000b0052566663551mr347669edr.27.1692295973388; Thu, 17 Aug 2023 11:12:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1692295973; cv=none; d=google.com; s=arc-20160816; b=T7qn7Eol/tkqSyBviaIcwZEsuY7b44ff2aYisnGHH4p40D8fpxFg8LsGrlhNeqa6ub Ce6bxp3yBW2T5ezB/ERhKOF3rBrqULK2S73/E0+KQtPoYaGmeLq5y/Q/VtOlbeRBmVvY 3OGteXxi2eY89LmpsF9RNCnP6/tD1BxpSiqYeHiZdmGIY1Q9kBgHc8tV84iS/NnTvJUp o+vQclOxx2+ShlTlR9GzQUajmF8Evt0nLN9cC8s/0+046GOz/CybTNy81knajLXX7Cze YtmlC2hu2F2+DKWqin4PUONPkAkcKaPKNAbFNyB70p9n1sw4Q1/IBYRW4qiMTgA2P3ot 3rHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=YnSfuEQf3iraU1vFMZmFC9fB8/TpBVL86BKQLGby0TY=; fh=RnOK2kMt7+DQSwabMVlm0F5hv9+FMo5J9F5oi1ILKLA=; b=TtIruVl1DP7Teq6WxrUEGcsMATW61iiOUSESqzHkrqk8Umum1uXzGHhppSxoFA4T0w iRvnkY5gUBMb7pj5rqPcuMxmNJrok9g61svcQ418qyP+G3VOtdIQ0meGVdhmVKP0fcF5 1kiMgEVNoGnvO/pxDjZ0xkWnhh9Cu/I9zHOcf3L17K4w0dwdc7kUoJgfZoGe9NVZR4VQ /EpImIVDSNPspsbeg2zSfuZeN4KLKuNTQjMhxk9KmPTm+1BeraIuivwmv+BLrrDKtOiF Ow5Rz7reaKapwKPmBR0jDGqkewXiO9Wu4+lcCv9x7K+PyBQK93MI6SE5BqXewi1wowy1 H0Bw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=kNfqTC5k; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id u1-20020aa7d981000000b0052257d9655bsi61736eds.304.2023.08.17.11.12.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Aug 2023 11:12:53 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=kNfqTC5k; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ED484385E019 for ; Thu, 17 Aug 2023 18:11:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ED484385E019 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1692295887; bh=YnSfuEQf3iraU1vFMZmFC9fB8/TpBVL86BKQLGby0TY=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=kNfqTC5kWJdGFMw0W5/o7M7v7rFyI7yvFS9Gjuc+6zMCFPb7eYHWbXba/hkk3/KSl pEPXUMu1fl3X3bHOMf51O1hluOjnHQlA6bhY/ZgrBftszapzRe3GorWyCaxrakEh4L Y95m+Ho6qmXFUEe/iHPlNHJQzarYGWqDRyqz9og4= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by sourceware.org (Postfix) with ESMTPS id 02A6B385DC10 for ; Thu, 17 Aug 2023 18:09:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 02A6B385DC10 Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-6879986a436so16778b3a.0 for ; Thu, 17 Aug 2023 11:09:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692295768; x=1692900568; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YnSfuEQf3iraU1vFMZmFC9fB8/TpBVL86BKQLGby0TY=; b=kmn41EusfULMhMq/zWHXPRUsRZ90VLH4J7T6pUp2AgaOsMBxx6LvFk1B9/IEbKDUQ+ Vl3IOw31caGxSCmkIYANb6ClQJW4Oqz/Up/aUJAFL1lQgGJOaKEWOgenAuTmeObB6DpE 3NzFHGSKeDe6adC752E2j/5vBDtEj5qFlewOpDTMrJcu4MhnBs3nvcwxwT1W7ludC+kU 6yr5al1+U6ijt0RhvrvA1HnXh/RccVGk5f5C1rMNAfPW15XRhop/K/yBlgP/eCD2QR4X RO5DjdhQj3xbyn9rVbAHZoy0cZgZMPmoP0xYHBXuNz06vIwQqjXFcWdRM2bWTfXTGm3E 9Xkw== X-Gm-Message-State: AOJu0Yx1GikfVilTM8imVxAuQ9UGPrkYKaSjbuhPoydo/JFBNgh0JmUw UCTA50hM7ETyy9Mxtd9yeF3t5uIPIe0+jIDH X-Received: by 2002:a05:6a20:441a:b0:13e:1d49:7249 with SMTP id ce26-20020a056a20441a00b0013e1d497249mr618267pzb.2.1692295768353; Thu, 17 Aug 2023 11:09:28 -0700 (PDT) Received: from localhost (zz20184013906F627101.userreverse.dion.ne.jp. [111.98.113.1]) by smtp.gmail.com with ESMTPSA id ey17-20020a056a0038d100b00686f048bb9dsm64094pfb.74.2023.08.17.11.09.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Aug 2023 11:09:27 -0700 (PDT) To: binutils@sourceware.org Cc: rui314@gmail.com, ruiu@bluewhale.systems, Tatsuyuki Ishi Subject: [PATCH 4/4] RISC-V: Initial ld.bfd support for TLSDESC. Date: Fri, 18 Aug 2023 03:08:37 +0900 Message-ID: <20230817180852.121628-6-ishitatsuyuki@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230817180852.121628-2-ishitatsuyuki@gmail.com> References: <20230817180852.121628-2-ishitatsuyuki@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.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 autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tatsuyuki Ishi via Binutils From: Tatsuyuki Ishi Reply-To: Tatsuyuki Ishi Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1774500943007427688 X-GMAIL-MSGID: 1774500943007427688 Only relocation handling for now; relaxation is not implemented yet. --- bfd/elfnn-riscv.c | 91 +++++++++++++++++++--- ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 2 + 2 files changed, 84 insertions(+), 9 deletions(-) diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 38883134828..a55bee7af52 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -166,6 +166,7 @@ struct riscv_elf_link_hash_entry #define GOT_TLS_GD 2 #define GOT_TLS_IE 4 #define GOT_TLS_LE 8 +#define GOT_TLSDESC 16 char tls_type; }; @@ -303,6 +304,7 @@ riscv_is_insn_reloc (const reloc_howto_type *howto) #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES #define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2) #define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES +#define TLSDESC_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2) /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver, the other is used for link map. Other targets also reserve one more entry used for runtime profile? */ @@ -858,6 +860,12 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, return false; break; + case R_RISCV_TLSDESC_HI20: + if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx) + || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLSDESC)) + return false; + break; + case R_RISCV_CALL: case R_RISCV_CALL_PLT: /* These symbol requires a procedure linkage table entry. @@ -1316,7 +1324,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) s = htab->elf.sgot; h->got.offset = s->size; dyn = htab->elf.dynamic_sections_created; - if (tls_type & (GOT_TLS_GD | GOT_TLS_IE)) + if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC)) { int indx = 0; bool need_reloc = false; @@ -1337,6 +1345,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (need_reloc) htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); } + + /* TLSDESC needs one dynamic reloc and four GOT slots. */ + if (tls_type & GOT_TLSDESC) + { + s->size += TLSDESC_GOT_ENTRY_SIZE; + /* TLSDESC always use dynamic relocs. */ + htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); + } } else { @@ -1564,7 +1580,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) if (*local_got > 0) { *local_got = s->size; - if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)) + if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC)) { if (*local_tls_type & GOT_TLS_GD) { @@ -1578,6 +1594,11 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) if (bfd_link_dll (info)) srel->size += sizeof (ElfNN_External_Rela); } + if (*local_tls_type & GOT_TLSDESC) + { + s->size += TLSDESC_GOT_ENTRY_SIZE; + srel->size += sizeof (ElfNN_External_Rela); + } } else { @@ -1728,6 +1749,17 @@ tpoff (struct bfd_link_info *info, bfd_vma address) return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET; } +/* Return the relocation value for a static TLSDESC relocation. */ + +static bfd_vma +tlsdescoff (struct bfd_link_info *info, bfd_vma address) +{ + /* If tls_sec is NULL, we should have signalled an error already. */ + if (elf_hash_table (info)->tls_sec == NULL) + return 0; + return address - elf_hash_table (info)->tls_sec->vma; +} + /* Return the global pointer's value, or 0 if it is not in use. */ static bfd_vma @@ -1764,6 +1796,7 @@ perform_relocation (const reloc_howto_type *howto, case R_RISCV_GOT_HI20: case R_RISCV_TLS_GOT_HI20: case R_RISCV_TLS_GD_HI20: + case R_RISCV_TLSDESC_HI20: if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value))) return bfd_reloc_overflow; value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)); @@ -1774,6 +1807,8 @@ perform_relocation (const reloc_howto_type *howto, case R_RISCV_TPREL_LO12_I: case R_RISCV_TPREL_I: case R_RISCV_PCREL_LO12_I: + case R_RISCV_TLSDESC_LOAD_LO12: + case R_RISCV_TLSDESC_ADD_LO12: value = ENCODE_ITYPE_IMM (value); break; @@ -2195,8 +2230,8 @@ riscv_elf_relocate_section (bfd *output_bfd, bfd_vma relocation; bfd_reloc_status_type r = bfd_reloc_ok; const char *name = NULL; - bfd_vma off, ie_off; - bool unresolved_reloc, is_ie = false; + bfd_vma off, ie_off, desc_off; + bool unresolved_reloc, is_ie = false, is_desc = false; bfd_vma pc = sec_addr (input_section) + rel->r_offset; int r_type = ELFNN_R_TYPE (rel->r_info), tls_type; reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type); @@ -2499,6 +2534,7 @@ riscv_elf_relocate_section (bfd *output_bfd, case R_RISCV_NONE: case R_RISCV_RELAX: case R_RISCV_TPREL_ADD: + case R_RISCV_TLSDESC_CALL: case R_RISCV_COPY: case R_RISCV_JUMP_SLOT: case R_RISCV_RELATIVE: @@ -2820,6 +2856,15 @@ riscv_elf_relocate_section (bfd *output_bfd, relocation = dtpoff (info, relocation); break; + case R_RISCV_TLSDESC_LOAD_LO12: + case R_RISCV_TLSDESC_ADD_LO12: + if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, relocation, rel, + input_section, info, howto, + contents)) + continue; + r = bfd_reloc_overflow; + break; + case R_RISCV_32: /* Non ABS symbol should be blocked in check_relocs. */ if (ARCH_SIZE > 32) @@ -2885,11 +2930,16 @@ riscv_elf_relocate_section (bfd *output_bfd, } break; + case R_RISCV_TLSDESC_HI20: + is_desc = true; + goto tls; + case R_RISCV_TLS_GOT_HI20: is_ie = true; - /* Fall through. */ + goto tls; case R_RISCV_TLS_GD_HI20: + tls: if (h != NULL) { off = h->got.offset; @@ -2902,12 +2952,16 @@ riscv_elf_relocate_section (bfd *output_bfd, } tls_type = _bfd_riscv_elf_tls_type (input_bfd, h, r_symndx); - BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD)); + BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD | GOT_TLSDESC)); /* If this symbol is referenced by both GD and IE TLS, the IE reference's GOT slot follows the GD reference's slots. */ ie_off = 0; if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE)) - ie_off = TLS_GD_GOT_ENTRY_SIZE; + ie_off += TLS_GD_GOT_ENTRY_SIZE; + + desc_off = ie_off; + if (tls_type & GOT_TLS_IE) + desc_off += TLS_IE_GOT_ENTRY_SIZE; if ((off & 1) != 0) off &= ~1; @@ -2989,10 +3043,29 @@ riscv_elf_relocate_section (bfd *output_bfd, htab->elf.sgot->contents + off + ie_off); } } + + if (tls_type & GOT_TLSDESC) + { + /* TLSDESC is always handled by the dynamic linker and always need + * a relocation. */ + bfd_put_NN (output_bfd, 0, + htab->elf.sgot->contents + off + desc_off); + outrel.r_offset = sec_addr (htab->elf.sgot) + + off + desc_off; + outrel.r_addend = 0; + if (indx == 0) + outrel.r_addend = tlsdescoff (info, relocation); + outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLSDESC); + riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel); + } } BFD_ASSERT (off < (bfd_vma) -2); - relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off : 0); + relocation = sec_addr (htab->elf.sgot) + off; + if (is_ie) + relocation += ie_off; + else if (is_desc) + relocation += desc_off; if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc, relocation, r_type, false)) @@ -3212,7 +3285,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd, } if (h->got.offset != (bfd_vma) -1 - && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)) + && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC)) && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) { asection *sgot; diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 947a266ba72..e09c25486a5 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -317,4 +317,6 @@ if [istarget "riscv*-*-*"] { run_dump_test "pcrel-reloc-rel-pie" run_dump_test "pcrel-reloc-abs-nopie" run_dump_test "pcrel-reloc-abs-pie" + + run_dump_test "tlsdesc" }