From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 78AFD3858412 for ; Mon, 8 Jan 2024 06:00:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 78AFD3858412 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 78AFD3858412 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704693657; cv=none; b=vWwwjQHq+ohbOdCn1KQCz5/+c709y0gnGx3zbMMbTYMyKOvUFhWfxJH/vzAbMSV9hqx6N4zmrTqvKIDOEc3u6huzf9WZDP5wm9UfqO5biMj3KmIO+heRVE32lonFE8YB+HCB4yYpgGj00ZqGK3vF+gSyUMkzjjF9Hk6GyzzLN8k= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704693657; c=relaxed/simple; bh=Qw7AWvikVBeo6jqfvc9KmrghFXxrCJA4JFyAoKV9cks=; h=Subject:To:From:Message-ID:Date:MIME-Version; b=keivMKJm4kh91tyRcAcoWlQxyfZUQ4xXRv7NBTinBax0Dwfv3yy5Y7IzNHzymFPyH6k7BxXYhCSeTocjvaowOhd2NsGiCtcKyAL4/4kDQEeuvmQIBDi4YijJ+likkNx/3tziKMoaNMK8svtJlCHsy3HE3VNmIMVzNb/4bmDdm/c= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from loongson.cn (unknown [10.20.4.103]) by gateway (Coremail) with SMTP id _____8CxLLuQj5tliAoDAA--.1699S3; Mon, 08 Jan 2024 14:00:49 +0800 (CST) Received: from [10.20.4.103] (unknown [10.20.4.103]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxC96Pj5tlUw8HAA--.18525S3; Mon, 08 Jan 2024 14:00:47 +0800 (CST) Subject: Re: [PATCH v5 4/5] LoongArch: Add support for TLS LD/GD/DESC relaxation To: Fangrui Song , Tatsuyuki Ishi , binutils@sourceware.org Cc: xuchenghua@loongson.cn, chenglulu@loongson.cn, liuzhensong@loongson.cn, mengqinggang@loongson.cn, xry111@xry111.site, i.swmail@xen0n.name, maskray@google.com, luweining@loongson.cn, wanglei@loongson.cn, hejinyang@loongson.cn References: <20231222114243.1836112-1-cailulu@loongson.cn> <20231222114243.1836112-5-cailulu@loongson.cn> <6f636b66-e747-8882-0138-2f55529ef280@loongson.cn> <71198CD4-E934-4458-BF2F-1C46E792CCDE@gmail.com> From: Lulu Cai Message-ID: Date: Mon, 8 Jan 2024 14:00:47 +0800 User-Agent: Mozilla/5.0 (X11; Linux loongarch64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-CM-TRANSID:AQAAf8CxC96Pj5tlUw8HAA--.18525S3 X-CM-SenderInfo: xfdlz3tox6z05rqj20fqof0/1tbiAQAKB2WbSakGMAAAsk X-Coremail-Antispam: 1Uk129KBj9fXoWfJFWUAr4fGFyfXw1xGr1rGrX_yoW8Cw1fuo WrZFyxAw1xGFW7ArZxJ3sxXFW7t3s5GrWrC3sxZwnIga18KF1Y9rW8tr15tr4fJrWUKa48 GFy3G3yDAF97K3Z8l-sFpf9Il3svdjkaLaAFLSUrUUUU8b8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUYW7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r1I6r4UM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r1j6r4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2 xF0cIa020Ex4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_ JF0_Jw1lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvEwI xGrwCYjI0SjxkI62AI1cAE67vIY487MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY 6r1j6r4UMxCIbckI1I0E14v26r1Y6r17MI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7 xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xII jxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY6xAIw2 0EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x02 67AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjxU7fMaUUUUU X-Spam-Status: No, score=-14.1 required=5.0 tests=BAYES_00,GIT_PATCH_0,KAM_DMARC_STATUS,NICE_REPLY_A,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 1/8/24 8:22 AM, Fangrui Song wrote: > On Sun, Jan 7, 2024 at 3:00 PM Tatsuyuki Ishi wrote: >> On Dec 29, 2023, at 19:45, Lulu Cai wrote: >> >> On 2023/12/28 at 10:38 PM, Tatsuyuki Ishi Wrote: >> >> On Dec 22, 2023, at 20:42, Lulu Cai wrote: >> >> From: mengqinggang >> >> The pcalau12i + addi.d of TLS LD/GD/DESC relax to pcaddi. >> Relaxation is only performed when the TLS model transition is not possible. >> --- >> bfd/bfd-in2.h | 3 + >> bfd/elfnn-loongarch.c | 174 +++++++- >> bfd/elfxx-loongarch.c | 60 +++ >> bfd/libbfd.h | 3 + >> bfd/reloc.c | 7 + >> gas/config/tc-loongarch.c | 8 +- >> gas/testsuite/gas/loongarch/macro_op.d | 128 +++--- >> gas/testsuite/gas/loongarch/macro_op_32.d | 120 +++--- >> .../gas/loongarch/macro_op_large_abs.d | 160 +++---- >> .../gas/loongarch/macro_op_large_pc.d | 160 +++---- >> include/elf/loongarch.h | 4 + >> ld/testsuite/ld-loongarch-elf/macro_op.d | 391 +++++++++--------- >> ld/testsuite/ld-loongarch-elf/macro_op_32.d | 120 +++--- >> 13 files changed, 795 insertions(+), 543 deletions(-) >> >> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h >> index 85251aa0edd..782845926ea 100644 >> --- a/bfd/bfd-in2.h >> +++ b/bfd/bfd-in2.h >> @@ -7473,6 +7473,9 @@ enum bfd_reloc_code_real >> BFD_RELOC_LARCH_TLS_DESC64_HI12, >> BFD_RELOC_LARCH_TLS_DESC_LD, >> BFD_RELOC_LARCH_TLS_DESC_CALL, >> + BFD_RELOC_LARCH_TLS_LD_PCREL20_S2, >> + BFD_RELOC_LARCH_TLS_GD_PCREL20_S2, >> + BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2, >> BFD_RELOC_UNUSED >> }; >> typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; >> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c >> index 1347d13d2e2..bd448cda453 100644 >> --- a/bfd/elfnn-loongarch.c >> +++ b/bfd/elfnn-loongarch.c >> @@ -2285,7 +2285,9 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section, >> case R_LARCH_TLS_DESC_LO12: >> case R_LARCH_TLS_DESC64_LO20: >> case R_LARCH_TLS_DESC64_HI12: >> - >> + case R_LARCH_TLS_LD_PCREL20_S2: >> + case R_LARCH_TLS_GD_PCREL20_S2: >> + case R_LARCH_TLS_DESC_PCREL20_S2: >> r = loongarch_check_offset (rel, input_section); >> if (r != bfd_reloc_ok) >> break; >> @@ -3674,6 +3676,9 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, >> case R_LARCH_TLS_GD_HI20: >> case R_LARCH_TLS_DESC_PC_HI20: >> case R_LARCH_TLS_DESC_HI20: >> + case R_LARCH_TLS_LD_PCREL20_S2: >> + case R_LARCH_TLS_GD_PCREL20_S2: >> + case R_LARCH_TLS_DESC_PCREL20_S2: >> BFD_ASSERT (rel->r_addend == 0); >> unresolved_reloc = false; >> >> @@ -3682,7 +3687,8 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, >> is_ie = true; >> >> if (r_type == R_LARCH_TLS_DESC_PC_HI20 >> - || r_type == R_LARCH_TLS_DESC_HI20) >> + || r_type == R_LARCH_TLS_DESC_HI20 >> + || r_type == R_LARCH_TLS_DESC_PCREL20_S2) >> is_desc = true; >> >> bfd_vma got_off = 0; >> @@ -3813,7 +3819,11 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, >> || r_type == R_LARCH_TLS_IE_PC_HI20 >> || r_type == R_LARCH_TLS_DESC_PC_HI20) >> RELOCATE_CALC_PC32_HI20 (relocation, pc); >> - >> + else if (r_type == R_LARCH_TLS_LD_PCREL20_S2 >> + || r_type == R_LARCH_TLS_GD_PCREL20_S2 >> + || r_type == R_LARCH_TLS_DESC_PCREL20_S2) >> + relocation -= pc; >> + /* else {} ABS relocations. */ >> break; >> >> case R_LARCH_TLS_DESC_PC_LO12: >> @@ -4244,6 +4254,85 @@ loongarch_relax_align (bfd *abfd, asection *sec, >> addend - need_nop_bytes, link_info); >> } >> >> +/* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */ >> +static bool >> +loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec, >> + Elf_Internal_Rela *rel_hi, bfd_vma symval, >> + struct bfd_link_info *info, bool *again) >> +{ >> + bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; >> + Elf_Internal_Rela *rel_lo = rel_hi + 2; >> + uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset); >> + uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset); >> + uint32_t rd = pca & 0x1f; >> + >> + /* This section's output_offset need to subtract the bytes of instructions >> + relaxed by the previous sections, so it needs to be updated beforehand. >> + size_input_section already took care of updating it after relaxation, >> + so we additionally update once here. */ >> + sec->output_offset = sec->output_section->size; >> + bfd_vma pc = sec_addr (sec) + rel_hi->r_offset; >> + >> + /* If pc and symbol not in the same segment, add/sub segment alignment. >> + FIXME: if there are multiple readonly segments? */ >> + if (!(sym_sec->flags & SEC_READONLY)) >> + { >> + if (symval > pc) >> + pc -= info->maxpagesize; >> + else if (symval < pc) >> + pc += info->maxpagesize; >> + } >> + >> + const uint32_t addi_d = 0x02c00000; >> + const uint32_t pcaddi = 0x18000000; >> + >> + /* Is pcalau12i + addi.d insns? */ >> + if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12 >> + && ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_TLS_DESC_PC_LO12) >> + || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX) >> + || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX) >> + || (rel_hi->r_offset + 4 != rel_lo->r_offset) >> + || ((add & addi_d) != addi_d) >> + /* Is pcalau12i $rd + addi.d $rd,$rd? */ >> + || ((add & 0x1f) != rd) >> + || (((add >> 5) & 0x1f) != rd) >> + /* Can be relaxed to pcaddi? */ >> + || (symval & 0x3) /* 4 bytes align. */ >> + || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000) >> + || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc)) >> + return false; >> + >> + /* Continue next relax trip. */ >> + *again = true; >> + >> + pca = pcaddi | rd; >> + bfd_put (32, abfd, pca, contents + rel_hi->r_offset); >> + >> + /* Adjust relocations. */ >> + switch (ELFNN_R_TYPE (rel_hi->r_info)) >> + { >> + case R_LARCH_TLS_LD_PC_HI20: >> + rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info), >> + R_LARCH_TLS_LD_PCREL20_S2); >> + break; >> + case R_LARCH_TLS_GD_PC_HI20: >> + rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info), >> + R_LARCH_TLS_GD_PCREL20_S2); >> + break; >> + case R_LARCH_TLS_DESC_PC_HI20: >> + rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info), >> + R_LARCH_TLS_DESC_PCREL20_S2); >> + break; >> + default: >> + break; >> + } >> + rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE); >> + >> + loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info); >> + >> + return true; >> +} >> + >> static bool >> loongarch_elf_relax_section (bfd *abfd, asection *sec, >> struct bfd_link_info *info, >> @@ -4288,15 +4377,23 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, >> >> for (unsigned int i = 0; i < sec->reloc_count; i++) >> { >> - Elf_Internal_Rela *rel = relocs + i; >> - asection *sym_sec; >> + char symtype; >> bfd_vma symval; >> - unsigned long r_symndx = ELFNN_R_SYM (rel->r_info); >> - unsigned long r_type = ELFNN_R_TYPE (rel->r_info); >> + asection *sym_sec; >> bool local_got = false; >> - char symtype; >> + Elf_Internal_Rela *rel = relocs + i; >> struct elf_link_hash_entry *h = NULL; >> + unsigned long r_type = ELFNN_R_TYPE (rel->r_info); >> + unsigned long r_symndx = ELFNN_R_SYM (rel->r_info); >> >> + /* Four kind of relocations: >> + Normal: symval is the symbol address. >> + R_LARCH_ALIGN: symval is the address of the last NOP instruction >> + added by this relocation, and then adds 4 more. >> + R_LARCH_CALL36: symval is the symbol address for local symbols, >> + or the PLT entry address of the symbol. (Todo) >> + R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address >> + of the symbol. */ >> if (r_symndx < symtab_hdr->sh_info) >> { >> Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents >> @@ -4304,7 +4401,24 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, >> if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) >> continue; >> >> - if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type) >> + if (R_LARCH_TLS_LD_PC_HI20 == r_type >> + || R_LARCH_TLS_GD_PC_HI20 == r_type >> + || R_LARCH_TLS_DESC_PC_HI20 == r_type) >> + { >> + if (loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx)) >> + continue; >> + else >> + { >> + sym_sec = htab->elf.sgot; >> + symval = elf_local_got_offsets (abfd)[r_symndx]; >> + char tls_type = _bfd_loongarch_elf_tls_type (abfd, h, >> + r_symndx); >> + if (R_LARCH_TLS_DESC_PC_HI20 == r_type >> + && GOT_TLS_GD_BOTH_P (tls_type)) >> + symval += 2 * GOT_ENTRY_SIZE; >> + } >> + } >> + else if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type) >> { >> sym_sec = sec; >> symval = rel->r_offset; >> @@ -4329,7 +4443,26 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, >> if (h != NULL && h->type == STT_GNU_IFUNC) >> continue; >> >> - if ((h->root.type == bfd_link_hash_defined >> + /* The GOT entry of tls symbols must in current execute file or >> + shared object. */ >> + if (R_LARCH_TLS_LD_PC_HI20 == r_type >> + || R_LARCH_TLS_GD_PC_HI20 == r_type >> + || R_LARCH_TLS_DESC_PC_HI20 == r_type) >> + { >> + if (loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx)) >> + continue; >> + else >> + { >> + sym_sec = htab->elf.sgot; >> + symval = h->got.offset; >> + char tls_type = _bfd_loongarch_elf_tls_type (abfd, h, >> + r_symndx); >> + if (R_LARCH_TLS_DESC_PC_HI20 == r_type >> + && GOT_TLS_GD_BOTH_P (tls_type)) >> + symval += 2 * GOT_ENTRY_SIZE; >> + } >> + } >> + else if ((h->root.type == bfd_link_hash_defined >> || h->root.type == bfd_link_hash_defweak) >> && h->root.u.def.section != NULL >> && h->root.u.def.section->output_section != NULL) >> @@ -4358,7 +4491,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, >> if (symtype != STT_SECTION) >> symval += rel->r_addend; >> } >> - /* For R_LARCH_ALIGN, symval is sec_addr (sym_sec) + rel->r_offset >> + /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset >> + (alingmeng - 4). >> If r_symndx is 0, alignmeng-4 is r_addend. >> If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */ >> @@ -4399,6 +4532,25 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, >> info, again); >> } >> break; >> + >> + case R_LARCH_TLS_LD_PC_HI20: >> + if (0 == info->relax_pass && (i + 4) <= sec->reloc_count) >> + loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval, >> + info, again); >> + break; >> + >> + case R_LARCH_TLS_GD_PC_HI20: >> + if (0 == info->relax_pass && (i + 4) <= sec->reloc_count) >> + loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval, >> + info, again); >> + break; >> + >> + case R_LARCH_TLS_DESC_PC_HI20: >> + if (0 == info->relax_pass && (i + 4) <= sec->reloc_count) >> + loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval, >> + info, again); >> + break; >> + >> default: >> break; >> } >> diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c >> index 30a941a851f..310e6d62dc0 100644 >> --- a/bfd/elfxx-loongarch.c >> +++ b/bfd/elfxx-loongarch.c >> @@ -1775,6 +1775,60 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = >> BFD_RELOC_LARCH_TLS_DESC_CALL, /* bfd_reloc_code_real_type. */ >> NULL, /* adjust_reloc_bits. */ >> "desc_call"), /* larch_reloc_type_name. */ >> >> + >> + /* For pcaddi, ld_pc_hi20 + ld_pc_lo12 can relax to ld_pcrel20_s2. */ >> + LOONGARCH_HOWTO (R_LARCH_TLS_LD_PCREL20_S2, /* type (124). */ >> + 2, /* rightshift. */ >> + 4, /* size. */ >> + 20, /* bitsize. */ >> + false, /* pc_relative. */ >> + 5, /* bitpos. */ >> + complain_overflow_signed, /* complain_on_overflow. */ >> + bfd_elf_generic_reloc, /* special_function. */ >> + "R_LARCH_TLS_LD_PCREL20_S2", /* name. */ >> + false, /* partial_inplace. */ >> + 0, /* src_mask. */ >> + 0x1ffffe0, /* dst_mask. */ >> + true, /* pcrel_offset. */ >> + BFD_RELOC_LARCH_TLS_LD_PCREL20_S2, /* bfd_reloc_code_real_type. */ >> + reloc_sign_bits, /* adjust_reloc_bits. */ >> + "ld_pcrel_20"), /* larch_reloc_type_name. */ >> + >> + /* For pcaddi, gd_pc_hi20 + gd_pc_lo12 can relax to gd_pcrel20_s2. */ >> + LOONGARCH_HOWTO (R_LARCH_TLS_GD_PCREL20_S2, /* type (125). */ >> + 2, /* rightshift. */ >> + 4, /* size. */ >> + 20, /* bitsize. */ >> + false, /* pc_relative. */ >> + 5, /* bitpos. */ >> + complain_overflow_signed, /* complain_on_overflow. */ >> + bfd_elf_generic_reloc, /* special_function. */ >> + "R_LARCH_TLS_GD_PCREL20_S2", /* name. */ >> + false, /* partial_inplace. */ >> + 0, /* src_mask. */ >> + 0x1ffffe0, /* dst_mask. */ >> + true, /* pcrel_offset. */ >> + BFD_RELOC_LARCH_TLS_GD_PCREL20_S2, /* bfd_reloc_code_real_type. */ >> + reloc_sign_bits, /* adjust_reloc_bits. */ >> + "gd_pcrel_20"), /* larch_reloc_type_name. */ >> + >> + /* For pcaddi, desc_pc_hi20 + desc_pc_lo12 can relax to desc_pcrel20_s2. */ >> + LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PCREL20_S2, /* type (126). */ >> + 2, /* rightshift. */ >> + 4, /* size. */ >> + 20, /* bitsize. */ >> + false, /* pc_relative. */ >> + 5, /* bitpos. */ >> + complain_overflow_signed, /* complain_on_overflow. */ >> + bfd_elf_generic_reloc, /* special_function. */ >> + "R_LARCH_TLS_DESC_PCREL20_S2", /* name. */ >> + false, /* partial_inplace. */ >> + 0, /* src_mask. */ >> + 0x1ffffe0, /* dst_mask. */ >> + true, /* pcrel_offset. */ >> + BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2, /* bfd_reloc_code_real_type. */ >> + reloc_sign_bits, /* adjust_reloc_bits. */ >> + "desc_pcrel_20"), /* larch_reloc_type_name. */ >> }; >> >> >> >> I think relaxation relocs is a concept internal to binutils and they should not be in the same number range as psABI defined relocs. Some linkers (e.g. mold) doesn’t create new relocs when relaxing and rewrites the instruction right away, therefore these relocs would have no purpose in the psABI. >> >> We recently refactored out all the linker-internal relocs to a different range [1]; LoongArch might want to follow suit. >> >> [1]: https://sourceware.org/pipermail/binutils/2023-November/130322.html >> >> >> However, it should be noted that in handwritten assembly, these relocations can be directly used. >> >> >> Sorry for the delay in reply. I’m not sure if there is any use cases to use relaxation-only relocations in assembly source. It’s one of the reasons we did away with this in RISC-V [1]. >> >> [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/398 > Agreed. If a relocation type is only used for internal relaxation > purposes, it should not be defined in the psABI and there should not > be an assembler directive generating it (except .reloc using a > hard-coded integer). We have considered such a situation. For those familiar with LoongArch assembly, if you want to use DESC to access "var" in assembly source, you can directly use pcaddi $a0,%desc_pcrel_20(var) instead of pcalau12i $a0,%desc_pc_hi20(var) and addi.d $a0, $a0,% desc_pc_lo12(var). The same situation applies to GD/LD. > >> reloc_howto_type * >> @@ -1783,7 +1837,9 @@ loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) >> if(r_type < R_LARCH_count) >> { >> /* For search table fast. */ >> >> + /* >> BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); >> + */ >> >> >> >> Was this supposed to be commented out and committed as-is? >> >> >> It has been deleted. >> >> >> >> if (loongarch_howto_table[r_type].howto.type == r_type) >> return (reloc_howto_type *)&loongarch_howto_table[r_type]; >> @@ -1802,7 +1858,9 @@ loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) >> reloc_howto_type * >> loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) >> { >> + /* >> BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); >> + */ >> >> for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) >> if (loongarch_howto_table[i].howto.name >> @@ -1821,7 +1879,9 @@ reloc_howto_type * >> loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, >> bfd_reloc_code_real_type code) >> { >> + /* >> BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); >> + */ >> >> /* Fast search for new reloc types. */ >> if (BFD_RELOC_LARCH_B16 <= code && code < BFD_RELOC_LARCH_RELAX) >> diff --git a/bfd/libbfd.h b/bfd/libbfd.h >> index 71b03da14d9..8dab44110a6 100644 >> --- a/bfd/libbfd.h >> +++ b/bfd/libbfd.h >> @@ -3612,6 +3612,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", >> "BFD_RELOC_LARCH_TLS_DESC64_HI12", >> "BFD_RELOC_LARCH_TLS_DESC_LD", >> "BFD_RELOC_LARCH_TLS_DESC_CALL", >> + "BFD_RELOC_LARCH_TLS_LD_PCREL20_S2", >> + "BFD_RELOC_LARCH_TLS_GD_PCREL20_S2", >> + "BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2", >> "@@overflow: BFD_RELOC_UNUSED@@", >> }; >> #endif >> diff --git a/bfd/reloc.c b/bfd/reloc.c >> index f7fe0c7ffe3..6fd0f1fb547 100644 >> --- a/bfd/reloc.c >> +++ b/bfd/reloc.c >> @@ -8324,6 +8324,13 @@ ENUMX >> ENUMX >> BFD_RELOC_LARCH_TLS_DESC_CALL >> >> +ENUMX >> + BFD_RELOC_LARCH_TLS_LD_PCREL20_S2 >> +ENUMX >> + BFD_RELOC_LARCH_TLS_GD_PCREL20_S2 >> +ENUMX >> + BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2 >> + >> ENUMDOC >> LARCH relocations. >> >> diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c >> index 1658025f918..def26daf634 100644 >> --- a/gas/config/tc-loongarch.c >> +++ b/gas/config/tc-loongarch.c >> @@ -682,7 +682,7 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2, >> esc_ch1, esc_ch2, bit_field, arg); >> >> if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16 >> - && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_CALL) >> + && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2) >> { >> /* As we compact stack-relocs, it is no need for pop operation. >> But break out until here in order to check the imm field. >> @@ -694,7 +694,11 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2, >> && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_type >> || BFD_RELOC_LARCH_PCALA_LO12 == reloc_type >> || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_type >> - || BFD_RELOC_LARCH_GOT_PC_LO12 == reloc_type)) >> + || BFD_RELOC_LARCH_GOT_PC_LO12 == reloc_type >> + || BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_type >> + || BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_type >> + || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_type >> + || BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_type)) >> { >> ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX; >> ip->reloc_info[ip->reloc_num].value = const_0; >> diff --git a/gas/testsuite/gas/loongarch/macro_op.d b/gas/testsuite/gas/loongarch/macro_op.d >> index 32860864704..47f8f45c663 100644 >> --- a/gas/testsuite/gas/loongarch/macro_op.d >> +++ b/gas/testsuite/gas/loongarch/macro_op.d >> @@ -2,70 +2,72 @@ >> #objdump: -dr >> #skip: loongarch32-*-* >> >> >> >> -- >> 2.43.0 >> >> >> >> >>