* [PATCH v1] LoongArch: gas: Ignore .align if it is at the start of a section
@ 2024-03-20 10:07 mengqinggang
2024-03-20 11:08 ` H.J. Lu
0 siblings, 1 reply; 4+ messages in thread
From: mengqinggang @ 2024-03-20 10:07 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, cailulu, xry111, i.swmail,
maskray, luweining, wanglei, hejinyang, mengqinggang
Ignore .align if it is at the start of a section, the section alignment
can ensure correct alignment.
---
gas/config/tc-loongarch.c | 105 ++++++++++++++----
.../gas/loongarch/relax-align-first.d | 12 ++
.../gas/loongarch/relax-align-first.s | 7 ++
.../ld-loongarch-elf/relax-align-first.d | 15 +++
.../ld-loongarch-elf/relax-align-first.s | 13 +++
ld/testsuite/ld-loongarch-elf/relax.exp | 1 +
6 files changed, 133 insertions(+), 20 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/relax-align-first.d
create mode 100644 gas/testsuite/gas/loongarch/relax-align-first.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-first.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-first.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 30aefce36fd..b009186e66f 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -128,6 +128,11 @@ static bool call36 = 0;
#define RELAX_BRANCH_ENCODE(x) \
(BFD_RELOC_LARCH_B16 == (x) ? RELAX_BRANCH_16 : RELAX_BRANCH_21)
+#define ALIGN_MAX_ADDEND(n, max) ((max << 8) | n)
+#define ALIGN_MAX_NOP_BYTES(addend) ((1 << (addend & 0xff)) - 4)
+#define FRAG_AT_START_OF_SECTION(frag) \
+ (0 == frag->fr_address && 0 == frag->fr_fix)
+
enum options
{
OPTION_IGNORE = OPTION_MD_BASE,
@@ -1647,11 +1652,22 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
}
}
+/* Before relax, return the fixed size of a frag to calculate address. */
+
int
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
asection *segtype ATTRIBUTE_UNUSED)
{
- return (fragp->fr_var = 4);
+ if (RELAX_BRANCH (fragp->fr_subtype))
+ return (fragp->fr_var = 4);
+ else /* R_LARCH_ALIGN */
+ if (FRAG_AT_START_OF_SECTION (fragp))
+ return (fragp->fr_var = 0);
+ else
+ if (NULL == fragp->fr_symbol)
+ return (fragp->fr_var = fragp->fr_offset);
+ else
+ return (fragp->fr_var = ALIGN_MAX_NOP_BYTES (fragp->fr_offset));
}
/* Translate internal representation of relocation info to BFD target
@@ -1767,8 +1783,7 @@ bool
loongarch_frag_align_code (int n, int max)
{
char *nops;
- symbolS *s;
- expressionS ex;
+ symbolS *s = NULL;
bfd_vma insn_alignment = 4;
bfd_vma bytes = (bfd_vma) 1 << n;
@@ -1783,8 +1798,6 @@ loongarch_frag_align_code (int n, int max)
if (!LARCH_opts.relax)
return false;
- nops = frag_more (worst_case_bytes);
-
/* If max <= 0, ignore max.
If max >= worst_case_bytes, max has no effect.
Similar to gas/write.c relax_segment function rs_align_code case:
@@ -1795,21 +1808,22 @@ loongarch_frag_align_code (int n, int max)
if (s == NULL)
s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg,
&zero_address_frag, 0);
- ex.X_add_symbol = s;
- ex.X_op = O_symbol;
- ex.X_add_number = (max << 8) | n;
- }
- else
- {
- ex.X_op = O_constant;
- ex.X_add_number = worst_case_bytes;
}
+ frag_grow (worst_case_bytes);
+ /* Use relaxable frag for .align.
+ If .align at the start of section, do nothing. Section alignment can
+ ensure correct alignment.
+ If .align is not at the start of a section, reserve NOP instructions
+ and R_LARCH_ALIGN relocation. */
+ nops = frag_var (rs_machine_dependent, worst_case_bytes, worst_case_bytes,
+ rs_align_code, s,
+ s ? (bfd_vma) ALIGN_MAX_ADDEND (n, max) : worst_case_bytes,
+ NULL);
+
+ /* Default write NOP for aligned bytes. */
loongarch_make_nops (nops, worst_case_bytes);
- fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
- &ex, false, BFD_RELOC_LARCH_ALIGN);
-
/* We need to start a new frag after the alignment which may be removed by
the linker, to prevent the assembler from computing static offsets.
This is necessary to get correct EH info. */
@@ -1976,6 +1990,20 @@ loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED,
fragp->fr_var = loongarch_relaxed_branch_length (fragp, sec, true);
return fragp->fr_var - old_var;
}
+ else if (rs_align_code == fragp->fr_subtype)
+ {
+ offsetT old_var = fragp->fr_var;
+ /* If .align at the start of a section, do nothing. Section alignment
+ * can ensure correct alignment. */
+ if (FRAG_AT_START_OF_SECTION (fragp))
+ fragp->fr_var = 0;
+ else
+ if (NULL == fragp->fr_symbol)
+ fragp->fr_var = fragp->fr_offset;
+ else
+ fragp->fr_var = ALIGN_MAX_NOP_BYTES (fragp->fr_offset);
+ return fragp->fr_var - old_var;
+ }
return 0;
}
@@ -2051,13 +2079,50 @@ loongarch_convert_frag_branch (fragS *fragp)
fragp->fr_fix += fragp->fr_var;
}
-/* Relax a machine dependent frag. This returns the amount by which
- the current size of the frag should change. */
+/* Relax .align frag. */
+
+static void
+loongarch_convert_frag_align (fragS *fragp)
+{
+ bfd_byte *buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
+
+ if (!FRAG_AT_START_OF_SECTION (fragp))
+ {
+ expressionS exp;
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fragp->fr_symbol;
+ exp.X_add_number = fragp->fr_offset;
+
+ unsigned long size = 0;
+ if (NULL == fragp->fr_symbol)
+ size = fragp->fr_offset;
+ else
+ size = ALIGN_MAX_NOP_BYTES (fragp->fr_offset);
+
+ fixS *fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ size, &exp, false, BFD_RELOC_LARCH_ALIGN);
+ fixp->fx_file = fragp->fr_file;
+ fixp->fx_line = fragp->fr_line;
+
+ buf += size;
+ }
+
+ gas_assert (buf == (bfd_byte *)fragp->fr_literal
+ + fragp->fr_fix + fragp->fr_var);
+
+ fragp->fr_fix += fragp->fr_var;
+}
+
+/* Relax a machine dependent frag. */
void
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
fragS *fragp)
{
- gas_assert (RELAX_BRANCH (fragp->fr_subtype));
- loongarch_convert_frag_branch (fragp);
+ gas_assert (RELAX_BRANCH (fragp->fr_subtype)
+ || rs_align_code == fragp->fr_subtype);
+ if (RELAX_BRANCH (fragp->fr_subtype))
+ loongarch_convert_frag_branch (fragp);
+ else if (rs_align_code == fragp->fr_subtype)
+ loongarch_convert_frag_align (fragp);
}
diff --git a/gas/testsuite/gas/loongarch/relax-align-first.d b/gas/testsuite/gas/loongarch/relax-align-first.d
new file mode 100644
index 00000000000..ec0698b6995
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-align-first.d
@@ -0,0 +1,12 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+0* <.text>:
+[ ]+0:[ ]+4c000020[ ]+ret
+Disassembly of section abc:
+0* <abc>:
+[ ]+0:[ ]+4c000020[ ]+ret
diff --git a/gas/testsuite/gas/loongarch/relax-align-first.s b/gas/testsuite/gas/loongarch/relax-align-first.s
new file mode 100644
index 00000000000..a4c3d68fee3
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-align-first.s
@@ -0,0 +1,7 @@
+.text
+.align 3
+ret
+
+.section "abc", "ax"
+.align 4, ,4
+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.d b/ld/testsuite/ld-loongarch-elf/relax-align-first.d
new file mode 100644
index 00000000000..9a4fad8ea46
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-first.d
@@ -0,0 +1,15 @@
+#ld: -e0
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section aaa:
+0000000120000078 <aaa>:
+[ ]+120000078:[ ]+4c000020[ ]+ret
+Disassembly of section bbb:
+0000000120000080 <bbb>:
+[ ]+120000080:[ ]+4c000020[ ]+ret
+Disassembly of section ccc:
+0000000120000090 <__bss_start-0x4004>:
+[ ]+120000090:[ ]+4c000020[ ]+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.s b/ld/testsuite/ld-loongarch-elf/relax-align-first.s
new file mode 100644
index 00000000000..0a9115b5bcf
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-first.s
@@ -0,0 +1,13 @@
+# If .align at the start of a section, do not add NOP instructions
+# and do not emit R_LARCH_ALIGN relocations.
+# Section alignment can ensure correct alignment.
+.section "aaa", "ax"
+ret
+
+.section "bbb", "ax"
+.align 3
+ret
+
+.section "ccc", "ax"
+.align 4, ,4
+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 7d95a9ca41d..969918955e3 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -20,6 +20,7 @@
#
if [istarget loongarch64-*-*] {
+ run_dump_test "relax-align-first"
if [isbuild loongarch64-*-*] {
set testname "loongarch relax .exe build"
--
2.36.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v1] LoongArch: gas: Ignore .align if it is at the start of a section
2024-03-20 10:07 [PATCH v1] LoongArch: gas: Ignore .align if it is at the start of a section mengqinggang
@ 2024-03-20 11:08 ` H.J. Lu
2024-03-20 12:53 ` Xi Ruoyao
0 siblings, 1 reply; 4+ messages in thread
From: H.J. Lu @ 2024-03-20 11:08 UTC (permalink / raw)
To: mengqinggang
Cc: binutils, xuchenghua, chenglulu, liuzhensong, cailulu, xry111,
i.swmail, maskray, luweining, wanglei, hejinyang
On Wed, Mar 20, 2024 at 3:08 AM mengqinggang <mengqinggang@loongson.cn> wrote:
>
> Ignore .align if it is at the start of a section, the section alignment
> can ensure correct alignment.
What happens when the section is aligned at 8 bytes and .align is aligned to
16 bytes?
--
H.J.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v1] LoongArch: gas: Ignore .align if it is at the start of a section
2024-03-20 11:08 ` H.J. Lu
@ 2024-03-20 12:53 ` Xi Ruoyao
2024-03-21 1:34 ` mengqinggang
0 siblings, 1 reply; 4+ messages in thread
From: Xi Ruoyao @ 2024-03-20 12:53 UTC (permalink / raw)
To: H.J. Lu, mengqinggang
Cc: binutils, xuchenghua, chenglulu, liuzhensong, cailulu, i.swmail,
maskray, luweining, wanglei, hejinyang
On Wed, 2024-03-20 at 04:08 -0700, H.J. Lu wrote:
> On Wed, Mar 20, 2024 at 3:08 AM mengqinggang <mengqinggang@loongson.cn> wrote:
> >
> > Ignore .align if it is at the start of a section, the section alignment
> > can ensure correct alignment.
>
> What happens when the section is aligned at 8 bytes and .align is aligned to
> 16 bytes?
If it happens we should increase the section alignment to 16, or we were
silently generating broken output and we had a bug anyway...
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v1] LoongArch: gas: Ignore .align if it is at the start of a section
2024-03-20 12:53 ` Xi Ruoyao
@ 2024-03-21 1:34 ` mengqinggang
0 siblings, 0 replies; 4+ messages in thread
From: mengqinggang @ 2024-03-21 1:34 UTC (permalink / raw)
To: Xi Ruoyao, H.J. Lu
Cc: binutils, xuchenghua, chenglulu, liuzhensong, cailulu, i.swmail,
maskray, luweining, wanglei, hejinyang
在 2024/3/20 下午8:53, Xi Ruoyao 写道:
> On Wed, 2024-03-20 at 04:08 -0700, H.J. Lu wrote:
>> On Wed, Mar 20, 2024 at 3:08 AM mengqinggang <mengqinggang@loongson.cn> wrote:
>>> Ignore .align if it is at the start of a section, the section alignment
>>> can ensure correct alignment.
>> What happens when the section is aligned at 8 bytes and .align is aligned to
>> 16 bytes?
According to my understanding, section alignment is the maximum
alignment within section.
And, can we set the alignment of a section separately?
> If it happens we should increase the section alignment to 16, or we were
> silently generating broken output and we had a bug anyway...
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-03-21 1:34 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-20 10:07 [PATCH v1] LoongArch: gas: Ignore .align if it is at the start of a section mengqinggang
2024-03-20 11:08 ` H.J. Lu
2024-03-20 12:53 ` Xi Ruoyao
2024-03-21 1:34 ` mengqinggang
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).