From: liuzhensong <liuzhensong@loongson.cn>
To: Xi Ruoyao <xry111@xry111.site>, binutils@sourceware.org
Cc: WANG Xuerui <i.swmail@xen0n.name>, chenglulu@loongson.cn
Subject: Re: [PATCH] LoongArch: Use copy relocation for %pc_lo12 against external symbol
Date: Thu, 1 Sep 2022 09:27:59 +0800 [thread overview]
Message-ID: <e0fad4d1-cf0f-bae6-186c-ad6a3b601d03@loongson.cn> (raw)
In-Reply-To: <20220831132259.71417-1-xry111@xry111.site>
在 2022/8/31 下午9:22, Xi Ruoyao 写道:
> We'd like to use PC-relative addressing instead of GOT for external
> symbols in main executable images. This can improve code locality.
> Doing so will need to implement copy relocation.
>
> Despite there was a comment saying "Glibc does not support copy
> relocation yet", I've run a very simple test and it seems copy
> relocation is handled by ld.so without a problem:
>
> pcalau12i $a1, %pc_hi20(stdout)
> ld.d $a1, $a1, %pc_lo12(stdout)
> pcalau12i $a0, %pc_hi20(msg)
> addi.d $a0, $a0, %pc_lo12(msg)
> pcalau12i $ra, %pc_hi20(fputs)
> jirl $ra, $ra, %pc_lo12(fputs)
>
> With this patch, R_LARCH_COPY is correctly emitted for "stdout" in
> Glibc, and the test program runs and outputs "Hello world" in "msg"
> successfully.
> ---
> bfd/elfnn-loongarch.c | 93 ++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 84 insertions(+), 9 deletions(-)
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index ed42b8b6770..0cf24bd24d8 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -743,14 +743,26 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
> h->non_got_ref = 1;
> break;
>
> - case R_LARCH_PCALA_HI20:
> + case R_LARCH_PCALA_LO12:
> if (h != NULL)
> {
> - /* For pcalau12i + jirl. */
> - h->needs_plt = 1;
> - if (h->plt.refcount < 0)
> - h->plt.refcount = 0;
> - h->plt.refcount++;
> + /* Check if it's a jirl instruction. */
> + bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
> + uint32_t insn = 0;
> +
> + if (contents || bfd_malloc_and_get_section (abfd, sec, &contents))
> + memcpy(&insn, contents + rel->r_offset, sizeof(insn));
> +
> + if ((insn & 0xfc000000) == 0x4c000000)
> + {
> + /* For pcalau12i + jirl. */
> + h->needs_plt = 1;
> + if (h->plt.refcount < 0)
> + h->plt.refcount = 0;
> + h->plt.refcount++;
> + }
> + else
> + need_dynreloc = 1;
>
> h->non_got_ref = 1;
> h->pointer_equality_needed = 1;
> @@ -949,7 +961,9 @@ loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
> struct elf_link_hash_entry *h)
> {
> struct loongarch_elf_link_hash_table *htab;
> + struct loongarch_elf_link_hash_entry *hent;
> bfd *dynobj;
> + asection *s, *srel;
>
> htab = loongarch_elf_hash_table (info);
> BFD_ASSERT (htab != NULL);
> @@ -999,9 +1013,52 @@ loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
> return true;
> }
>
> - /* R_LARCH_COPY is not adept glibc, not to generate. */
> - /* Can not print anything, because make check ld. */
> - return true;
> + /* If copy relocations is disabled via -z nocopyreloc, or we don't find any
> + dynamic relocs in read-only sections, avoid the copy reloc. */
> + if (info->nocopyreloc || !_bfd_elf_readonly_dynrelocs (h))
> + h->non_got_ref = 0;
> +
> + if (!h->non_got_ref)
> + return true;
> +
> + /* We must allocate the symbol in our .dynbss section, which will
> + become part of the .bss section of the executable. There will be
> + an entry for this symbol in the .dynsym section. The dynamic
> + object will contain position independent code, so all references
> + from the dynamic object to this symbol will go through the global
> + offset table. The dynamic linker will use the .dynsym entry to
> + determine the address it must put in the global offset table, so
> + both the dynamic object and the regular object will refer to the
> + same memory location for the variable. */
> +
> + /* Generate a copy relocation to tell the dynamic linker to copy the
> + initial value out of the dynamic object and into the runtime process
> + image. We need to remember the offset into the .rel.bss section we
> + are going to use. */
> + hent = (struct loongarch_elf_link_hash_entry *) h;
> + if (hent->tls_type & ~GOT_NORMAL)
> + {
> + s = htab->sdyntdata;
> + srel = htab->elf.srelbss;
> + }
> + else if (h->root.u.def.section->flags & SEC_READONLY)
> + {
> + s = htab->elf.sdynrelro;
> + srel = htab->elf.sreldynrelro;
> + }
> + else
> + {
> + s = htab->elf.sdynbss;
> + srel = htab->elf.srelbss;
> + }
> +
> + if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
> + {
> + srel->size += sizeof (ElfNN_External_Rela);
> + h->needs_copy = 1;
> + }
> +
> + return _bfd_elf_adjust_dynamic_copy (info, h, s);
> }
>
> /* Allocate space in .plt, .got and associated reloc sections for
> @@ -3702,6 +3759,24 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
> loongarch_elf_append_rela (output_bfd, srela, &rela);
> }
>
> + if (h->needs_copy)
> + {
> + Elf_Internal_Rela rela;
> + asection *s;
> +
> + /* This symbols needs a copy reloc. Set it up. */
> + BFD_ASSERT (h->dynindx != -1);
> +
> + rela.r_offset = sec_addr (h->root.u.def.section) + h->root.u.def.value;
> + rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_COPY);
> + rela.r_addend = 0;
> + if (h->root.u.def.section == htab->elf.sdynrelro)
> + s = htab->elf.sreldynrelro;
> + else
> + s = htab->elf.srelbss;
> + loongarch_elf_append_rela (output_bfd, s, &rela);
> + }
> +
> /* Mark some specially defined symbols as absolute. */
> if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
> sym->st_shndx = SHN_ABS;
The R_LARCH_COPY is supported in older versions,we removed this feature
and are not going to support.
WARNING: multiple messages have this Message-ID
From: liuzhensong <liuzhensong@loongson.cn>
To: Xi Ruoyao <xry111@xry111.site>, binutils@sourceware.org
Cc: WANG Xuerui <i.swmail@xen0n.name>, chenglulu@loongson.cn
Subject: Re: [PATCH] LoongArch: Use copy relocation for %pc_lo12 against external symbol
Date: Thu, 1 Sep 2022 09:27:59 +0800 [thread overview]
Message-ID: <e0fad4d1-cf0f-bae6-186c-ad6a3b601d03@loongson.cn> (raw)
Message-ID: <20220901012759.Pr7Pj1KD0T7d-0R5uJdJ5hWYGpIIXPYDBrzrezrHezY@z> (raw)
In-Reply-To: <20220831132259.71417-1-xry111@xry111.site>
[-- Attachment #1: Type: text/plain, Size: 5715 bytes --]
在 2022/8/31 下午9:22, Xi Ruoyao 写道:
> We'd like to use PC-relative addressing instead of GOT for external
> symbols in main executable images. This can improve code locality.
> Doing so will need to implement copy relocation.
>
> Despite there was a comment saying "Glibc does not support copy
> relocation yet", I've run a very simple test and it seems copy
> relocation is handled by ld.so without a problem:
>
> pcalau12i $a1, %pc_hi20(stdout)
> ld.d $a1, $a1, %pc_lo12(stdout)
> pcalau12i $a0, %pc_hi20(msg)
> addi.d $a0, $a0, %pc_lo12(msg)
> pcalau12i $ra, %pc_hi20(fputs)
> jirl $ra, $ra, %pc_lo12(fputs)
>
> With this patch, R_LARCH_COPY is correctly emitted for "stdout" in
> Glibc, and the test program runs and outputs "Hello world" in "msg"
> successfully.
> ---
> bfd/elfnn-loongarch.c | 93 ++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 84 insertions(+), 9 deletions(-)
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index ed42b8b6770..0cf24bd24d8 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -743,14 +743,26 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
> h->non_got_ref = 1;
> break;
>
> - case R_LARCH_PCALA_HI20:
> + case R_LARCH_PCALA_LO12:
> if (h != NULL)
> {
> - /* For pcalau12i + jirl. */
> - h->needs_plt = 1;
> - if (h->plt.refcount < 0)
> - h->plt.refcount = 0;
> - h->plt.refcount++;
> + /* Check if it's a jirl instruction. */
> + bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
> + uint32_t insn = 0;
> +
> + if (contents || bfd_malloc_and_get_section (abfd, sec, &contents))
> + memcpy(&insn, contents + rel->r_offset, sizeof(insn));
> +
> + if ((insn & 0xfc000000) == 0x4c000000)
> + {
> + /* For pcalau12i + jirl. */
> + h->needs_plt = 1;
> + if (h->plt.refcount < 0)
> + h->plt.refcount = 0;
> + h->plt.refcount++;
> + }
> + else
> + need_dynreloc = 1;
>
> h->non_got_ref = 1;
> h->pointer_equality_needed = 1;
> @@ -949,7 +961,9 @@ loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
> struct elf_link_hash_entry *h)
> {
> struct loongarch_elf_link_hash_table *htab;
> + struct loongarch_elf_link_hash_entry *hent;
> bfd *dynobj;
> + asection *s, *srel;
>
> htab = loongarch_elf_hash_table (info);
> BFD_ASSERT (htab != NULL);
> @@ -999,9 +1013,52 @@ loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
> return true;
> }
>
> - /* R_LARCH_COPY is not adept glibc, not to generate. */
> - /* Can not print anything, because make check ld. */
> - return true;
> + /* If copy relocations is disabled via -z nocopyreloc, or we don't find any
> + dynamic relocs in read-only sections, avoid the copy reloc. */
> + if (info->nocopyreloc || !_bfd_elf_readonly_dynrelocs (h))
> + h->non_got_ref = 0;
> +
> + if (!h->non_got_ref)
> + return true;
> +
> + /* We must allocate the symbol in our .dynbss section, which will
> + become part of the .bss section of the executable. There will be
> + an entry for this symbol in the .dynsym section. The dynamic
> + object will contain position independent code, so all references
> + from the dynamic object to this symbol will go through the global
> + offset table. The dynamic linker will use the .dynsym entry to
> + determine the address it must put in the global offset table, so
> + both the dynamic object and the regular object will refer to the
> + same memory location for the variable. */
> +
> + /* Generate a copy relocation to tell the dynamic linker to copy the
> + initial value out of the dynamic object and into the runtime process
> + image. We need to remember the offset into the .rel.bss section we
> + are going to use. */
> + hent = (struct loongarch_elf_link_hash_entry *) h;
> + if (hent->tls_type & ~GOT_NORMAL)
> + {
> + s = htab->sdyntdata;
> + srel = htab->elf.srelbss;
> + }
> + else if (h->root.u.def.section->flags & SEC_READONLY)
> + {
> + s = htab->elf.sdynrelro;
> + srel = htab->elf.sreldynrelro;
> + }
> + else
> + {
> + s = htab->elf.sdynbss;
> + srel = htab->elf.srelbss;
> + }
> +
> + if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
> + {
> + srel->size += sizeof (ElfNN_External_Rela);
> + h->needs_copy = 1;
> + }
> +
> + return _bfd_elf_adjust_dynamic_copy (info, h, s);
> }
>
> /* Allocate space in .plt, .got and associated reloc sections for
> @@ -3702,6 +3759,24 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
> loongarch_elf_append_rela (output_bfd, srela, &rela);
> }
>
> + if (h->needs_copy)
> + {
> + Elf_Internal_Rela rela;
> + asection *s;
> +
> + /* This symbols needs a copy reloc. Set it up. */
> + BFD_ASSERT (h->dynindx != -1);
> +
> + rela.r_offset = sec_addr (h->root.u.def.section) + h->root.u.def.value;
> + rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_COPY);
> + rela.r_addend = 0;
> + if (h->root.u.def.section == htab->elf.sdynrelro)
> + s = htab->elf.sreldynrelro;
> + else
> + s = htab->elf.srelbss;
> + loongarch_elf_append_rela (output_bfd, s, &rela);
> + }
> +
> /* Mark some specially defined symbols as absolute. */
> if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
> sym->st_shndx = SHN_ABS;
The R_LARCH_COPY is supported in older versions,we removed this feature
and are not going to support.
next prev parent reply other threads:[~2022-09-01 1:28 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-31 13:22 Xi Ruoyao
2022-08-31 13:41 ` Xi Ruoyao
2022-09-01 1:38 ` liuzhensong
2022-09-01 1:38 ` liuzhensong
2022-09-01 2:12 ` Xi Ruoyao
2022-09-01 2:31 ` liuzhensong
2022-09-01 2:31 ` liuzhensong
2022-09-01 1:27 ` liuzhensong [this message]
2022-09-01 1:27 ` liuzhensong
2022-09-01 1:41 ` Xi Ruoyao
2022-09-01 2:09 ` liuzhensong
2022-09-01 7:42 ` Fangrui Song
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e0fad4d1-cf0f-bae6-186c-ad6a3b601d03@loongson.cn \
--to=liuzhensong@loongson.cn \
--cc=binutils@sourceware.org \
--cc=chenglulu@loongson.cn \
--cc=i.swmail@xen0n.name \
--cc=xry111@xry111.site \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).