From: Jinyang He <hejinyang@loongson.cn>
To: Chenghua Xu <xuchenghua@loongson.cn>,
Zhensong Liu <liuzhensong@loongson.cn>,
mengqinggang <mengqinggang@loongson.cn>,
WANG Xuerui <i.swmail@xen0n.name>
Cc: binutils@sourceware.org, Xing Li <lixing@loongson.cn>,
yala <zhaojunchao@loongson.cn>, Peng Fan <fanpeng@loongson.cn>
Subject: [PATCH 2/2] LoongArch: bfd: Add counter to get real relax region
Date: Tue, 11 Jul 2023 16:49:31 +0800 [thread overview]
Message-ID: <20230711084931.18978-2-hejinyang@loongson.cn> (raw)
In-Reply-To: <20230711084931.18978-1-hejinyang@loongson.cn>
The relax action, loongarch_relax_pcala_addi and loongarch_relax_align,
may reduce the pc value of later instructions. Add counter to count
the number of bytes or instructions deleted. And recalculate the relax
region in loongarch_relax_pcala_addi.
bfd/ChangeLog:
* elfnn-loongarch.c (loongarch_elf_relax_section): Add vars
to count the deleted instructions and the maximum number of
instructions that may be deleted due to R_LARCH_ALIGN.
(loongarch_relax_pcala_addi): Adjust the relax decision range.
ld/ChangeLog:
* testsuite/ld-loongarch-elf/relax.exp: Add test.
* testsuite/ld-loongarch-elf/relax-edge1.s: New test.
* testsuite/ld-loongarch-elf/relax-edge2.s: New test.
* testsuite/ld-loongarch-elf/relax-edge1.dd: New test.
* testsuite/ld-loongarch-elf/relax-edge2.dd: New test.
---
bfd/elfnn-loongarch.c | 31 +++++++++++++++-----
ld/testsuite/ld-loongarch-elf/relax-edge1.dd | 6 ++++
ld/testsuite/ld-loongarch-elf/relax-edge1.s | 25 ++++++++++++++++
ld/testsuite/ld-loongarch-elf/relax-edge2.dd | 8 +++++
ld/testsuite/ld-loongarch-elf/relax-edge2.s | 15 ++++++++++
ld/testsuite/ld-loongarch-elf/relax.exp | 20 +++++++++++++
6 files changed, 98 insertions(+), 7 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-edge1.dd
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-edge1.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-edge2.dd
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-edge2.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 01f349a24..52f8ab764 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3700,16 +3700,19 @@ loongarch_relax_delete_bytes (bfd *abfd,
/* Relax pcalau12i,addi.d => pcaddi. */
static bool
loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
- Elf_Internal_Rela *rel_hi, bfd_vma symval)
+ Elf_Internal_Rela *rel_hi, bfd_vma symval,
+ uint32_t align_max_deleted, uint32_t *pcnt_deleted)
{
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;
- bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
+ bfd_vma pc = sec_addr (sec) + rel_hi->r_offset - *pcnt_deleted * 4;
const uint32_t addi_d = 0x02c00000;
const uint32_t pcaddi = 0x18000000;
+ bfd_signed_vma low = (bfd_signed_vma)(int32_t)0xffe00000;
+ bfd_signed_vma high = (bfd_signed_vma)(int32_t)0x1ffffc - align_max_deleted;
/* Is pcalau12i + addi.d insns? */
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
@@ -3722,8 +3725,8 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
|| (((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))
+ || ((bfd_signed_vma)(symval - pc) < low)
+ || ((bfd_signed_vma)(symval - pc) > high))
return false;
pca = pcaddi | rd;
@@ -3734,6 +3737,7 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
R_LARCH_PCREL20_S2);
rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
R_LARCH_DELETE);
+ (*pcnt_deleted) += 1;
return true;
}
@@ -3840,6 +3844,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
struct bfd_elf_section_data *data = elf_section_data (sec);
Elf_Internal_Rela *relocs;
*again = false;
+ uint32_t cnt_deleted = 0, align_max_deleted = 0;
if (bfd_link_relocatable (info)
|| sec->sec_flg0
@@ -3881,6 +3886,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
bool local_got = false;
char symtype;
struct elf_link_hash_entry *h = NULL;
+ bool relaxed = false;
if (r_symndx < symtab_hdr->sh_info)
{
@@ -3954,6 +3960,8 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
case R_LARCH_ALIGN:
if (2 == info->relax_pass)
loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
+ else if (0 == info->relax_pass)
+ align_max_deleted += rel->r_addend;
break;
case R_LARCH_DELETE:
if (info->relax_pass == 1)
@@ -3961,23 +3969,32 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
}
+ else if (0 == info->relax_pass)
+ cnt_deleted += 1;
break;
case R_LARCH_PCALA_HI20:
if (info->relax_pass == 0)
{
if (i + 4 > sec->reloc_count)
break;
- loongarch_relax_pcala_addi (abfd, sec, rel, symval);
+ relaxed = loongarch_relax_pcala_addi (abfd, sec, rel, symval,
+ align_max_deleted, &cnt_deleted);
+ /* Skip the next R_LARCH_{RELAX, PCALA_LO12, RELAX} relocs. */
+ if (relaxed)
+ i += 3;
}
break;
case R_LARCH_GOT_PC_HI20:
- if (local_got)
+ if (info->relax_pass == 0 && local_got)
{
if (i + 4 > sec->reloc_count)
break;
if (loongarch_relax_pcala_ld (abfd, sec, rel))
{
- loongarch_relax_pcala_addi (abfd, sec, rel, symval);
+ relaxed = loongarch_relax_pcala_addi (abfd, sec, rel, symval,
+ align_max_deleted, &cnt_deleted);
+ if (relaxed)
+ i += 3;
}
}
break;
diff --git a/ld/testsuite/ld-loongarch-elf/relax-edge1.dd b/ld/testsuite/ld-loongarch-elf/relax-edge1.dd
new file mode 100644
index 000000000..92836e679
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-edge1.dd
@@ -0,0 +1,6 @@
+#...
+.*pcaddi.*
+.*pcalau12i.*
+.*addi.*
+.*pcaddi.*
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/relax-edge1.s b/ld/testsuite/ld-loongarch-elf/relax-edge1.s
new file mode 100644
index 000000000..df16c1384
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-edge1.s
@@ -0,0 +1,25 @@
+ .data
+ .type obj1, @object
+obj1:
+ .word 0
+ .size obj1, .-obj1
+
+ .space 8
+
+ .type obj2, @object
+obj2:
+ .word 0
+ .size obj2, .-obj2
+
+ .text
+main:
+ la.local $a0, obj1
+ la.local $a0, obj3
+ la.local $a0, obj2
+
+ .bss
+ .space 0x4
+ .type obj3, @object
+obj3:
+ .word 0
+ .size obj3, .-obj3
diff --git a/ld/testsuite/ld-loongarch-elf/relax-edge2.dd b/ld/testsuite/ld-loongarch-elf/relax-edge2.dd
new file mode 100644
index 000000000..5610cc8ed
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-edge2.dd
@@ -0,0 +1,8 @@
+#...
+.*nop.*
+.*nop.*
+.*nop.*
+.*nop.*
+.*pcalau12i.*
+.*addi.*
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/relax-edge2.s b/ld/testsuite/ld-loongarch-elf/relax-edge2.s
new file mode 100644
index 000000000..c2a42e705
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-edge2.s
@@ -0,0 +1,15 @@
+ .text
+main:
+ nop
+ nop
+ nop
+ nop
+ .align 4
+ la.local $a0, obj1
+
+ .data
+ .space 0x10
+ .type obj1, @object
+obj1:
+ .word 0
+ .size obj1, .-obj1
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index d2bb967c6..19ade4970 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -43,6 +43,26 @@ if [istarget loongarch64-*-*] {
] \
"relax" \
] \
+ [list \
+ "relax-edge1" \
+ "-e 0 -Ttext 0x400000 -Tdata 0x200000 -Tbss 0x600000" "" \
+ "" \
+ {relax-edge1.s} \
+ [list \
+ [list objdump -d relax-edge1.dd] \
+ ] \
+ "relax-edge1" \
+ ] \
+ [list \
+ "relax-edge2" \
+ "-e 0 -Ttext 0x400000 -Tdata 0x600000" "" \
+ "" \
+ {relax-edge2.s} \
+ [list \
+ [list objdump -d relax-edge2.dd] \
+ ] \
+ "relax-edge2" \
+ ] \
]
set objdump_flags "-s -j .data"
--
2.33.0
next prev parent reply other threads:[~2023-07-11 8:49 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-11 8:49 [PATCH 1/2] LoongArch: bfd: Remove elf_seg_map condition in loongarch_elf_relax_section Jinyang He
2023-07-11 8:49 ` Jinyang He [this message]
2023-07-12 6:35 ` mengqinggang
2023-07-12 8:08 ` Jinyang He
2023-07-13 3:13 ` mengqinggang
2023-07-13 7:19 ` Jinyang He
2023-07-13 8:18 ` Jinyang He
2023-10-05 10:09 ` Xi Ruoyao
2023-10-05 11:19 ` Xi Ruoyao
2023-10-07 1:23 ` mengqinggang
2023-10-10 13:13 ` Xi Ruoyao
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=20230711084931.18978-2-hejinyang@loongson.cn \
--to=hejinyang@loongson.cn \
--cc=binutils@sourceware.org \
--cc=fanpeng@loongson.cn \
--cc=i.swmail@xen0n.name \
--cc=liuzhensong@loongson.cn \
--cc=lixing@loongson.cn \
--cc=mengqinggang@loongson.cn \
--cc=xuchenghua@loongson.cn \
--cc=zhaojunchao@loongson.cn \
/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).