* [PATCH v2 0/6] LoongArch linker relaxation support.
@ 2022-12-13 6:58 mengqinggang
2022-12-13 6:58 ` [PATCH v2 1/6] LoongArch: include: Add support for linker relaxation mengqinggang
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: mengqinggang @ 2022-12-13 6:58 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, liuzhensong, chenglulu, xry111, i.swmail, maskray,
schwab, mengqinggang
This is the v2 version of patches to support loongarch linker relax.
The new relocs document at here:
https://github.com/loongson/LoongArch-Documentation/pull/77
The patch set changelog:
v1 -> v2:
1. Simplified a ld relax test.
2. Use the C99 designated initializer syntax for LARCH_opts.relax.
3. Fix one spelling error.
mengqinggang (6):
LoongArch: include: Add support for linker relaxation.
LoongArch: bfd: Add support for linker relaxation.
LoongArch: opcodes: Add support for linker relaxation.
LoongArch: binutils: Add support for linker relaxation.
LoongArch: gas: Add support for linker relaxation.
LoongArch: ld: Add support for linker relaxation.
bfd/bfd-in2.h | 8 +
bfd/elfnn-loongarch.c | 582 +++++++++++++--
bfd/elfxx-loongarch.c | 676 +++++++++++++-----
bfd/elfxx-loongarch.h | 10 +-
bfd/libbfd.h | 8 +
bfd/reloc.c | 22 +
binutils/readelf.c | 84 ++-
binutils/testsuite/binutils-all/readelf.exp | 13 +-
gas/config/tc-loongarch.c | 412 +++++++++--
gas/config/tc-loongarch.h | 45 +-
gas/testsuite/gas/all/align.d | 5 +-
gas/testsuite/gas/all/gas.exp | 10 +-
gas/testsuite/gas/all/relax.d | 4 +
gas/testsuite/gas/elf/dwarf-5-irp.d | 3 +-
gas/testsuite/gas/elf/dwarf-5-loc0.d | 3 +-
gas/testsuite/gas/elf/dwarf2-11.d | 3 +-
gas/testsuite/gas/elf/dwarf2-15.d | 3 +-
gas/testsuite/gas/elf/dwarf2-16.d | 3 +-
gas/testsuite/gas/elf/dwarf2-17.d | 3 +-
gas/testsuite/gas/elf/dwarf2-18.d | 3 +-
gas/testsuite/gas/elf/dwarf2-19.d | 3 +-
gas/testsuite/gas/elf/dwarf2-5.d | 3 +-
gas/testsuite/gas/elf/ehopt0.d | 3 +
gas/testsuite/gas/elf/elf.exp | 3 +
gas/testsuite/gas/elf/section11.d | 4 +-
gas/testsuite/gas/lns/lns.exp | 1 +
gas/testsuite/gas/loongarch/jmp_op.d | 65 +-
gas/testsuite/gas/loongarch/li.d | 9 +-
gas/testsuite/gas/loongarch/macro_op.d | 69 +-
.../gas/loongarch/macro_op_large_abs.d | 103 +--
.../gas/loongarch/macro_op_large_pc.d | 103 +--
gas/testsuite/gas/loongarch/relax_align.d | 25 +
gas/testsuite/gas/loongarch/relax_align.s | 5 +
gas/testsuite/gas/loongarch/uleb128.d | 35 +
gas/testsuite/gas/loongarch/uleb128.s | 20 +
include/elf/loongarch.h | 20 +
include/opcode/loongarch.h | 3 +
ld/emultempl/loongarchelf.em | 3 +
ld/testsuite/ld-elf/compressed1d.d | 3 +
ld/testsuite/ld-elf/pr26936.d | 4 +-
ld/testsuite/ld-loongarch-elf/disas-jirl.d | 4 +-
ld/testsuite/ld-loongarch-elf/jmp_op.d | 65 +-
ld/testsuite/ld-loongarch-elf/macro_op.d | 138 ++--
ld/testsuite/ld-loongarch-elf/relax-align.dd | 7 +
ld/testsuite/ld-loongarch-elf/relax-align.s | 9 +
ld/testsuite/ld-loongarch-elf/relax.exp | 73 ++
ld/testsuite/ld-loongarch-elf/relax.s | 16 +
ld/testsuite/ld-loongarch-elf/uleb128.dd | 10 +
ld/testsuite/ld-loongarch-elf/uleb128.s | 21 +
opcodes/loongarch-opc.c | 5 +-
50 files changed, 2192 insertions(+), 540 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/relax_align.d
create mode 100644 gas/testsuite/gas/loongarch/relax_align.s
create mode 100644 gas/testsuite/gas/loongarch/uleb128.d
create mode 100644 gas/testsuite/gas/loongarch/uleb128.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align.dd
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax.exp
create mode 100644 ld/testsuite/ld-loongarch-elf/relax.s
create mode 100644 ld/testsuite/ld-loongarch-elf/uleb128.dd
create mode 100644 ld/testsuite/ld-loongarch-elf/uleb128.s
--
2.36.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/6] LoongArch: include: Add support for linker relaxation.
2022-12-13 6:58 [PATCH v2 0/6] LoongArch linker relaxation support mengqinggang
@ 2022-12-13 6:58 ` mengqinggang
2022-12-13 6:58 ` [PATCH v2 2/6] LoongArch: bfd: " mengqinggang
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: mengqinggang @ 2022-12-13 6:58 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, liuzhensong, chenglulu, xry111, i.swmail, maskray,
schwab, mengqinggang
Add relocs and gas LARCH_opts.relax option.
include/ChangeLog:
* elf/loongarch.h: Add relocs.
* opcode/loongarch.h: Add LARCH_opts.relax and macro LARCH_NOP.
---
include/elf/loongarch.h | 20 ++++++++++++++++++++
include/opcode/loongarch.h | 3 +++
2 files changed, 23 insertions(+)
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index a6341b46791..4e7470064e7 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -229,6 +229,26 @@ RELOC_NUMBER (R_LARCH_32_PCREL, 99)
/* RELAX. */
RELOC_NUMBER (R_LARCH_RELAX, 100)
+/* relax delete. */
+RELOC_NUMBER (R_LARCH_DELETE, 101)
+
+/* relax align. */
+RELOC_NUMBER (R_LARCH_ALIGN, 102)
+
+/* pcaddi. */
+RELOC_NUMBER (R_LARCH_PCREL20_S2, 103)
+
+/* cfa. */
+RELOC_NUMBER (R_LARCH_CFA, 104)
+
+/* DW_CFA_advance_loc. */
+RELOC_NUMBER (R_LARCH_ADD6, 105)
+RELOC_NUMBER (R_LARCH_SUB6, 106)
+
+/* unsigned leb128. */
+RELOC_NUMBER (R_LARCH_ADD_ULEB128, 107)
+RELOC_NUMBER (R_LARCH_SUB_ULEB128, 108)
+
END_RELOC_NUMBERS (R_LARCH_count)
/* Processor specific flags for the ELF header e_flags field. */
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index c3922348a56..71570e9acc2 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -28,6 +28,8 @@ extern "C"
{
#endif
+ #define LARCH_NOP 0x03400000
+
typedef uint32_t insn_t;
struct loongarch_opcode
@@ -228,6 +230,7 @@ dec2 : [1-9][0-9]?
#define ase_gpcr isa.use_la_global_with_pcrel
#define ase_gabs isa.use_la_global_with_abs
+ int relax;
} LARCH_opts;
extern size_t loongarch_insn_length (insn_t insn);
--
2.36.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/6] LoongArch: bfd: Add support for linker relaxation.
2022-12-13 6:58 [PATCH v2 0/6] LoongArch linker relaxation support mengqinggang
2022-12-13 6:58 ` [PATCH v2 1/6] LoongArch: include: Add support for linker relaxation mengqinggang
@ 2022-12-13 6:58 ` mengqinggang
2022-12-13 6:58 ` [PATCH v2 3/6] LoongArch: opcodes: " mengqinggang
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: mengqinggang @ 2022-12-13 6:58 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, liuzhensong, chenglulu, xry111, i.swmail, maskray,
schwab, mengqinggang
Add relax support and related relocs in bfd.
bfd/ChangeLog:
* bfd-in2.h: Add relocs related to relax.
* elfnn-loongarch.c (struct loongarch_elf_link_hash_table): New integer
pointer (data_segment_phase) to monitor the data segment phase.
(loongarch_elf_check_relocs): Swap B21/B26 reloc sequence.
(loongarch_elf_adjust_dynamic_symbol): Fix code format.
(loongarch_reloc_rewrite_imm_insn): Fix function call.
(perform_relocation): Handle new relocs related to relax.
(RELOCATE_CALC_PC32_HI20): Fix code format.
(RELOCATE_CALC_PC64_HI32): Likewise.
(loongarch_elf_relocate_section): Handle new relocs related to relax.
(loongarch_relax_delete_bytes): New function.
(loongarch_relax_pcala_addi): Likewise.
(loongarch_relax_pcala_ld): Likewise.
(bfd_elfNN_loongarch_set_data_segment_info): Likewise.
(loongarch_relax_align): Likewise.
(loongarch_elf_relax_section): Likewise.
(bfd_elfNN_bfd_relax_section): New macro define.
* elfxx-loongarch.c (reloc_bits): New bfd point parameter.
(reloc_bits_b16): Likewise.
(reloc_bits_b21): Likewise.
(reloc_bits_b26): Likewise.
(loongarch_adjust_reloc_bitsfield): Likewise.
(reloc_bits_pcrel20_s2): New function.
(loongarch_elf_add_sub_reloc): Likewise.
(loongarch_elf_add_sub_reloc_uleb128): Likewise.
(loongarch_write_unsigned_leb128): New function.
* elfxx-loongarch.h (loongarch_adjust_reloc_bitsfield): New bfd point
parameter.
(bfd_elf32_loongarch_set_data_segment_info): New declare.
(bfd_elf64_loongarch_set_data_segment_info): Likewise.
(loongarch_write_unsigned_leb128): Likewise.
* libbfd.h: Add relocs related to relax.
* reloc.c: Add relocs related to relax.
---
bfd/bfd-in2.h | 8 +
bfd/elfnn-loongarch.c | 582 ++++++++++++++++++++++++++++++++----
bfd/elfxx-loongarch.c | 676 +++++++++++++++++++++++++++++++-----------
bfd/elfxx-loongarch.h | 10 +-
bfd/libbfd.h | 8 +
bfd/reloc.c | 22 ++
6 files changed, 1077 insertions(+), 229 deletions(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 0b071dda1e5..39e3868f6cf 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6310,6 +6310,14 @@ assembler and not (currently) written to any object files. */
BFD_RELOC_LARCH_TLS_GD_HI20,
BFD_RELOC_LARCH_32_PCREL,
BFD_RELOC_LARCH_RELAX,
+ BFD_RELOC_LARCH_DELETE,
+ BFD_RELOC_LARCH_ALIGN,
+ BFD_RELOC_LARCH_PCREL20_S2,
+ BFD_RELOC_LARCH_CFA,
+ BFD_RELOC_LARCH_ADD6,
+ BFD_RELOC_LARCH_SUB6,
+ BFD_RELOC_LARCH_ADD_ULEB128,
+ BFD_RELOC_LARCH_SUB_ULEB128,
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 8d8a6a47317..11a0da8c3c7 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -27,6 +27,7 @@
#include "objalloc.h"
#include "elf/loongarch.h"
#include "elfxx-loongarch.h"
+#include "opcode/loongarch.h"
static bool
loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr,
@@ -93,6 +94,10 @@ struct loongarch_elf_link_hash_table
/* The max alignment of output sections. */
bfd_vma max_alignment;
+
+ /* The data segment phase, don't relax the section
+ when it is exp_seg_relro_adjust. */
+ int *data_segment_phase;
};
/* Get the LoongArch ELF linker hash table from a link_info structure. */
@@ -772,8 +777,8 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
break;
- case R_LARCH_B21:
case R_LARCH_B16:
+ case R_LARCH_B21:
case R_LARCH_B26:
if (h != NULL)
{
@@ -972,8 +977,12 @@ loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
/* Make sure we know what is going on here. */
BFD_ASSERT (dynobj != NULL
- && (h->needs_plt || h->type == STT_GNU_IFUNC || h->is_weakalias
- || (h->def_dynamic && h->ref_regular && !h->def_regular)));
+ && (h->needs_plt
+ || h->type == STT_GNU_IFUNC
+ || h->is_weakalias
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later
@@ -1886,7 +1895,7 @@ loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
int bits = bfd_get_reloc_size (howto) * 8;
uint32_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
- if (!loongarch_adjust_reloc_bitsfield(howto, &reloc_val))
+ if (!loongarch_adjust_reloc_bitsfield (input_bfd, howto, &reloc_val))
return bfd_reloc_overflow;
insn = (insn & (uint32_t)howto->src_mask)
@@ -2006,42 +2015,73 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
bfd_put (bits, input_bfd, value, contents + rel->r_offset);
break;
+ /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
+ Because set/sub reloc pair not support multi-thread. While add/sub
+ reloc pair process order not affect the final result.
+
+ For add/sub reloc, the original value will be involved in the
+ calculation. In order not to add/sub extra value, we write 0 to symbol
+ address at assembly time.
+
+ add/sub reloc bits determined by the value after symbol subtraction,
+ not symbol value.
+
+ add/sub reloc save part of the symbol value, so we only need to
+ save howto->dst_mask bits. */
+ case R_LARCH_ADD6:
+ case R_LARCH_SUB6:
+ {
+ bfd_vma word = bfd_get (howto->bitsize, input_bfd,
+ contents + rel->r_offset);
+ word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
+ bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
+ r = bfd_reloc_ok;
+ break;
+ }
+
+ /* Not need to read the original value, just write the new value. */
case R_LARCH_ADD8:
case R_LARCH_ADD16:
case R_LARCH_ADD24:
case R_LARCH_ADD32:
case R_LARCH_ADD64:
- r = loongarch_check_offset (rel, input_section);
- if (r != bfd_reloc_ok)
- break;
-
- opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
- bfd_put (bits, input_bfd, opr1 + value, contents + rel->r_offset);
- break;
-
case R_LARCH_SUB8:
case R_LARCH_SUB16:
case R_LARCH_SUB24:
case R_LARCH_SUB32:
case R_LARCH_SUB64:
- r = loongarch_check_offset (rel, input_section);
- if (r != bfd_reloc_ok)
+ {
+ /* Because add/sub reloc is processed separately,
+ so the high bits is invalid. */
+ bfd_vma word = value & howto->dst_mask;
+ bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
+ r = bfd_reloc_ok;
break;
+ }
- opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
- bfd_put (bits, input_bfd, opr1 - value, contents + rel->r_offset);
- break;
+ case R_LARCH_ADD_ULEB128:
+ case R_LARCH_SUB_ULEB128:
+ {
+ unsigned int len = 0;
+ /* Before write uleb128, first read it to get it's length. */
+ _bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len);
+ loongarch_write_unsigned_leb128 (contents + rel->r_offset, len, value);
+ r = bfd_reloc_ok;
+ break;
+ }
/* For eh_frame and debug info. */
case R_LARCH_32_PCREL:
- value -= sec_addr (input_section) + rel->r_offset;
- value += rel->r_addend;
- bfd_vma word = bfd_get (howto->bitsize, input_bfd,
- contents + rel->r_offset);
- word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
- bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
- r = bfd_reloc_ok;
- break;
+ {
+ value -= sec_addr (input_section) + rel->r_offset;
+ value += rel->r_addend;
+ bfd_vma word = bfd_get (howto->bitsize, input_bfd,
+ contents + rel->r_offset);
+ word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
+ bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
+ r = bfd_reloc_ok;
+ break;
+ }
/* New reloc type.
R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */
@@ -2080,6 +2120,7 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
case R_LARCH_TLS_LD_HI20:
case R_LARCH_TLS_GD_PC_HI20:
case R_LARCH_TLS_GD_HI20:
+ case R_LARCH_PCREL20_S2:
r = loongarch_check_offset (rel, input_section);
if (r != bfd_reloc_ok)
break;
@@ -2246,9 +2287,9 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
#define RELOCATE_CALC_PC32_HI20(relocation, pc) \
({ \
- bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \
+ bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
pc = pc & (~(bfd_vma)0xfff); \
- if (lo > 0x7ff) \
+ if (__lo > 0x7ff) \
{ \
relocation += 0x1000; \
} \
@@ -2258,8 +2299,8 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
#define RELOCATE_CALC_PC64_HI32(relocation, pc) \
({ \
- bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \
- if (lo > 0x7ff) \
+ bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
+ if (__lo > 0x7ff) \
{ \
relocation -= 0x100000000; \
} \
@@ -2524,29 +2565,49 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
relocation += rel->r_addend;
break;
+ case R_LARCH_ADD6:
case R_LARCH_ADD8:
case R_LARCH_ADD16:
case R_LARCH_ADD24:
case R_LARCH_ADD32:
case R_LARCH_ADD64:
+ {
+ bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
+ contents + rel->r_offset);
+ relocation = old_value + relocation + rel->r_addend;
+ break;
+ }
+
+ case R_LARCH_SUB6:
case R_LARCH_SUB8:
case R_LARCH_SUB16:
case R_LARCH_SUB24:
case R_LARCH_SUB32:
case R_LARCH_SUB64:
- if (resolved_dynly)
- fatal = (loongarch_reloc_is_fatal
- (info, input_bfd, input_section, rel, howto,
- bfd_reloc_undefined, is_undefweak, name,
- "Can't be resolved dynamically. "
- "If this procedure is hand-written assembly,\n"
- "there must be something like '.dword sym1 - sym2' "
- "to generate these relocs\n"
- "and we can't get known link-time address of "
- "these symbols."));
- else
- relocation += rel->r_addend;
- break;
+ {
+ bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
+ contents + rel->r_offset);
+ relocation = old_value - relocation - rel->r_addend;
+ break;
+ }
+
+ case R_LARCH_ADD_ULEB128:
+ case R_LARCH_SUB_ULEB128:
+ {
+ /* Get the value and length of the uleb128 data. */
+ unsigned int len = 0;
+ bfd_vma old_value = _bfd_read_unsigned_leb128 (input_bfd,
+ contents + rel->r_offset, &len);
+
+ if (R_LARCH_ADD_ULEB128 == ELFNN_R_TYPE (rel->r_info))
+ relocation = old_value + relocation + rel->r_addend;
+ else if (R_LARCH_SUB_ULEB128 == ELFNN_R_TYPE (rel->r_info))
+ relocation = old_value - relocation - rel->r_addend;
+
+ bfd_vma mask = (1 << (7 * len)) - 1;
+ relocation &= mask;
+ break;
+ }
case R_LARCH_TLS_DTPREL32:
case R_LARCH_TLS_DTPREL64:
@@ -3086,6 +3147,15 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
break;
+ case R_LARCH_PCREL20_S2:
+ unresolved_reloc = false;
+ if (h && h->plt.offset != MINUS_ONE)
+ relocation = sec_addr (plt) + h->plt.offset;
+ else
+ relocation += rel->r_addend;
+ relocation -= pc;
+ break;
+
case R_LARCH_PCALA_HI20:
unresolved_reloc = false;
if (h && h->plt.offset != MINUS_ONE)
@@ -3111,15 +3181,15 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
else
relocation += rel->r_addend;
- relocation &= 0xfff;
- /* Signed extend. */
- relocation = (relocation ^ 0x800) - 0x800;
-
/* For 2G jump, generate pcalau12i, jirl. */
/* If use jirl, turns to R_LARCH_B16. */
uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
if ((insn & 0x4c000000) == 0x4c000000)
{
+ relocation &= 0xfff;
+ /* Signed extend. */
+ relocation = (relocation ^ 0x800) - 0x800;
+
rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16);
howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
}
@@ -3255,13 +3325,12 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+ (idx * GOT_ENTRY_SIZE)
- sec_addr (htab->elf.sgot);
}
+
relocation = got_off + sec_addr (got);
}
- if (r_type == R_LARCH_GOT_PC_LO12)
- relocation &= (bfd_vma)0xfff;
- else if (r_type == R_LARCH_GOT64_PC_LO20
- || r_type == R_LARCH_GOT64_PC_HI12)
+ if (r_type == R_LARCH_GOT64_PC_HI12
+ || r_type == R_LARCH_GOT64_PC_LO20)
RELOCATE_CALC_PC64_HI32 (relocation, pc);
break;
@@ -3419,15 +3488,16 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
relocation += 2 * GOT_ENTRY_SIZE;
- if (r_type == R_LARCH_TLS_IE_PC_LO12)
- relocation &= (bfd_vma)0xfff;
- else if (r_type == R_LARCH_TLS_IE64_PC_LO20
- || r_type == R_LARCH_TLS_IE64_PC_HI12)
+ if (r_type == R_LARCH_TLS_IE64_PC_LO20
+ || r_type == R_LARCH_TLS_IE64_PC_HI12)
RELOCATE_CALC_PC64_HI32 (relocation, pc);
break;
case R_LARCH_RELAX:
+ case R_LARCH_ALIGN:
+ r = bfd_reloc_continue;
+ unresolved_reloc = false;
break;
default:
@@ -3518,6 +3588,409 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
return !fatal;
}
+static bool
+loongarch_relax_delete_bytes (bfd *abfd,
+ asection *sec,
+ bfd_vma addr,
+ size_t count,
+ struct bfd_link_info *link_info)
+{
+ unsigned int i, symcount;
+ bfd_vma toaddr = sec->size;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+ struct bfd_elf_section_data *data = elf_section_data (sec);
+ bfd_byte *contents = data->this_hdr.contents;
+
+ /* Actually delete the bytes. */
+ sec->size -= count;
+ memmove (contents + addr, contents + addr + count, toaddr - addr - count);
+
+ /* Adjust the location of all of the relocs. Note that we need not
+ adjust the addends, since all PC-relative references must be against
+ symbols, which we will adjust below. */
+ for (i = 0; i < sec->reloc_count; i++)
+ if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
+ data->relocs[i].r_offset -= count;
+
+ /* Adjust the local symbols defined in this section. */
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ {
+ Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
+ if (sym->st_shndx == sec_shndx)
+ {
+ /* If the symbol is in the range of memory we just moved, we
+ have to adjust its value. */
+ if (sym->st_value > addr && sym->st_value <= toaddr)
+ sym->st_value -= count;
+
+ /* If the symbol *spans* the bytes we just deleted (i.e. its
+ *end* is in the moved bytes but its *start* isn't), then we
+ must adjust its size.
+
+ This test needs to use the original value of st_value, otherwise
+ we might accidentally decrease size when deleting bytes right
+ before the symbol. But since deleted relocs can't span across
+ symbols, we can't have both a st_value and a st_size decrease,
+ so it is simpler to just use an else. */
+ else if (sym->st_value <= addr
+ && sym->st_value + sym->st_size > addr
+ && sym->st_value + sym->st_size <= toaddr)
+ sym->st_size -= count;
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = ((symtab_hdr->sh_size / sizeof (ElfNN_External_Sym))
+ - symtab_hdr->sh_info);
+
+ for (i = 0; i < symcount; i++)
+ {
+ struct elf_link_hash_entry *sym_hash = sym_hashes[i];
+
+ /* The '--wrap SYMBOL' option is causing a pain when the object file,
+ containing the definition of __wrap_SYMBOL, includes a direct
+ call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
+ the same symbol (which is __wrap_SYMBOL), but still exist as two
+ different symbols in 'sym_hashes', we don't want to adjust
+ the global symbol __wrap_SYMBOL twice.
+
+ The same problem occurs with symbols that are versioned_hidden, as
+ foo becomes an alias for foo@BAR, and hence they need the same
+ treatment. */
+ if (link_info->wrap_hash != NULL
+ || sym_hash->versioned != unversioned)
+ {
+ struct elf_link_hash_entry **cur_sym_hashes;
+
+ /* Loop only over the symbols which have already been checked. */
+ for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i];
+ cur_sym_hashes++)
+ {
+ /* If the current symbol is identical to 'sym_hash', that means
+ the symbol was already adjusted (or at least checked). */
+ if (*cur_sym_hashes == sym_hash)
+ break;
+ }
+ /* Don't adjust the symbol again. */
+ if (cur_sym_hashes < &sym_hashes[i])
+ continue;
+ }
+
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec)
+ {
+ /* As above, adjust the value if needed. */
+ if (sym_hash->root.u.def.value > addr
+ && sym_hash->root.u.def.value <= toaddr)
+ sym_hash->root.u.def.value -= count;
+
+ /* As above, adjust the size if needed. */
+ else if (sym_hash->root.u.def.value <= addr
+ && sym_hash->root.u.def.value + sym_hash->size > addr
+ && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
+ sym_hash->size -= count;
+ }
+ }
+
+ return true;
+}
+
+/* Relax pcalau12i,addi.d => pcaddi. */
+static bool
+loongarch_relax_pcala_addi(bfd *abfd, asection *sec,
+ Elf_Internal_Rela *rel_hi, bfd_vma symval)
+{
+ 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;
+ 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_PCALA_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;
+
+ pca = pcaddi | rd;
+ bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
+
+ /* Adjust relocations. */
+ rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
+ R_LARCH_PCREL20_S2);
+ rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
+ R_LARCH_DELETE);
+
+ return true;
+}
+
+/* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
+static bool
+loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
+ Elf_Internal_Rela *rel_hi)
+{
+ 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 ld = bfd_get (32, abfd, contents + rel_lo->r_offset);
+ uint32_t rd = pca & 0x1f;
+ const uint32_t ld_d = 0x28c00000;
+ uint32_t addi_d = 0x02c00000;
+
+ if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_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)
+ || ((ld & 0x1f) != rd)
+ || (((ld >> 5) & 0x1f) != rd)
+ || ((ld & ld_d) != ld_d))
+ return false;
+
+ addi_d = addi_d | (rd << 5) | rd;
+ bfd_put (32, abfd, addi_d, contents + rel_lo->r_offset);
+
+ rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
+ R_LARCH_PCALA_HI20);
+ rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_lo->r_info),
+ R_LARCH_PCALA_LO12);
+ return true;
+}
+
+/* Called by after_allocation to set the information of data segment
+ before relaxing. */
+
+void
+bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info *info,
+ int *data_segment_phase)
+{
+ struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
+ htab->data_segment_phase = data_segment_phase;
+}
+
+/* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
+ Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
+static bool
+loongarch_relax_align (bfd *abfd, asection *sec,
+ asection *sym_sec,
+ struct bfd_link_info *link_info,
+ Elf_Internal_Rela *rel,
+ bfd_vma symval)
+{
+ bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+ bfd_vma alignment = 1, pos;
+ while (alignment <= rel->r_addend)
+ alignment *= 2;
+
+ symval -= rel->r_addend;
+ bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
+ bfd_vma nop_bytes = aligned_addr - symval;
+
+ /* Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
+ sec->sec_flg0 = true;
+
+ /* Make sure there are enough NOPs to actually achieve the alignment. */
+ if (rel->r_addend < nop_bytes)
+ {
+ _bfd_error_handler
+ (_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
+ "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
+ abfd, sym_sec, (uint64_t) rel->r_offset,
+ (int64_t) nop_bytes, (int64_t) alignment, (int64_t) rel->r_addend);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* Delete the reloc. */
+ rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
+
+ /* If the number of NOPs is already correct, there's nothing to do. */
+ if (nop_bytes == rel->r_addend)
+ return true;
+
+ /* Write as many LOONGARCH NOPs as we need. */
+ for (pos = 0; pos < (nop_bytes & -4); pos += 4)
+ bfd_putl32 (LARCH_NOP, contents + rel->r_offset + pos);
+
+ /* Delete the excess NOPs. */
+ return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset + nop_bytes,
+ rel->r_addend - nop_bytes, link_info);
+}
+
+static bool
+loongarch_elf_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *info,
+ bool *again)
+{
+ struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
+ struct bfd_elf_section_data *data = elf_section_data (sec);
+ Elf_Internal_Rela *relocs;
+ *again = false;
+
+ if (bfd_link_relocatable (info)
+ || sec->sec_flg0
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || elf_seg_map (info->output_bfd) == NULL
+ || (info->disable_target_specific_optimizations
+ && info->relax_pass == 0)
+ /* The exp_seg_relro_adjust is enum phase_enum (0x4),
+ and defined in ld/ldexp.h. */
+ || *(htab->data_segment_phase) == 4)
+ return true;
+
+ if (data->relocs)
+ relocs = data->relocs;
+ else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ info->keep_memory)))
+ return true;
+
+ if (!data->this_hdr.contents
+ && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
+ return true;
+
+ if (symtab_hdr->sh_info != 0
+ && !symtab_hdr->contents
+ && !(symtab_hdr->contents =
+ (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info,
+ 0, NULL, NULL, NULL)))
+ return true;
+
+ data->relocs = relocs;
+
+ for (unsigned int i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *rel = relocs + i;
+ asection *sym_sec;
+ bfd_vma symval;
+ unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
+ bool local_got = false;
+ char symtype;
+ struct elf_link_hash_entry *h = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
+ + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ continue;
+
+ if (sym->st_shndx == SHN_UNDEF)
+ {
+ sym_sec = sec;
+ symval = rel->r_offset;
+ }
+ else
+ {
+ sym_sec = elf_elfsections (abfd)[sym->st_shndx]->bfd_section;
+ symval = sym->st_value;
+ }
+ symtype = ELF_ST_TYPE (sym->st_info);
+ }
+ else
+ {
+ r_symndx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[r_symndx];
+
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* Disable the relaxation for ifunc. */
+ if (h != NULL && h->type == STT_GNU_IFUNC)
+ continue;
+
+ 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)
+ {
+ symval = h->root.u.def.value;
+ sym_sec = h->root.u.def.section;
+ }
+ else
+ continue;
+
+ if (h && bfd_link_executable (info)
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ local_got = true;
+ symtype = h->type;
+ }
+
+ if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE
+ && (sym_sec->flags & SEC_MERGE))
+ {
+ if (symtype == STT_SECTION)
+ symval += rel->r_addend;
+
+ symval = _bfd_merged_section_offset (abfd, &sym_sec,
+ elf_section_data (sym_sec)->sec_info,
+ symval);
+
+ if (symtype != STT_SECTION)
+ symval += rel->r_addend;
+ }
+ else
+ symval += rel->r_addend;
+
+ symval += sec_addr (sym_sec);
+
+ switch (ELFNN_R_TYPE (rel->r_info))
+ {
+ case R_LARCH_ALIGN:
+ if (2 == info->relax_pass)
+ loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
+ break;
+ case R_LARCH_DELETE:
+ if (info->relax_pass == 1)
+ {
+ loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
+ rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
+ }
+ 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);
+ }
+ break;
+ case R_LARCH_GOT_PC_HI20:
+ if (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);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return true;
+}
+
/* Finish up dynamic symbol handling. We set the contents of various
dynamic sections here. */
@@ -4151,5 +4624,6 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
#define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
+#define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
#include "elfNN-target.h"
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 0b00df556b7..72903863019 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -34,7 +34,7 @@ typedef struct loongarch_reloc_howto_type_struct
/* The first must be reloc_howto_type! */
reloc_howto_type howto;
bfd_reloc_code_real_type bfd_type;
- bool (*adjust_reloc_bits)(reloc_howto_type *, bfd_vma *);
+ bool (*adjust_reloc_bits)(bfd *, reloc_howto_type *, bfd_vma *);
const char *larch_reloc_type_name;
} loongarch_reloc_howto_type;
@@ -52,13 +52,23 @@ typedef struct loongarch_reloc_howto_type_struct
{ EMPTY_HOWTO (C), BFD_RELOC_NONE, NULL, NULL }
static bool
-reloc_bits (reloc_howto_type *howto, bfd_vma *val);
+reloc_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *val);
static bool
-reloc_bits_b16 (reloc_howto_type *howto, bfd_vma *fix_val);
+reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val);
static bool
-reloc_bits_b21 (reloc_howto_type *howto, bfd_vma *fix_val);
+reloc_bits_b16 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val);
static bool
-reloc_bits_b26 (reloc_howto_type *howto, bfd_vma *val);
+reloc_bits_b21 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val);
+static bool
+reloc_bits_b26 (bfd *abfd, reloc_howto_type *howto, bfd_vma *val);
+
+static bfd_reloc_status_type
+loongarch_elf_add_sub_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+
+static bfd_reloc_status_type
+loongarch_elf_add_sub_reloc_uleb128 (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
/* This does not include any relocation information, but should be
good enough for GDB or objdump to read the file. */
@@ -521,175 +531,185 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
reloc_bits, /* adjust_reloc_bits */
NULL), /* larch_reloc_type_name */
+ /* 8-bit in-place addition, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */
0, /* rightshift. */
- 4, /* size. */
+ 1, /* size. */
8, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_ADD8", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_ADD8, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0xff, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_ADD8, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+ /* 16-bit in-place addition, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */
0, /* rightshift. */
- 4, /* size. */
+ 2, /* size. */
16, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_ADD16", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_ADD16, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0xffff, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_ADD16, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+ /* 24-bit in-place addition, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */
0, /* rightshift. */
- 4, /* size. */
+ 3, /* size. */
24, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_ADD24", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_ADD24, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0xffffff, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_ADD24, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+ /* 32-bit in-place addition, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */
0, /* rightshift. */
4, /* size. */
32, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_ADD32", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_ADD32, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0xffffffff, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_ADD32, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+ /* 64-bit in-place addition, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */
0, /* rightshift. */
8, /* size. */
64, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_ADD64", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_ADD64, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ ALL_ONES, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_ADD64, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+ /* 8-bit in-place subtraction, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */
0, /* rightshift. */
- 4, /* size. */
+ 1, /* size. */
8, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_SUB8", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_SUB8, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0xff, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_SUB8, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+ /* 16-bit in-place subtraction, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */
0, /* rightshift. */
- 4, /* size. */
+ 2, /* size. */
16, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_SUB16", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_SUB16, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0xffff, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_SUB16, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+ /* 24-bit in-place subtraction, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */
0, /* rightshift. */
- 4, /* size. */
+ 3, /* size. */
24, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_SUB24", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_SUB24, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0xffffff, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_SUB24, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+ /* 32-bit in-place subtraction, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */
0, /* rightshift. */
4, /* size. */
32, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_SUB32", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_SUB32, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0xffffffff, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_SUB32, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+ /* 64-bit in-place subtraction, for local label subtraction. */
LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */
0, /* rightshift. */
8, /* size. */
64, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
"R_LARCH_SUB64", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- ALL_ONES, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_SUB64, /* bfd_reloc_code_real_type */
- NULL, /* adjust_reloc_bits */
- NULL), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ ALL_ONES, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_SUB64, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT, /* type (57). */
0, /* rightshift. */
@@ -742,12 +762,12 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_B16", /* name. */
false, /* partial_inplace. */
- 0x3fffc00, /* src_mask */
- 0x3fffc00, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_B16, /* bfd_reloc_code_real_type */
- reloc_bits_b16, /* adjust_reloc_bits */
- "b16"), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0x3fffc00, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_B16, /* bfd_reloc_code_real_type. */
+ reloc_bits_b16, /* adjust_reloc_bits. */
+ "b16"), /* larch_reloc_type_name. */
LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */
2, /* rightshift. */
@@ -759,12 +779,12 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_B21", /* name. */
false, /* partial_inplace. */
- 0xfc0003e0, /* src_mask */
- 0xfc0003e0, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_B21, /* bfd_reloc_code_real_type */
- reloc_bits_b21, /* adjust_reloc_bits */
- "b21"), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0x3fffc1f, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_B21, /* bfd_reloc_code_real_type. */
+ reloc_bits_b21, /* adjust_reloc_bits. */
+ "b21"), /* larch_reloc_type_name. */
LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */
2, /* rightshift. */
@@ -776,12 +796,12 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_B26", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- 0x03ffffff, /* dst_mask */
- false, /* pcrel_offset */
- BFD_RELOC_LARCH_B26, /* bfd_reloc_code_real_type */
- reloc_bits_b26, /* adjust_reloc_bits */
- "b26"), /* larch_reloc_type_name */
+ 0, /* src_mask. */
+ 0x03ffffff, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_B26, /* bfd_reloc_code_real_type. */
+ reloc_bits_b26, /* adjust_reloc_bits. */
+ "b26"), /* larch_reloc_type_name. */
LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */
12, /* rightshift. */
@@ -1078,7 +1098,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
12, /* bitsize. */
false, /* pc_relative. */
10, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_TLS_LE_LO12", /* name. */
false, /* partial_inplace. */
@@ -1146,7 +1166,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
12, /* bitsize. */
false, /* pc_relative. */
10, /* bitpos. */
- complain_overflow_unsigned, /* complain_on_overflow. */
+ complain_overflow_signed, /* complain_on_overflow. */
bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_TLS_IE_PC_LO12", /* name. */
false, /* partial_inplace. */
@@ -1191,7 +1211,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
reloc_bits, /* adjust_reloc_bits */
"ie64_pc_hi12"), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_TLS_IE_HI20, /* type (91). */
+ LOONGARCH_HOWTO (R_LARCH_TLS_IE_HI20, /* type (91). */
12, /* rightshift. */
4, /* size. */
20, /* bitsize. */
@@ -1327,13 +1347,14 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
reloc_bits, /* adjust_reloc_bits */
"gd_hi20"), /* larch_reloc_type_name */
+ /* 32-bit PC relative. */
LOONGARCH_HOWTO (R_LARCH_32_PCREL, /* type (99). */
0, /* rightshift. */
4, /* size. */
32, /* bitsize. */
true, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_dont, /* complain_on_overflow. */
+ complain_overflow_signed, /* complain_on_overflow. */
bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_32_PCREL", /* name. */
false, /* partial_inplace. */
@@ -1344,6 +1365,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
NULL, /* adjust_reloc_bits */
NULL), /* larch_reloc_type_name */
+ /* The paired relocation may be relaxed. */
LOONGARCH_HOWTO (R_LARCH_RELAX, /* type (100). */
0, /* rightshift */
1, /* size */
@@ -1361,6 +1383,158 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
NULL, /* adjust_reloc_bits */
NULL), /* larch_reloc_type_name */
+ /* Delete relaxed instruction. */
+ LOONGARCH_HOWTO (R_LARCH_DELETE, /* type (101). */
+ 0, /* rightshift. */
+ 0, /* size. */
+ 0, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_DELETE", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_DELETE, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
+ /* Indicates an alignment statement. The addend field encodes how many
+ bytes of NOPs follow the statement. The desired alignment is the
+ addend rounded up to the next power of two. */
+ LOONGARCH_HOWTO (R_LARCH_ALIGN, /* type (102). */
+ 0, /* rightshift. */
+ 0, /* size. */
+ 0, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ALIGN", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_ALIGN, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
+ /* pcala_hi20 + pcala_lo12 relaxed to pcrel20_s2. */
+ LOONGARCH_HOWTO (R_LARCH_PCREL20_S2, /* type (103). */
+ 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_PCREL20_S2", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x1ffffe0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_PCREL20_S2, /* bfd_reloc_code_real_type. */
+ reloc_bits_pcrel20_s2, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
+ /* Canonical Frame Address. */
+ LOONGARCH_HOWTO (R_LARCH_CFA, /* type (104). */
+ 0, /* rightshift. */
+ 0, /* size. */
+ 0, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_CFA", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_CFA, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
+ /* 6-bit in-place addition, for local label subtraction
+ to calculate DW_CFA_advance_loc. */
+ LOONGARCH_HOWTO (R_LARCH_ADD6, /* type (105). */
+ 0, /* rightshift. */
+ 1, /* size. */
+ 8, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
+ "R_LARCH_ADD6", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x3f, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_ADD6, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
+ /* 6-bit in-place subtraction, for local label subtraction
+ to calculate DW_CFA_advance_loc. */
+ LOONGARCH_HOWTO (R_LARCH_SUB6, /* type (106). */
+ 0, /* rightshift. */
+ 1, /* size. */
+ 8, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc, /* special_function. */
+ "R_LARCH_SUB6", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x3f, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_SUB6, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
+ /* The length of unsigned-leb128 is variable, just assume the
+ size is one byte here.
+ uleb128 in-place addition, for local label subtraction. */
+ LOONGARCH_HOWTO (R_LARCH_ADD_ULEB128, /* type (107). */
+ 0, /* rightshift. */
+ 1, /* size. */
+ 0, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc_uleb128, /* special_function. */
+ "R_LARCH_ADD_ULEB128", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_ADD_ULEB128, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
+ /* The length of unsigned-leb128 is variable, just assume the
+ size is one byte here.
+ uleb128 in-place subtraction, for local label subtraction. */
+ LOONGARCH_HOWTO (R_LARCH_SUB_ULEB128, /* type (108). */
+ 0, /* rightshift. */
+ 1, /* size. */
+ 0, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ loongarch_elf_add_sub_reloc_uleb128, /* special_function. */
+ "R_LARCH_SUB_ULEB128", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_SUB_ULEB128, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
};
reloc_howto_type *
@@ -1464,13 +1638,54 @@ loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
BFD_RELOC_LARCH_SOP_POP_32_S_10_16
BFD_RELOC_LARCH_SOP_POP_32_S_5_20
BFD_RELOC_LARCH_SOP_POP_32_U. */
+
+static bool
+reloc_bits (bfd *abfd ATTRIBUTE_UNUSED,
+ reloc_howto_type *howto,
+ bfd_vma *fix_val)
+{
+ bfd_signed_vma val = (bfd_signed_vma)(*fix_val);
+ bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
+
+ val = val >> howto->rightshift;
+
+ /* Perform insn bits field. */
+ val = val & mask;
+ val <<= howto->bitpos;
+
+ *fix_val = (bfd_vma)val;
+
+ return true;
+}
+
static bool
-reloc_bits (reloc_howto_type *howto, bfd_vma *fix_val)
+reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
{
- bfd_signed_vma val = ((bfd_signed_vma)(*fix_val)) >> howto->rightshift;
+ bfd_signed_vma val = (bfd_signed_vma)(*fix_val);
+ bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
+
+ /* Check rightshift. */
+ if (howto->rightshift
+ && (val & ((((bfd_signed_vma) 1) << howto->rightshift) - 1)))
+ {
+ (*_bfd_error_handler) (_("%pB: relocation %s right shift %d error 0x%lx"),
+ abfd, howto->name, howto->rightshift, val);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ val = val >> howto->rightshift;
+
+ if ((val & ~mask) && ((val & ~mask) != ~mask))
+ {
+ (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"),
+ abfd, howto->name, val);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
/* Perform insn bits field. */
- val = val & (((bfd_vma)0x1 << howto->bitsize) - 1);
+ val = val & mask;
val <<= howto->bitpos;
*fix_val = (bfd_vma)val;
@@ -1478,42 +1693,35 @@ reloc_bits (reloc_howto_type *howto, bfd_vma *fix_val)
return true;
}
+
/* Adjust val to perform insn
R_LARCH_SOP_POP_32_S_10_16_S2
R_LARCH_B16. */
static bool
-reloc_bits_b16 (reloc_howto_type *howto, bfd_vma *fix_val)
+reloc_bits_b16 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
{
+ bfd_signed_vma val = *fix_val;
+ bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
+
if (howto->complain_on_overflow != complain_overflow_signed)
return false;
- bfd_signed_vma val = *fix_val;
-
/* Judge whether 4 bytes align. */
if (val & ((0x1UL << howto->rightshift) - 1))
return false;
- int bitsize = howto->bitsize + howto->rightshift;
- bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
+ val = val >> howto->rightshift;
- /* If val < 0, sign bit is 1. */
- if (sig_bit)
- {
- /* Signed bits is 1. */
- if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
- != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1))
- return false;
- }
- else
+ if ((val & ~mask) && ((val & ~mask) != ~mask))
{
- /* Signed bits is 0. */
- if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val)
- return false;
+ (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"),
+ abfd, howto->name, val);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
}
/* Perform insn bits field. */
- val >>= howto->rightshift;
- val = val & (((bfd_vma)0x1 << howto->bitsize) - 1);
+ val = val & mask;
val <<= howto->bitpos;
*fix_val = val;
@@ -1525,36 +1733,30 @@ reloc_bits_b16 (reloc_howto_type *howto, bfd_vma *fix_val)
R_LARCH_SOP_POP_32_S_0_5_10_16_S2
R_LARCH_B21. */
static bool
-reloc_bits_b21 (reloc_howto_type *howto,
- bfd_vma *fix_val)
+reloc_bits_b21 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
{
+ bfd_signed_vma val = *fix_val;
+ bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
+
if (howto->complain_on_overflow != complain_overflow_signed)
return false;
- bfd_signed_vma val = *fix_val;
-
+ /* Judge whether 4 bytes align. */
if (val & ((0x1UL << howto->rightshift) - 1))
return false;
- int bitsize = howto->bitsize + howto->rightshift;
- bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
+ val = val >> howto->rightshift;
- /* If val < 0. */
- if (sig_bit)
+ if ((val & ~mask) && ((val & ~mask) != ~mask))
{
- if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
- != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1))
- return false;
- }
- else
- {
- if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val)
- return false;
+ (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"),
+ abfd, howto->name, val);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
}
/* Perform insn bits field. */
- val >>= howto->rightshift;
- val = val & (((bfd_vma)0x1 << howto->bitsize) - 1);
+ val = val & mask;
/* Perform insn bits field. 15:0<<10, 20:16>>16. */
val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f);
@@ -1568,37 +1770,31 @@ reloc_bits_b21 (reloc_howto_type *howto,
R_LARCH_SOP_POP_32_S_0_10_10_16_S2
R_LARCH_B26. */
static bool
-reloc_bits_b26 (reloc_howto_type *howto,
- bfd_vma *fix_val)
+reloc_bits_b26 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
{
- /* Return false if overflow. */
+ bfd_signed_vma val = *fix_val;
+ bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
+
if (howto->complain_on_overflow != complain_overflow_signed)
return false;
- bfd_signed_vma val = *fix_val;
-
+ /* Judge whether 4 bytes align. */
if (val & ((0x1UL << howto->rightshift) - 1))
return false;
- int bitsize = howto->bitsize + howto->rightshift;
- bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
+ val = val >> howto->rightshift;
- /* If val < 0. */
- if (sig_bit)
+ if ((val & ~mask) && ((val & ~mask) != ~mask))
{
- if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
- != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1))
- return false;
- }
- else
- {
- if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val)
- return false;
+ (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"),
+ abfd, howto->name, val);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
}
+
/* Perform insn bits field. */
- val >>= howto->rightshift;
- val = val & (((bfd_vma)0x1 << howto->bitsize) - 1);
+ val = val & mask;
/* Perform insn bits field. 25:16>>16, 15:0<<10. */
val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff);
@@ -1609,10 +1805,142 @@ reloc_bits_b26 (reloc_howto_type *howto,
}
bool
-loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto,
+loongarch_adjust_reloc_bitsfield (bfd *abfd, reloc_howto_type *howto,
bfd_vma *fix_val)
{
BFD_ASSERT (((loongarch_reloc_howto_type *)howto)->adjust_reloc_bits);
return ((loongarch_reloc_howto_type *)
- howto)->adjust_reloc_bits(howto, fix_val);
+ howto)->adjust_reloc_bits (abfd, howto, fix_val);
+}
+
+static bfd_reloc_status_type
+loongarch_elf_add_sub_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ reloc_howto_type *howto = reloc_entry->howto;
+ bfd_vma relocation;
+
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ return bfd_reloc_continue;
+
+ relocation = symbol->value + symbol->section->output_section->vma
+ + symbol->section->output_offset + reloc_entry->addend;
+
+ bfd_size_type octets = reloc_entry->address
+ * bfd_octets_per_byte (abfd, input_section);
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+ input_section, octets))
+ return bfd_reloc_outofrange;
+
+ bfd_vma old_value = bfd_get (howto->bitsize, abfd,
+ data + reloc_entry->address);
+
+ switch (howto->type)
+ {
+ case R_LARCH_ADD6:
+ case R_LARCH_ADD8:
+ case R_LARCH_ADD16:
+ case R_LARCH_ADD32:
+ case R_LARCH_ADD64:
+ relocation = old_value + relocation;
+ break;
+
+ case R_LARCH_SUB6:
+ case R_LARCH_SUB8:
+ case R_LARCH_SUB16:
+ case R_LARCH_SUB32:
+ case R_LARCH_SUB64:
+ relocation = old_value - relocation;
+ break;
+ }
+
+ bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+loongarch_elf_add_sub_reloc_uleb128 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ reloc_howto_type *howto = reloc_entry->howto;
+ bfd_vma relocation;
+
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ return bfd_reloc_continue;
+
+ relocation = symbol->value + symbol->section->output_section->vma
+ + symbol->section->output_offset + reloc_entry->addend;
+
+ bfd_size_type octets = reloc_entry->address
+ * bfd_octets_per_byte (abfd, input_section);
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+ input_section, octets))
+ return bfd_reloc_outofrange;
+
+ unsigned int len = 0;
+ bfd_byte *p = data + reloc_entry->address;
+ bfd_vma old_value = _bfd_read_unsigned_leb128 (abfd, p, &len);
+
+ switch (howto->type)
+ {
+ case R_LARCH_ADD_ULEB128:
+ relocation = old_value + relocation;
+ break;
+
+ case R_LARCH_SUB_ULEB128:
+ relocation = old_value - relocation;
+ break;
+ }
+
+ bfd_vma mask = (1 << (7 * len)) - 1;
+ relocation = relocation & mask;
+ loongarch_write_unsigned_leb128 (p, len, relocation);
+ return bfd_reloc_ok;
+}
+
+/* Write VALUE in uleb128 format to P.
+ LEN is the uleb128 value length.
+ Return a pointer to the byte following the last byte that was written. */
+bfd_byte *
+loongarch_write_unsigned_leb128 (bfd_byte *p, unsigned int len, bfd_vma value)
+{
+ bfd_byte c;
+ do
+ {
+ c = value & 0x7f;
+ if (len > 1)
+ c |= 0x80;
+ *(p++) = c;
+ value >>= 7;
+ len--;
+ }
+ while (len);
+ return p;
}
diff --git a/bfd/elfxx-loongarch.h b/bfd/elfxx-loongarch.h
index 7b8a72130f1..9b5e560c370 100644
--- a/bfd/elfxx-loongarch.h
+++ b/bfd/elfxx-loongarch.h
@@ -34,7 +34,15 @@ extern bfd_reloc_code_real_type
loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
const char *l_r_name);
-bool loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto, bfd_vma *fix_val);
+bool
+loongarch_adjust_reloc_bitsfield (bfd *, reloc_howto_type *, bfd_vma *);
+void
+bfd_elf32_loongarch_set_data_segment_info (struct bfd_link_info *, int *);
+void
+bfd_elf64_loongarch_set_data_segment_info (struct bfd_link_info *, int *);
+
+bfd_byte *
+loongarch_write_unsigned_leb128 (bfd_byte *p, unsigned int len, bfd_vma value);
/* TRUE if this is a PLT reference to a local IFUNC. */
#define PLT_LOCAL_IFUNC_P(INFO, H) \
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 2dec8109bb8..c29e5b54d49 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3509,6 +3509,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_LARCH_TLS_GD_HI20",
"BFD_RELOC_LARCH_32_PCREL",
"BFD_RELOC_LARCH_RELAX",
+ "BFD_RELOC_LARCH_DELETE",
+ "BFD_RELOC_LARCH_ALIGN",
+ "BFD_RELOC_LARCH_PCREL20_S2",
+ "BFD_RELOC_LARCH_CFA",
+ "BFD_RELOC_LARCH_ADD6",
+ "BFD_RELOC_LARCH_SUB6",
+ "BFD_RELOC_LARCH_ADD_ULEB128",
+ "BFD_RELOC_LARCH_SUB_ULEB128",
"@@overflow: BFD_RELOC_UNUSED@@",
};
#endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 6446acc7a30..7fc82129007 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8310,6 +8310,28 @@ ENUMX
ENUMX
BFD_RELOC_LARCH_RELAX
+ENUMX
+ BFD_RELOC_LARCH_DELETE
+
+ENUMX
+ BFD_RELOC_LARCH_ALIGN
+
+ENUMX
+ BFD_RELOC_LARCH_PCREL20_S2
+
+ENUMX
+ BFD_RELOC_LARCH_CFA
+
+ENUMX
+ BFD_RELOC_LARCH_ADD6
+ENUMX
+ BFD_RELOC_LARCH_SUB6
+
+ENUMX
+ BFD_RELOC_LARCH_ADD_ULEB128
+ENUMX
+ BFD_RELOC_LARCH_SUB_ULEB128
+
ENUMDOC
LARCH relocations.
--
2.36.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 3/6] LoongArch: opcodes: Add support for linker relaxation.
2022-12-13 6:58 [PATCH v2 0/6] LoongArch linker relaxation support mengqinggang
2022-12-13 6:58 ` [PATCH v2 1/6] LoongArch: include: Add support for linker relaxation mengqinggang
2022-12-13 6:58 ` [PATCH v2 2/6] LoongArch: bfd: " mengqinggang
@ 2022-12-13 6:58 ` mengqinggang
2022-12-14 19:21 ` Hans-Peter Nilsson
2022-12-13 6:58 ` [PATCH v2 4/6] LoongArch: binutils: " mengqinggang
` (2 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: mengqinggang @ 2022-12-13 6:58 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, liuzhensong, chenglulu, xry111, i.swmail, maskray,
schwab, mengqinggang
Set gas default to enable relax.
opcodes/ChangeLog:
* loongarch-opc.c (struct loongarch_ASEs_option): New member relax and
the default value is 1.
---
opcodes/loongarch-opc.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 1b510048c29..aa43fbc3fb7 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -22,7 +22,10 @@
#include "opcode/loongarch.h"
#include "libiberty.h"
-struct loongarch_ASEs_option LARCH_opts;
+struct loongarch_ASEs_option LARCH_opts =
+{
+ .relax = 1
+};
size_t
loongarch_insn_length (insn_t insn ATTRIBUTE_UNUSED)
--
2.36.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 4/6] LoongArch: binutils: Add support for linker relaxation.
2022-12-13 6:58 [PATCH v2 0/6] LoongArch linker relaxation support mengqinggang
` (2 preceding siblings ...)
2022-12-13 6:58 ` [PATCH v2 3/6] LoongArch: opcodes: " mengqinggang
@ 2022-12-13 6:58 ` mengqinggang
2022-12-13 6:58 ` [PATCH v2 5/6] LoongArch: gas: " mengqinggang
2022-12-13 6:58 ` [PATCH v2 6/6] LoongArch: ld: " mengqinggang
5 siblings, 0 replies; 8+ messages in thread
From: mengqinggang @ 2022-12-13 6:58 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, liuzhensong, chenglulu, xry111, i.swmail, maskray,
schwab, mengqinggang
Add support for relocs related to relax to readelf.
binutils/ChangeLog:
* readelf.c (target_specific_reloc_handling): Handle ULEB128 reloc.
(is_32bit_inplace_add_reloc): Handle new reloc.
(is_32bit_inplace_sub_reloc): Likewise.
(is_64bit_inplace_add_reloc): Likewise.
(is_64bit_inplace_sub_reloc): Likewise.
(is_16bit_inplace_add_reloc): Likewise.
(is_16bit_inplace_sub_reloc): Likewise.
(is_8bit_inplace_add_reloc): Likewise.
(is_8bit_inplace_sub_reloc): Likewise.
(is_6bit_inplace_sub_reloc): Likewise.
(is_6bit_inplace_add_reloc): New function.
(apply_relocations): Handle new reloc.
* testsuite/binutils-all/readelf.exp: Add -mno-relax option
for LoongArch.
---
binutils/readelf.c | 84 ++++++++++++++++++++-
binutils/testsuite/binutils-all/readelf.exp | 13 +++-
2 files changed, 91 insertions(+), 6 deletions(-)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 6b2cbbcbb1b..dbca5552bdc 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -13961,6 +13961,51 @@ target_specific_reloc_handling (Filedata * filedata,
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ {
+ switch (reloc_type)
+ {
+ /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
+ at assembly time. */
+ case 107: /* R_LARCH_ADD_ULEB128. */
+ case 108: /* R_LARCH_SUB_ULEB128. */
+ {
+ uint64_t value;
+ unsigned int reloc_size = 0;
+ int leb_ret = 0;
+
+ value = read_leb128 (start + reloc->r_offset, end, false,
+ &reloc_size, &leb_ret);
+ if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
+ error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
+ "ULEB128 value\n"),
+ (long) reloc->r_offset);
+
+ if (107 == reloc_type)
+ value += (reloc->r_addend + symtab[sym_index].st_value);
+ else if (108 == reloc_type)
+ value -= (reloc->r_addend + symtab[sym_index].st_value);
+
+ /* Write uleb128 value to p. */
+ bfd_byte c;
+ bfd_byte *p = start + reloc->r_offset;
+ do
+ {
+ c = value & 0x7f;
+ if (reloc_size > 1)
+ c |= 0x80;
+ *(p++) = c;
+ value >>= 7;
+ reloc_size--;
+ }
+ while (reloc_size);
+
+ return true;
+ }
+ }
+ break;
+ }
+
case EM_MSP430:
case EM_MSP430_OLD:
{
@@ -14680,6 +14725,8 @@ is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
/* Please keep this table alpha-sorted for ease of visual lookup. */
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ return reloc_type == 50; /* R_LARCH_ADD32. */
case EM_RISCV:
return reloc_type == 35; /* R_RISCV_ADD32. */
default:
@@ -14696,6 +14743,8 @@ is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
/* Please keep this table alpha-sorted for ease of visual lookup. */
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ return reloc_type == 55; /* R_LARCH_SUB32. */
case EM_RISCV:
return reloc_type == 39; /* R_RISCV_SUB32. */
default:
@@ -14712,6 +14761,8 @@ is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
/* Please keep this table alpha-sorted for ease of visual lookup. */
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ return reloc_type == 51; /* R_LARCH_ADD64. */
case EM_RISCV:
return reloc_type == 36; /* R_RISCV_ADD64. */
default:
@@ -14728,6 +14779,8 @@ is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
/* Please keep this table alpha-sorted for ease of visual lookup. */
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ return reloc_type == 56; /* R_LARCH_SUB64. */
case EM_RISCV:
return reloc_type == 40; /* R_RISCV_SUB64. */
default:
@@ -14744,6 +14797,8 @@ is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
/* Please keep this table alpha-sorted for ease of visual lookup. */
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ return reloc_type == 48; /* R_LARCH_ADD16. */
case EM_RISCV:
return reloc_type == 34; /* R_RISCV_ADD16. */
default:
@@ -14760,6 +14815,8 @@ is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
/* Please keep this table alpha-sorted for ease of visual lookup. */
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ return reloc_type == 53; /* R_LARCH_SUB16. */
case EM_RISCV:
return reloc_type == 38; /* R_RISCV_SUB16. */
default:
@@ -14776,6 +14833,8 @@ is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
/* Please keep this table alpha-sorted for ease of visual lookup. */
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ return reloc_type == 47; /* R_LARCH_ADD8. */
case EM_RISCV:
return reloc_type == 33; /* R_RISCV_ADD8. */
default:
@@ -14792,6 +14851,8 @@ is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
/* Please keep this table alpha-sorted for ease of visual lookup. */
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ return reloc_type == 52; /* R_LARCH_SUB8. */
case EM_RISCV:
return reloc_type == 37; /* R_RISCV_SUB8. */
default:
@@ -14799,6 +14860,21 @@ is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
}
}
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+ a 6-bit inplace add RELA relocation used in DWARF debug sections. */
+
+static bool
+is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
+{
+ switch (filedata->file_header.e_machine)
+ {
+ case EM_LOONGARCH:
+ return reloc_type == 105; /* R_LARCH_ADD6. */
+ default:
+ return false;
+ }
+}
+
/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
@@ -14807,6 +14883,8 @@ is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
{
switch (filedata->file_header.e_machine)
{
+ case EM_LOONGARCH:
+ return reloc_type == 106; /* R_LARCH_SUB6. */
case EM_RISCV:
return reloc_type == 52; /* R_RISCV_SUB6. */
default:
@@ -15054,7 +15132,8 @@ apply_relocations (Filedata *filedata,
reloc_inplace = true;
}
else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
- reloc_type)))
+ reloc_type))
+ || is_6bit_inplace_add_reloc (filedata, reloc_type))
{
reloc_size = 1;
reloc_inplace = true;
@@ -15144,7 +15223,8 @@ apply_relocations (Filedata *filedata,
reloc_size);
}
else if (is_6bit_abs_reloc (filedata, reloc_type)
- || is_6bit_inplace_sub_reloc (filedata, reloc_type))
+ || is_6bit_inplace_sub_reloc (filedata, reloc_type)
+ || is_6bit_inplace_add_reloc (filedata, reloc_type))
{
if (reloc_subtract)
addend -= sym->st_value;
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
index d7f1524fc5c..07056aec6bb 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -489,18 +489,23 @@ if {![binutils_assemble $srcdir/$subdir/z.s tmpdir/z.o]} then {
readelf_test {--decompress --hex-dump .debug_loc} $tempfile readelf.z
}
-set hpux ""
+set flags ""
# Skip the next test for the RISCV architectures because they
# do not support .ULEB128 pseudo-ops with non-constant values.
if ![istarget "riscv*-*-*"] then {
if [istarget "hppa*64*-*-hpux*"] {
- set hpux "--defsym HPUX=1"
+ set flags "--defsym HPUX=1"
}
+ # LOONGARCH relax align add nops, so label subtractions will increase
+ if [istarget "loongarch*-*-*"] {
+ set flags "-mno-relax"
+ }
+
# Assemble the DWARF-5 test file.
- if {![binutils_assemble_flags $srcdir/$subdir/dw5.S tmpdir/dw5.o $hpux]} then {
+ if {![binutils_assemble_flags $srcdir/$subdir/dw5.S tmpdir/dw5.o $flags]} then {
unsupported "readelf -wiaoRlL dw5 (failed to assemble)"
} else {
@@ -612,7 +617,7 @@ if ![is_remote host] {
}
# Check dwarf-5 support for DW_OP_addrx.
-if {![binutils_assemble_flags $srcdir/$subdir/dw5-op.S tmpdir/dw5-op.o $hpux]} then {
+if {![binutils_assemble_flags $srcdir/$subdir/dw5-op.S tmpdir/dw5-op.o $flags]} then {
unsupported "readelf -wi dw5-op (failed to assemble)"
} else {
--
2.36.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 5/6] LoongArch: gas: Add support for linker relaxation.
2022-12-13 6:58 [PATCH v2 0/6] LoongArch linker relaxation support mengqinggang
` (3 preceding siblings ...)
2022-12-13 6:58 ` [PATCH v2 4/6] LoongArch: binutils: " mengqinggang
@ 2022-12-13 6:58 ` mengqinggang
2022-12-13 6:58 ` [PATCH v2 6/6] LoongArch: ld: " mengqinggang
5 siblings, 0 replies; 8+ messages in thread
From: mengqinggang @ 2022-12-13 6:58 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, liuzhensong, chenglulu, xry111, i.swmail, maskray,
schwab, mengqinggang
Add gas -mrelax and -mno-relax option.
Add R_LARCH_RELAX reloc for instrction if it can be relaxed.
ADD R_LARCH_ALIGN reloc for alignpeudo instruction because relax.
Add ADD/SUB reloc pair for debug and exception data to calculate symbol
substraction because relax.
gas/ChangeLog:
* config/tc-loongarch.c:
(struct loongarch_cl_insn): New macro_id member.
(enum options): New OPTION_RELAX and OPTION_NO_RELAX.
(struct option): New mrelax and mno-relax.
(md_parse_option): Likewise.
(get_internal_label):
(loongarch_args_parser_can_match_arg_helper): Generate relax reloc.
(move_insn): Set fx_frag and fx_where if exist.
(append_fixp_and_insn): Call frag_wane and frag_new for linker relax
relocs.
(loongarch_assemble_INSNs): New loongarch_cl_insn pointer parameter.
(md_assemble): Fix function call.
(fix_reloc_insn): Likewise.
(md_apply_fix): Generate ADD/SUB reloc pair for debug and exception
data.
(loongarch_fix_adjustable): Delete.
(md_convert_frag): Generate new fix.
(loongarch_pre_output_hook): New function.
(loongarch_make_nops): Likewise.
(loongarch_frag_align_code): Likewise.
(loongarch_insert_uleb128_fixes): Likewise.
(loongarch_md_finish): Likewise.
* config/tc-loongarch.h
(md_allow_local_subtract): New macro define.
(loongarch_frag_align_code): New declare.
(md_do_align): Likewise.
(loongarch_fix_adjustable): Delete.
(tc_fix_adjustable): New macro define.
(TC_FORCE_RELOCATION_SUB_SAME): Likewise.
(TC_LINKRELAX_FIXUP): Likewise.
(TC_FORCE_RELOCATION_LOCAL): Likewise.
(DWARF2_USE_FIXED_ADVANCE_PC): Likewise.
(MD_APPLY_SYM_VALUE): Likewise.
(tc_symbol_new_hook): New extern.
(NOP_OPCODE): Delete.
(loongarch_pre_output_hook): New macro define.
(md_pre_output_hook): Likewise.
(md_finish): Likewise.
(loongarch_md_finish): New extern.
* testsuite/gas/all/align.d: Mark as unsupported on LoongArch.
* testsuite/gas/all/gas.exp: Xfail loongarch*-*.
* testsuite/gas/all/relax.d: Likewise.
* testsuite/gas/elf/dwarf-5-irp.d: Likewise.
* testsuite/gas/elf/dwarf-5-loc0.d: Likewise.
* testsuite/gas/elf/dwarf2-11.d: Likewise.
* testsuite/gas/elf/dwarf2-15.d: Likewise.
* testsuite/gas/elf/dwarf2-16.d: Likewise.
* testsuite/gas/elf/dwarf2-17.d: Likewise.
* testsuite/gas/elf/dwarf2-18.d: Likewise.
* testsuite/gas/elf/dwarf2-19.d: Likewise.
* testsuite/gas/elf/dwarf2-5.d: Likewise.
* testsuite/gas/elf/ehopt0.d: Likewise.
* testsuite/gas/elf/elf.exp: Likewise.
* testsuite/gas/elf/section11.d: Likewise.
* testsuite/gas/lns/lns.exp: Likewise.
* testsuite/gas/loongarch/jmp_op.d: New generated.
* testsuite/gas/loongarch/li.d: Likewise.
* testsuite/gas/loongarch/macro_op.d: Likewise.
* testsuite/gas/loongarch/macro_op_large_abs.d: Likewise.
* testsuite/gas/loongarch/macro_op_large_pc.d: Likewise.
* testsuite/gas/loongarch/relax_align.d: New test.
* testsuite/gas/loongarch/relax_align.s: New test.
* testsuite/gas/loongarch/uleb128.d: New test.
* testsuite/gas/loongarch/uleb128.s: New test.
---
gas/config/tc-loongarch.c | 412 +++++++++++++++---
gas/config/tc-loongarch.h | 45 +-
gas/testsuite/gas/all/align.d | 5 +-
gas/testsuite/gas/all/gas.exp | 10 +-
gas/testsuite/gas/all/relax.d | 4 +
gas/testsuite/gas/elf/dwarf-5-irp.d | 3 +-
gas/testsuite/gas/elf/dwarf-5-loc0.d | 3 +-
gas/testsuite/gas/elf/dwarf2-11.d | 3 +-
gas/testsuite/gas/elf/dwarf2-15.d | 3 +-
gas/testsuite/gas/elf/dwarf2-16.d | 3 +-
gas/testsuite/gas/elf/dwarf2-17.d | 3 +-
gas/testsuite/gas/elf/dwarf2-18.d | 3 +-
gas/testsuite/gas/elf/dwarf2-19.d | 3 +-
gas/testsuite/gas/elf/dwarf2-5.d | 3 +-
gas/testsuite/gas/elf/ehopt0.d | 3 +
gas/testsuite/gas/elf/elf.exp | 3 +
gas/testsuite/gas/elf/section11.d | 4 +-
gas/testsuite/gas/lns/lns.exp | 1 +
gas/testsuite/gas/loongarch/jmp_op.d | 65 ++-
gas/testsuite/gas/loongarch/li.d | 9 +-
gas/testsuite/gas/loongarch/macro_op.d | 69 +--
.../gas/loongarch/macro_op_large_abs.d | 103 +++--
.../gas/loongarch/macro_op_large_pc.d | 103 +++--
gas/testsuite/gas/loongarch/relax_align.d | 25 ++
gas/testsuite/gas/loongarch/relax_align.s | 5 +
gas/testsuite/gas/loongarch/uleb128.d | 35 ++
gas/testsuite/gas/loongarch/uleb128.s | 20 +
27 files changed, 721 insertions(+), 227 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/relax_align.d
create mode 100644 gas/testsuite/gas/loongarch/relax_align.s
create mode 100644 gas/testsuite/gas/loongarch/uleb128.d
create mode 100644 gas/testsuite/gas/loongarch/uleb128.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 60149a6d8db..10b79fb7894 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -20,6 +20,7 @@
see <http://www.gnu.org/licenses/>. */
#include "as.h"
+#include "subsegs.h"
#include "dw2gencfi.h"
#include "loongarch-lex.h"
#include "elf/loongarch.h"
@@ -30,6 +31,7 @@
#include <string.h>
#include <stdio.h>
#include <assert.h>
+#include "libbfd.h"
/* All information about an instruction during assemble. */
struct loongarch_cl_insn
@@ -70,6 +72,7 @@ struct loongarch_cl_insn
long where;
/* The relocs associated with the instruction, if any. */
fixS *fixp[MAX_RELOC_NUMBER_A_INSN];
+ long macro_id;
};
#ifndef DEFAULT_ARCH
@@ -116,6 +119,8 @@ enum options
OPTION_LA_LOCAL_WITH_ABS,
OPTION_LA_GLOBAL_WITH_PCREL,
OPTION_LA_GLOBAL_WITH_ABS,
+ OPTION_RELAX,
+ OPTION_NO_RELAX,
OPTION_END_OF_ENUM,
};
@@ -130,6 +135,9 @@ struct option md_longopts[] =
{ "mla-global-with-pcrel", no_argument, NULL, OPTION_LA_GLOBAL_WITH_PCREL },
{ "mla-global-with-abs", no_argument, NULL, OPTION_LA_GLOBAL_WITH_ABS },
+ { "mrelax", no_argument, NULL, OPTION_RELAX },
+ { "mno-relax", no_argument, NULL, OPTION_NO_RELAX },
+
{ NULL, no_argument, NULL, 0 }
};
@@ -195,6 +203,14 @@ md_parse_option (int c, const char *arg)
LARCH_opts.ase_gabs = 1;
break;
+ case OPTION_RELAX:
+ LARCH_opts.relax = 1;
+ break;
+
+ case OPTION_NO_RELAX:
+ LARCH_opts.relax = 0;
+ break;
+
case OPTION_IGNORE:
break;
@@ -460,7 +476,6 @@ get_internal_label (expressionS *label_expr, unsigned long label,
int augend /* 0 for previous, 1 for next. */)
{
assert (label < INTERNAL_LABEL_SPECIAL);
- if (augend == 0 && internal_label_count[label] == 0)
as_fatal (_("internal error: we have no internal label yet"));
label_expr->X_op = O_symbol;
label_expr->X_add_symbol =
@@ -617,13 +632,26 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
as_fatal (
_("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"),
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_RELAX)
+ && ip->reloc_info[0].type < BFD_RELOC_LARCH_SUB_ULEB128)
{
/* As we compact stack-relocs, it is no need for pop operation.
But break out until here in order to check the imm field.
May be reloc_num > 1 if implement relax? */
ip->reloc_num += reloc_num;
+ reloc_type = ip->reloc_info[0].type;
+
+ if (LARCH_opts.relax && ip->macro_id
+ && (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))
+ {
+ ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
+ ip->reloc_info[ip->reloc_num].value = const_0;
+ ip->reloc_num++;
+ }
break;
}
reloc_num++;
@@ -835,8 +863,11 @@ move_insn (struct loongarch_cl_insn *insn, fragS *frag, long where)
insn->where = where;
for (i = 0; i < insn->reloc_num; i++)
{
- insn->fixp[i]->fx_frag = frag;
- insn->fixp[i]->fx_where = where;
+ if (insn->fixp[i])
+ {
+ insn->fixp[i]->fx_frag = frag;
+ insn->fixp[i]->fx_where = where;
+ }
}
install_insn (insn);
}
@@ -875,6 +906,21 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip)
as_fatal (_("Internal error: not support relax now"));
else
append_fixed_insn (ip);
+
+ /* We need to start a new frag after any instruction that can be
+ optimized away or compressed by the linker during relaxation, to prevent
+ the assembler from computing static offsets across such an instruction.
+
+ This is necessary to get correct .eh_frame cfa info. If one cfa's two
+ symbol is not in the same frag, it will generate relocs to calculate
+ symbol subtraction. (gas/dw2gencfi.c:output_cfi_insn:
+ if (symbol_get_frag (to) == symbol_get_frag (from))) */
+ if (BFD_RELOC_LARCH_PCALA_HI20 == reloc_info[0].type
+ || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type)
+ {
+ frag_wane (frag_now);
+ frag_new (0);
+ }
}
/* Ask helper for returning a malloced c_str or NULL. */
@@ -968,7 +1014,7 @@ assember_macro_helper (const char *const args[], void *context_ptr)
* assuming 'not starting with space and not ending with space' or pass in
* empty c_str. */
static void
-loongarch_assemble_INSNs (char *str)
+loongarch_assemble_INSNs (char *str, struct loongarch_cl_insn *ctx)
{
char *rest;
size_t len_str = strlen(str);
@@ -991,6 +1037,7 @@ loongarch_assemble_INSNs (char *str)
struct loongarch_cl_insn the_one = { 0 };
the_one.name = str;
+ the_one.macro_id = ctx->macro_id;
for (; *str && *str != ' '; str++)
;
@@ -1014,24 +1061,27 @@ loongarch_assemble_INSNs (char *str)
append_fixp_and_insn (&the_one);
if (the_one.insn_length == 0 && the_one.insn->macro)
{
+ the_one.macro_id = 1;
+
char *c_str = loongarch_expand_macro (the_one.insn->macro,
the_one.arg_strs,
assember_macro_helper,
&the_one, len_str);
- loongarch_assemble_INSNs (c_str);
+ loongarch_assemble_INSNs (c_str, &the_one);
free (c_str);
}
}
while (0);
if (*rest != '\0')
- loongarch_assemble_INSNs (rest);
+ loongarch_assemble_INSNs (rest, ctx);
}
void
md_assemble (char *str)
{
- loongarch_assemble_INSNs (str);
+ struct loongarch_cl_insn the_one = { 0 };
+ loongarch_assemble_INSNs (str, &the_one);
}
const char *
@@ -1062,7 +1112,7 @@ static void fix_reloc_insn (fixS *fixP, bfd_vma reloc_val, char *buf)
insn = bfd_getl32 (buf);
- if (!loongarch_adjust_reloc_bitsfield(howto, &reloc_val))
+ if (!loongarch_adjust_reloc_bitsfield (NULL, howto, &reloc_val))
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
insn = (insn & (insn_t)howto->src_mask)
@@ -1137,6 +1187,23 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
fix_reloc_insn (fixP, (bfd_vma)stack_top, buf);
break;
+ /* LARCH only has R_LARCH_64/32, not has R_LARCH_24/16/8.
+ For BFD_RELOC_64/32, if fx_addsy and fx_subsy not null, wer need
+ generate BFD_RELOC_LARCH_ADD64/32 and BFD_RELOC_LARCH_SUB64/32 here.
+ Then will parse howto table bfd_reloc_code_real_type to generate
+ R_LARCH_ADD64/32 and R_LARCH_SUB64/32 reloc at tc_gen_reloc function.
+ If only fx_addsy not null, skip here directly, then generate
+ R_LARCH_64/32.
+
+ For BFD_RELOC_24/16/8, if fx_addsy and fx_subsy not null, wer need
+ generate BFD_RELOC_LARCH_ADD24/16/8 and BFD_RELOC_LARCH_SUB24/16/8 here.
+ Then will parse howto table bfd_reloc_code_real_type to generate
+ R_LARCH_ADD24/16/8 and R_LARCH_SUB24/16/8 reloc at tc_gen_reloc
+ function. If only fx_addsy not null, we generate
+ BFD_RELOC_LARCH_ADD24/16/8 only, then generate R_LARCH_24/16/8.
+ To avoid R_LARCH_ADDxx add extra value, we write 0 first
+ (use md_number_to_chars (buf, 0, fixP->fx_size)).
+ */
case BFD_RELOC_64:
case BFD_RELOC_32:
if (fixP->fx_r_type == BFD_RELOC_32
@@ -1151,7 +1218,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
break;
}
- if (fixP->fx_subsy)
+ if (fixP->fx_addsy && fixP->fx_subsy)
{
fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
fixP->fx_next->fx_addsy = fixP->fx_subsy;
@@ -1186,34 +1253,37 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_24:
case BFD_RELOC_16:
case BFD_RELOC_8:
- fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
- fixP->fx_next->fx_addsy = fixP->fx_subsy;
- fixP->fx_next->fx_subsy = NULL;
- fixP->fx_next->fx_offset = 0;
- fixP->fx_subsy = NULL;
-
- switch (fixP->fx_r_type)
+ if (fixP->fx_addsy)
{
- case BFD_RELOC_24:
- fixP->fx_r_type = BFD_RELOC_LARCH_ADD24;
- fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB24;
- break;
- case BFD_RELOC_16:
- fixP->fx_r_type = BFD_RELOC_LARCH_ADD16;
- fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16;
- break;
- case BFD_RELOC_8:
- fixP->fx_r_type = BFD_RELOC_LARCH_ADD8;
- fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8;
- break;
- default:
- break;
- }
+ fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
+ fixP->fx_next->fx_addsy = fixP->fx_subsy;
+ fixP->fx_next->fx_subsy = NULL;
+ fixP->fx_next->fx_offset = 0;
+ fixP->fx_subsy = NULL;
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_24:
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD24;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB24;
+ break;
+ case BFD_RELOC_16:
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD16;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16;
+ break;
+ case BFD_RELOC_8:
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD8;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8;
+ break;
+ default:
+ break;
+ }
- md_number_to_chars (buf, 0, fixP->fx_size);
+ md_number_to_chars (buf, 0, fixP->fx_size);
- if (fixP->fx_next->fx_addsy == NULL)
- fixP->fx_next->fx_done = 1;
+ if (fixP->fx_next->fx_addsy == NULL)
+ fixP->fx_next->fx_done = 1;
+ }
if (fixP->fx_addsy == NULL)
{
@@ -1222,6 +1292,67 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
}
break;
+ case BFD_RELOC_LARCH_CFA:
+ if (fixP->fx_addsy && fixP->fx_subsy)
+ {
+ fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
+ fixP->fx_next->fx_addsy = fixP->fx_subsy;
+ fixP->fx_next->fx_subsy = NULL;
+ fixP->fx_next->fx_offset = 0;
+ fixP->fx_subsy = NULL;
+
+ unsigned int subtype;
+ offsetT loc;
+ subtype = bfd_get_8 (NULL, &((fragS *)
+ (fixP->fx_frag->fr_opcode))->fr_literal[fixP->fx_where]);
+ loc = fixP->fx_frag->fr_fix - (subtype & 7);
+ switch (subtype)
+ {
+ case DW_CFA_advance_loc1:
+ fixP->fx_where = loc + 1;
+ fixP->fx_next->fx_where = loc + 1;
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD8;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8;
+ md_number_to_chars (buf+1, 0, fixP->fx_size);
+ break;
+
+ case DW_CFA_advance_loc2:
+ fixP->fx_size = 2;
+ fixP->fx_next->fx_size = 2;
+ fixP->fx_where = loc + 1;
+ fixP->fx_next->fx_where = loc + 1;
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD16;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16;
+ md_number_to_chars (buf+1, 0, fixP->fx_size);
+ break;
+
+ case DW_CFA_advance_loc4:
+ fixP->fx_size = 4;
+ fixP->fx_next->fx_size = 4;
+ fixP->fx_where = loc;
+ fixP->fx_next->fx_where = loc;
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD32;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB32;
+ md_number_to_chars (buf+1, 0, fixP->fx_size);
+ break;
+
+ default:
+ if (subtype < 0x80 && (subtype & 0x40))
+ {
+ /* DW_CFA_advance_loc. */
+ fixP->fx_frag = (fragS *) fixP->fx_frag->fr_opcode;
+ fixP->fx_next->fx_frag = fixP->fx_frag;
+ fixP->fx_r_type = BFD_RELOC_LARCH_ADD6;
+ fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB6;
+ md_number_to_chars (buf, 0x40, fixP->fx_size);
+ }
+ else
+ as_fatal (_("internal: bad CFA value #%d"), subtype);
+ break;
+ }
+ }
+ break;
+
case BFD_RELOC_LARCH_B16:
case BFD_RELOC_LARCH_B21:
case BFD_RELOC_LARCH_B26:
@@ -1236,11 +1367,28 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
int64_t sym_addend = S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset;
int64_t pc = fixP->fx_where + fixP->fx_frag->fr_address;
fix_reloc_insn (fixP, sym_addend - pc, buf);
- fixP->fx_done = 1;
- }
+ /* If relax, symbol value may change at link time, so reloc need to
+ be saved. */
+ if (!LARCH_opts.relax)
+ fixP->fx_done = 1;
+ }
break;
+ /* Because ADD_ULEB128/SUB_ULEB128 always occur in pairs.
+ So just deal with one is ok.
+ case BFD_RELOC_LARCH_ADD_ULEB128: */
+ case BFD_RELOC_LARCH_SUB_ULEB128:
+ {
+ unsigned int len = 0;
+ _bfd_read_unsigned_leb128 (NULL, (bfd_byte *)buf, &len);
+ bfd_byte *endp = (bfd_byte*) buf + len -1;
+ /* Clean the uleb128 value to 0. Do not reduce the length. */
+ memset (buf, 0x80, len - 1);
+ *endp = 0;
+ break;
+ }
+
default:
break;
}
@@ -1258,19 +1406,7 @@ int
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
asection *segtype ATTRIBUTE_UNUSED)
{
- return 0;
-}
-
-int
-loongarch_fix_adjustable (fixS *fix)
-{
- /* Prevent all adjustments to global symbols. */
- if (S_IS_EXTERNAL (fix->fx_addsy)
- || S_IS_WEAK (fix->fx_addsy)
- || S_FORCE_RELOC (fix->fx_addsy, true))
- return 0;
-
- return 1;
+ return (fragp->fr_var = 4);
}
/* Translate internal representation of relocation info to BFD target
@@ -1300,9 +1436,25 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
/* Convert a machine dependent frag. */
void
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
- fragS *fragp ATTRIBUTE_UNUSED)
+ fragS *fragp)
{
- /* fragp->fr_fix += 8; */
+ expressionS exp;
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fragp->fr_symbol;
+ exp.X_add_number = fragp->fr_offset;
+ bfd_byte *buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
+
+ fixS *fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ 4, &exp, false, fragp->fr_subtype);
+ buf += 4;
+
+ fixp->fx_file = fragp->fr_file;
+ fixp->fx_line = fragp->fr_line;
+ fragp->fr_fix += fragp->fr_var;
+
+ gas_assert (fragp->fr_next == NULL
+ || (fragp->fr_next->fr_address - fragp->fr_address
+ == fragp->fr_fix));
}
/* Standard calling conventions leave the CFA at SP on entry. */
@@ -1312,6 +1464,48 @@ loongarch_cfi_frame_initial_instructions (void)
cfi_add_CFA_def_cfa_register (3 /* $sp */);
}
+void
+loongarch_pre_output_hook (void)
+{
+ const frchainS *frch;
+ segT s;
+
+ /* Save the current segment info. */
+ segT seg = now_seg;
+ subsegT subseg = now_subseg;
+
+ for (s = stdoutput->sections; s; s = s->next)
+ for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next)
+ {
+ fragS *frag;
+
+ for (frag = frch->frch_root; frag; frag = frag->fr_next)
+ {
+ if (frag->fr_type == rs_cfa)
+ {
+ expressionS exp;
+ expressionS *symval;
+
+ symval = symbol_get_value_expression (frag->fr_symbol);
+ exp.X_op = O_subtract;
+ exp.X_add_symbol = symval->X_add_symbol;
+ exp.X_add_number = 0;
+ exp.X_op_symbol = symval->X_op_symbol;
+
+ /* We must set the segment before creating a frag after all
+ frag chains have been chained together. */
+ subseg_set (s, frch->frch_subseg);
+
+ fix_new_exp (frag, (int) frag->fr_offset, 1, &exp, 0,
+ BFD_RELOC_LARCH_CFA);
+ }
+ }
+ }
+
+ /* Restore the original segment info. */
+ subseg_set (seg, subseg);
+}
+
void
tc_loongarch_parse_to_dw2regnum (expressionS *exp)
{
@@ -1325,6 +1519,58 @@ md_show_usage (FILE *stream)
/* FIXME */
}
+static void
+loongarch_make_nops (char *buf, bfd_vma bytes)
+{
+ bfd_vma i = 0;
+
+ /* Fill with 4-byte NOPs. */
+ for ( ; i < bytes; i += 4)
+ number_to_chars_littleendian (buf + i, LARCH_NOP, 4);
+}
+
+/* Called from md_do_align. Used to create an alignment frag in a
+ code section by emitting a worst-case NOP sequence that the linker
+ will later relax to the correct number of NOPs. We can't compute
+ the correct alignment now because of other linker relaxations. */
+
+bool
+loongarch_frag_align_code (int n)
+{
+ bfd_vma bytes = (bfd_vma) 1 << n;
+ bfd_vma insn_alignment = 4;
+ bfd_vma worst_case_bytes = bytes - insn_alignment;
+ char *nops;
+ expressionS ex;
+
+ /* If we are moving to a smaller alignment than the instruction size, then no
+ alignment is required. */
+ if (bytes <= insn_alignment)
+ return true;
+
+ /* When not relaxing, loongarch_handle_align handles code alignment. */
+ if (!LARCH_opts.relax)
+ return false;
+
+ nops = frag_more (worst_case_bytes);
+
+ ex.X_op = O_constant;
+ ex.X_add_number = worst_case_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. */
+ frag_wane (frag_now);
+ frag_new (0);
+
+ return true;
+}
+
/* Fill in an rs_align_code fragment. We want to fill 'andi $r0,$r0,0'. */
void
loongarch_handle_align (fragS *fragp)
@@ -1360,6 +1606,68 @@ loongarch_handle_align (fragS *fragp)
fragp->fr_var = size;
}
+/* Scan uleb128 subtraction expressions and insert fixups for them.
+ e.g., .uleb128 .L1 - .L0
+ Because relaxation may change the value of the subtraction, we
+ must resolve them at link-time. */
+
+static void
+loongarch_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec, void *xxx ATTRIBUTE_UNUSED)
+{
+ segment_info_type *seginfo = seg_info (sec);
+ struct frag *fragP;
+
+ subseg_set (sec, 0);
+
+ for (fragP = seginfo->frchainP->frch_root;
+ fragP; fragP = fragP->fr_next)
+ {
+ expressionS *exp, *exp_dup;
+
+ if (fragP->fr_type != rs_leb128 || fragP->fr_symbol == NULL)
+ continue;
+
+ exp = symbol_get_value_expression (fragP->fr_symbol);
+
+ if (exp->X_op != O_subtract)
+ continue;
+
+ /* FIXME: Skip for .sleb128. */
+ if (fragP->fr_subtype != 0)
+ continue;
+
+ exp_dup = xmemdup (exp, sizeof (*exp), sizeof (*exp));
+ exp_dup->X_op = O_symbol;
+ exp_dup->X_op_symbol = NULL;
+
+ exp_dup->X_add_symbol = exp->X_add_symbol;
+ fix_new_exp (fragP, fragP->fr_fix, 0,
+ exp_dup, 0, BFD_RELOC_LARCH_ADD_ULEB128);
+
+ /* From binutils/testsuite/binutils-all/dw5.S
+ section .debug_rnglists
+ .uleb128 .Letext0-.Ltext0 Range length (*.LLRL2)
+ Offset Info Type Symbol's Value Symbol's Name + Addend
+0000000000000015 0000000200000079 R_LARCH_ADD_ULEB128 0000000000000000 .text + 2
+0000000000000015 000000020000007a R_LARCH_SUB_ULEB128 0000000000000000 .text + 0. */
+
+ /* Only the ADD_ULEB128 has X_add_number (Addend)? */
+ exp_dup->X_add_number = 0;
+ exp_dup->X_add_symbol = exp->X_op_symbol;
+ fix_new_exp (fragP, fragP->fr_fix, 0,
+ exp_dup, 0, BFD_RELOC_LARCH_SUB_ULEB128);
+ }
+}
+
+void
+loongarch_md_finish (void)
+{
+ /* Insert relocations for uleb128 directives, so the values can be recomputed
+ at link time. */
+ bfd_map_over_sections (stdoutput, loongarch_insert_uleb128_fixes, NULL);
+}
+
void
loongarch_elf_final_processing (void)
{
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
index 7d416b0c01b..c6e0b4af2d5 100644
--- a/gas/config/tc-loongarch.h
+++ b/gas/config/tc-loongarch.h
@@ -30,6 +30,8 @@ extern unsigned long loongarch_mach (void);
#define WORKING_DOT_WORD 1
#define REPEAT_CONS_EXPRESSIONS
+#define md_allow_local_subtract(l,r,s) 0
+
/* Early than md_begin. */
#define md_after_parse_args loongarch_after_parse_args
extern void loongarch_after_parse_args (void);
@@ -47,16 +49,40 @@ extern int loongarch_relax_frag (asection *, struct frag *, long);
#define md_undefined_symbol(name) (0)
#define md_operand(x)
+extern bool loongarch_frag_align_code (int);
+#define md_do_align(N, FILL, LEN, MAX, LABEL) \
+ if ((N) != 0 && !(FILL) && !need_pass_2 && subseg_text_p (now_seg)) \
+ { \
+ if (loongarch_frag_align_code (N)) \
+ goto LABEL; \
+ }
+
/* This is called to see whether a reloc against a defined symbol
- should be converted into a reloc against a section. */
-extern int loongarch_fix_adjustable (struct fix *fix);
-#define tc_fix_adjustable(fixp) loongarch_fix_adjustable(fixp)
+ should be converted into a reloc against a section.
+ Let the linker resolve all the relocs due to relaxation. */
+#define tc_fix_adjustable(fixp) 0
/* Values passed to md_apply_fix don't include symbol values. */
#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1
#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1
#define DIFF_EXPR_OK 1
+#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC) \
+ (GENERIC_FORCE_RELOCATION_SUB_SAME (FIX, SEC) \
+ || ((SEC)->flags & SEC_CODE) != 0 \
+ || ((SEC)->flags & SEC_DEBUGGING) != 0 \
+ || TC_FORCE_RELOCATION (FIX))
+
+#define TC_LINKRELAX_FIXUP(seg) ((seg->flags & SEC_CODE) \
+ || (seg->flags & SEC_DEBUGGING))
+
+#define TC_FORCE_RELOCATION_LOCAL(FIX) 1
+
+/* Adjust debug_line after relaxation. */
+#define DWARF2_USE_FIXED_ADVANCE_PC 1
+
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
#define TARGET_USE_CFIPOP 1
#define DWARF2_DEFAULT_RETURN_COLUMN 1 /* $ra. */
#define DWARF2_CIE_DATA_ALIGNMENT -4
@@ -65,13 +91,15 @@ extern int loongarch_fix_adjustable (struct fix *fix);
loongarch_cfi_frame_initial_instructions
extern void loongarch_cfi_frame_initial_instructions (void);
+#define tc_symbol_new_hook(sym) \
+ if (0 == strcmp (sym->bsym->name, FAKE_LABEL_NAME)) \
+ S_SET_OTHER (sym, STV_HIDDEN);
+
#define tc_parse_to_dw2regnum tc_loongarch_parse_to_dw2regnum
extern void tc_loongarch_parse_to_dw2regnum (expressionS *);
-/* A enumerated values to specific how to deal with align in '.text'.
- Now we want to fill 'andi $r0,$r0,0x0'.
- Here is the type 0, will fill andi insn later. */
-#define NOP_OPCODE (0x00)
+extern void loongarch_pre_output_hook (void);
+#define md_pre_output_hook loongarch_pre_output_hook ()
#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
@@ -90,4 +118,7 @@ struct reloc_info
expressionS value;
};
+#define md_finish loongarch_md_finish
+extern void loongarch_md_finish (void);
+
#endif
diff --git a/gas/testsuite/gas/all/align.d b/gas/testsuite/gas/all/align.d
index c701f25bfcc..43c1413de04 100644
--- a/gas/testsuite/gas/all/align.d
+++ b/gas/testsuite/gas/all/align.d
@@ -3,8 +3,9 @@
# The RX port will always replace zeros in any aligned area with NOPs,
# even if the user requested that they filled with zeros.
# RISC-V handles alignment via relaxation and therefor won't have object files
-# with the expected alignment.
-#notarget: riscv*-* rx-*
+# LoongArch handles alignment via relaxation and therefor won't have object
+# files with the expected alignment.
+#notarget: loongarch*-* riscv*-* rx-*
# Test the alignment pseudo-op.
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 28570c53ac5..20010d9522c 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -67,14 +67,14 @@ if { ![istarget alpha*-*-*vms*]
&& ![istarget ft32-*-*]
&& ![istarget hppa*-*-*]
&& ![istarget microblaze-*-*]
+ && ![istarget loongarch*-*-*]
&& ![istarget mn10300-*-*]
&& ![istarget msp430*-*-*]
&& ![istarget powerpc*-*-aix*]
&& ![istarget riscv*-*-*]
&& ![istarget rl78-*-*]
&& ![istarget rs6000*-*-aix*]
- && ![istarget rx-*-*]
- && ![istarget loongarch*-*-*] } then {
+ && ![istarget rx-*-*] } then {
gas_test_error "diff1.s" "" "difference of two undefined symbols"
}
@@ -165,11 +165,11 @@ switch -glob $target_triplet {
# These targets fail redef2 because they disallow redefined
# symbols on relocs.
setup_xfail "m68hc1*-*-*" "m6811-*-*" "m6812-*-*" "rl78-*-*"
- setup_xfail "riscv*-*-*" "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*"
+ setup_xfail "loongarch*-*-*" "riscv*-*-*" "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*"
setup_xfail "avr-*-*"
run_dump_test redef2
setup_xfail "m68hc1*-*-*" "m6811-*-*" "m6812-*-*" "rl78-*-*"
- setup_xfail "riscv*-*-*" "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*"
+ setup_xfail "loongarch*-*-*" "riscv*-*-*" "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*"
setup_xfail "avr-*-*"
# rs6000-aix disallows redefinition via .comm.
if [is_xcoff_format] {
@@ -281,7 +281,7 @@ if { ![istarget *c30*-*-*]
# The vax fails because VMS can apparently actually handle this
# case in relocs, so gas doesn't handle it itself.
# msp430, mn10[23]00 and riscv emit two relocs to handle the difference of two symbols.
- setup_xfail "am3*-*-*" "mn10200-*-*" "mn10300*-*-*" "msp430*-*-*" "riscv*-*-*" "vax*-*-vms*"
+ setup_xfail "am3*-*-*" "loongarch*-*-*" "mn10200-*-*" "mn10300*-*-*" "msp430*-*-*" "riscv*-*-*" "vax*-*-vms*"
do_930509a
}
diff --git a/gas/testsuite/gas/all/relax.d b/gas/testsuite/gas/all/relax.d
index f394043b017..00fba6d62cd 100644
--- a/gas/testsuite/gas/all/relax.d
+++ b/gas/testsuite/gas/all/relax.d
@@ -4,6 +4,10 @@
# because symbol values are not known until after linker relaxation has been
# performed.
#notarget : riscv*-*-*
+# LoongArch doesn't resolve .uleb operands that are the difference of two
+# symbols because gas write zero to object file and generate add_uleb128 and
+# sub_uleb128 reloc pair.
+#xfail: loongarch*-*-*
.*: .*
diff --git a/gas/testsuite/gas/elf/dwarf-5-irp.d b/gas/testsuite/gas/elf/dwarf-5-irp.d
index 048a6d5a87a..6bcdc6636a6 100644
--- a/gas/testsuite/gas/elf/dwarf-5-irp.d
+++ b/gas/testsuite/gas/elf/dwarf-5-irp.d
@@ -5,7 +5,8 @@
# The bfin target does not allow .subsection with an equated symbol as operand.
# The d30v target emits sufficiently different debug info, apparently also covering padding it inserts.
# The riscv targets do not support the subtraction of symbols.
-#xfail: am33*-* bfin-* cr16-* crx-* d30v-* ft32-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
+# The loongarch targets do not support the subtraction of symbols.
+#xfail: am33*-* bfin-* cr16-* crx-* d30v-* ft32-* loongarch*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
Raw dump of debug contents .*
#...
diff --git a/gas/testsuite/gas/elf/dwarf-5-loc0.d b/gas/testsuite/gas/elf/dwarf-5-loc0.d
index 7e8473a486f..e58025bba62 100644
--- a/gas/testsuite/gas/elf/dwarf-5-loc0.d
+++ b/gas/testsuite/gas/elf/dwarf-5-loc0.d
@@ -3,7 +3,8 @@
#name: DWARF5 .loc 0
# The am33 cr16 crx ft32 mn10 msp430 nds32 and rl78 targets do not evaluate the subtraction of symbols at assembly time.
# The riscv targets do not support the subtraction of symbols.
-#xfail: am3*-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
+# The loongarch targets do not support the subtraction of symbols.
+#xfail: am3*-* cr16-* crx-* ft32*-* loongarch*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
Contents of the \.debug_line section:
diff --git a/gas/testsuite/gas/elf/dwarf2-11.d b/gas/testsuite/gas/elf/dwarf2-11.d
index 2c30e55c695..44f5cd18ec6 100644
--- a/gas/testsuite/gas/elf/dwarf2-11.d
+++ b/gas/testsuite/gas/elf/dwarf2-11.d
@@ -3,7 +3,8 @@
#name: DWARF2 11
# The am33 cr16 crx ft32 mn10 msp430 nds32 and rl78 targets do not evaluate the subtraction of symbols at assembly time.
# The riscv targets do not support the subtraction of symbols.
-#xfail: am3*-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
+# The loongarch targets do not support the subtraction of symbols.
+#xfail: am3*-* cr16-* crx-* ft32*-* loongarch*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
Contents of the \.debug_line section:
diff --git a/gas/testsuite/gas/elf/dwarf2-15.d b/gas/testsuite/gas/elf/dwarf2-15.d
index 939c61598cb..3ec9f2785a7 100644
--- a/gas/testsuite/gas/elf/dwarf2-15.d
+++ b/gas/testsuite/gas/elf/dwarf2-15.d
@@ -3,7 +3,8 @@
#name: DWARF2 15
# The am33 cr16 crx ft32 mn10 msp430 nds32 and rl78 targets do not evaluate the subtraction of symbols at assembly time.
# The riscv targets do not support the subtraction of symbols.
-#xfail: am3*-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
+# The loongarch targets do not support the subtraction of symbols.
+#xfail: am3*-* cr16-* crx-* ft32*-* loongarch*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
Hex dump of section '\.rodata':
0x00000000 01 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-16.d b/gas/testsuite/gas/elf/dwarf2-16.d
index 8e35d493619..32b57763137 100644
--- a/gas/testsuite/gas/elf/dwarf2-16.d
+++ b/gas/testsuite/gas/elf/dwarf2-16.d
@@ -4,7 +4,8 @@
# The am33 cr16 crx ft32 mn10 msp430 nds32 and rl78 targets do not evaluate the subtraction of symbols at assembly time.
# The mep target tries to relay code sections which breaks symbolic view computations.
# The riscv targets do not support the subtraction of symbols.
-#xfail: am3*-* cr16-* crx-* ft32*-* mep-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
+# The loongarch targets do not support the subtraction of symbols.
+#xfail: am3*-* cr16-* crx-* ft32*-* mep-* loongarch*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
Hex dump of section '\.rodata':
0x00000000 01 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-17.d b/gas/testsuite/gas/elf/dwarf2-17.d
index 881477cf95b..4c2f2e3999e 100644
--- a/gas/testsuite/gas/elf/dwarf2-17.d
+++ b/gas/testsuite/gas/elf/dwarf2-17.d
@@ -4,7 +4,8 @@
# The am33 cr16 crx ft32 mn10 msp430 nds32 and rl78 targets do not evaluate the subtraction of symbols at assembly time.
# The mep target tries to relay code sections which breaks symbolic view computations.
# The riscv targets do not support the subtraction of symbols.
-#xfail: am3*-* cr16-* crx-* ft32*-* mep-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
+# The loongarch targets do not support the subtraction of symbols.
+#xfail: am3*-* cr16-* crx-* ft32*-* loongarch*-* mep-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
Hex dump of section '\.rodata':
0x00000000 00 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-18.d b/gas/testsuite/gas/elf/dwarf2-18.d
index fbaebaa9019..18157c634a5 100644
--- a/gas/testsuite/gas/elf/dwarf2-18.d
+++ b/gas/testsuite/gas/elf/dwarf2-18.d
@@ -3,7 +3,8 @@
#name: DWARF2 18
# The am33 cr16 crx ft32 mn10 msp430 nds32 and rl78 targets do not evaluate the subtraction of symbols at assembly time.
# The riscv targets do not support the subtraction of symbols.
-#xfail: am3*-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
+# The loongarch targets do not support the subtraction of symbols.
+#xfail: am3*-* cr16-* crx-* ft32*-* loongarch*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
Hex dump of section '\.rodata':
0x00000000 0100 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-19.d b/gas/testsuite/gas/elf/dwarf2-19.d
index 55d0caf4cb1..133294affe7 100644
--- a/gas/testsuite/gas/elf/dwarf2-19.d
+++ b/gas/testsuite/gas/elf/dwarf2-19.d
@@ -4,7 +4,8 @@
# The am33 cr16 crx ft32 mn10 msp430 nds32 and rl78 targets do not evaluate the subtraction of symbols at assembly time.
# The mep targets turns some view computations into complex relocations.
# The riscv targets do not support the subtraction of symbols.
-#xfail: am3*-* cr16-* crx-* ft32*-* mep-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
+# The loongarch targets do not support the subtraction of symbols.
+#xfail: am3*-* cr16-* crx-* ft32*-* mep-* loongarch*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-*
Hex dump of section '\.rodata':
0x00000000 01000102 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-5.d b/gas/testsuite/gas/elf/dwarf2-5.d
index ced12e7c0c7..886f1a13389 100644
--- a/gas/testsuite/gas/elf/dwarf2-5.d
+++ b/gas/testsuite/gas/elf/dwarf2-5.d
@@ -4,7 +4,8 @@
# The am33 cr16 crx ft32 mn10 msp430 nds32 rl78 and rx targets do not evaluate the subtraction of symbols at assembly time.
# The mep target tries to relay code sections which breaks symbolic view computations.
# The riscv targets do not support the subtraction of symbols.
-#xfail: am3*-* cr16-* crx-* ft32*-* mep-* mn10*-* msp430-* nds32*-* riscv*-* rl78-* rx-*
+# The loongarch targets do not support the subtraction of symbols.
+#xfail: am3*-* cr16-* crx-* ft32*-* loongarch*-* mep-* mn10*-* msp430-* nds32*-* riscv*-* rl78-* rx-*
Hex dump of section '\.rodata':
0x00000000 01010201 010203 *.*
diff --git a/gas/testsuite/gas/elf/ehopt0.d b/gas/testsuite/gas/elf/ehopt0.d
index a13c4f26e33..64c5fb5ddc4 100644
--- a/gas/testsuite/gas/elf/ehopt0.d
+++ b/gas/testsuite/gas/elf/ehopt0.d
@@ -1,5 +1,8 @@
#objdump: -s -j .eh_frame
#name: elf ehopt0
+# The loongarch target do not evaluate .eh_frame fde cfa advance loc at assembly time.
+# Because loongarch use add/sub reloc evaluate cfa advance loc, so gas should write 0 to cfa advance loc address.
+#xfail: loongarch*-*
.*: +file format .*
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index 07f08a00a28..7873eb39ab1 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -72,6 +72,9 @@ if { [is_elf_format] } then {
if {[istarget "csky*-*-*"]} {
set target_machine -csky
}
+ if {[istarget "loongarch*-*-*"]} then {
+ set dump_opts {{as -mno-relax}}
+ }
if {[istarget "m32r*-*-*"]} then {
set target_machine -m32r
}
diff --git a/gas/testsuite/gas/elf/section11.d b/gas/testsuite/gas/elf/section11.d
index 427aea67032..277fa6df7d6 100644
--- a/gas/testsuite/gas/elf/section11.d
+++ b/gas/testsuite/gas/elf/section11.d
@@ -2,8 +2,8 @@
#readelf: -S --wide
#name: Disabling section padding
# The RX port uses non standard section names.
-#xfail: rx-*-*
-# RISC-V handles alignment via linker relaxation, so object files don't have
+#xfail: loongarch*-* rx-*-*
+# LoongArch and RISC-V handles alignment via linker relaxation, so object files don't have
# the expected alignment.
#xfail: riscv*-*-*
diff --git a/gas/testsuite/gas/lns/lns.exp b/gas/testsuite/gas/lns/lns.exp
index 046b50d5729..1d672102743 100644
--- a/gas/testsuite/gas/lns/lns.exp
+++ b/gas/testsuite/gas/lns/lns.exp
@@ -31,6 +31,7 @@ if { ![istarget s390*-*-*] } {
|| [istarget cr16-*-*]
|| [istarget crx-*-*]
|| [istarget ft32*-*]
+ || [istarget loongarch*-*-*]
|| [istarget mn10*-*-*]
|| [istarget msp430-*-*]
|| [istarget nds32*-*-*]
diff --git a/gas/testsuite/gas/loongarch/jmp_op.d b/gas/testsuite/gas/loongarch/jmp_op.d
index 218c13f9398..a4535c297c9 100644
--- a/gas/testsuite/gas/loongarch/jmp_op.d
+++ b/gas/testsuite/gas/loongarch/jmp_op.d
@@ -6,26 +6,45 @@
Disassembly of section .text:
-00000000.* <.text>:
-[ ]+0:[ ]+03400000[ ]+[ ]+andi[ ]+\$zero, \$zero, 0x0
-[ ]+4:[ ]+63fffc04[ ]+[ ]+blt[ ]+\$zero, \$a0, -4\(0x3fffc\)[ ]+# 0x0
-[ ]+8:[ ]+67fff880[ ]+[ ]+bge[ ]+\$a0, \$zero, -8\(0x3fff8\)[ ]+# 0x0
-[ ]+c:[ ]+67fff404[ ]+[ ]+bge[ ]+\$zero, \$a0, -12\(0x3fff4\)[ ]+# 0x0
-[ ]+10:[ ]+43fff09f[ ]+[ ]+beqz[ ]+\$a0, -16\(0x7ffff0\)[ ]+# 0x0
-[ ]+14:[ ]+47ffec9f[ ]+[ ]+bnez[ ]+\$a0, -20\(0x7fffec\)[ ]+# 0x0
-[ ]+18:[ ]+4bffe81f[ ]+[ ]+bceqz[ ]+\$fcc0, -24\(0x7fffe8\)[ ]+# 0x0
-[ ]+1c:[ ]+4bffe51f[ ]+[ ]+bcnez[ ]+\$fcc0, -28\(0x7fffe4\)[ ]+# 0x0
-[ ]+20:[ ]+4c000080[ ]+[ ]+jirl[ ]+\$zero, \$a0, 0
-[ ]+24:[ ]+53ffdfff[ ]+[ ]+b[ ]+-36\(0xfffffdc\)[ ]+# 0x0
-[ ]+28:[ ]+57ffdbff[ ]+[ ]+bl[ ]+-40\(0xfffffd8\)[ ]+# 0x0
-[ ]+2c:[ ]+5bffd485[ ]+[ ]+beq[ ]+\$a0, \$a1, -44\(0x3ffd4\)[ ]+# 0x0
-[ ]+30:[ ]+5fffd085[ ]+[ ]+bne[ ]+\$a0, \$a1, -48\(0x3ffd0\)[ ]+# 0x0
-[ ]+34:[ ]+63ffcc85[ ]+[ ]+blt[ ]+\$a0, \$a1, -52\(0x3ffcc\)[ ]+# 0x0
-[ ]+38:[ ]+63ffc8a4[ ]+[ ]+blt[ ]+\$a1, \$a0, -56\(0x3ffc8\)[ ]+# 0x0
-[ ]+3c:[ ]+67ffc485[ ]+[ ]+bge[ ]+\$a0, \$a1, -60\(0x3ffc4\)[ ]+# 0x0
-[ ]+40:[ ]+67ffc0a4[ ]+[ ]+bge[ ]+\$a1, \$a0, -64\(0x3ffc0\)[ ]+# 0x0
-[ ]+44:[ ]+6bffbc85[ ]+[ ]+bltu[ ]+\$a0, \$a1, -68\(0x3ffbc\)[ ]+# 0x0
-[ ]+48:[ ]+6bffb8a4[ ]+[ ]+bltu[ ]+\$a1, \$a0, -72\(0x3ffb8\)[ ]+# 0x0
-[ ]+4c:[ ]+6fffb485[ ]+[ ]+bgeu[ ]+\$a0, \$a1, -76\(0x3ffb4\)[ ]+# 0x0
-[ ]+50:[ ]+6fffb0a4[ ]+[ ]+bgeu[ ]+\$a1, \$a0, -80\(0x3ffb0\)[ ]+# 0x0
-[ ]+54:[ ]+4c000020[ ]+[ ]+jirl[ ]+\$zero, \$ra, 0
+00000000.* <.L1>:
+[ ]+0:[ ]+03400000[ ]+andi[ ]+\$zero,[ ]+\$zero,[ ]+0x0
+[ ]+4:[ ]+63fffc04[ ]+blt[ ]+\$zero,[ ]+\$a0,[ ]+-4\(0x3fffc\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+4:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+8:[ ]+67fff880[ ]+bge[ ]+\$a0,[ ]+\$zero,[ ]+-8\(0x3fff8\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+8:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+c:[ ]+67fff404[ ]+bge[ ]+\$zero,[ ]+\$a0,[ ]+-12\(0x3fff4\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+c:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+10:[ ]+43fff09f[ ]+beqz[ ]+\$a0,[ ]+-16\(0x7ffff0\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+10:[ ]+R_LARCH_B21[ ]+\.L1
+[ ]+14:[ ]+47ffec9f[ ]+bnez[ ]+\$a0,[ ]+-20\(0x7fffec\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+14:[ ]+R_LARCH_B21[ ]+\.L1
+[ ]+18:[ ]+4bffe81f[ ]+bceqz[ ]+\$fcc0,[ ]+-24\(0x7fffe8\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+18:[ ]+R_LARCH_B21[ ]+\.L1
+[ ]+1c:[ ]+4bffe51f[ ]+bcnez[ ]+\$fcc0,[ ]+-28\(0x7fffe4\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+1c:[ ]+R_LARCH_B21[ ]+\.L1
+[ ]+20:[ ]+4c000080[ ]+jirl[ ]+\$zero,[ ]+\$a0,[ ]+0
+[ ]+24:[ ]+53ffdfff[ ]+b[ ]+-36\(0xfffffdc\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+24:[ ]+R_LARCH_B26[ ]+\.L1
+[ ]+28:[ ]+57ffdbff[ ]+bl[ ]+-40\(0xfffffd8\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+28:[ ]+R_LARCH_B26[ ]+\.L1
+[ ]+2c:[ ]+5bffd485[ ]+beq[ ]+\$a0,[ ]+\$a1,[ ]+-44\(0x3ffd4\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+2c:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+30:[ ]+5fffd085[ ]+bne[ ]+\$a0,[ ]+\$a1,[ ]+-48\(0x3ffd0\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+30:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+34:[ ]+63ffcc85[ ]+blt[ ]+\$a0,[ ]+\$a1,[ ]+-52\(0x3ffcc\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+34:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+38:[ ]+63ffc8a4[ ]+blt[ ]+\$a1,[ ]+\$a0,[ ]+-56\(0x3ffc8\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+38:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+3c:[ ]+67ffc485[ ]+bge[ ]+\$a0,[ ]+\$a1,[ ]+-60\(0x3ffc4\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+3c:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+40:[ ]+67ffc0a4[ ]+bge[ ]+\$a1,[ ]+\$a0,[ ]+-64\(0x3ffc0\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+40:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+44:[ ]+6bffbc85[ ]+bltu[ ]+\$a0,[ ]+\$a1,[ ]+-68\(0x3ffbc\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+44:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+48:[ ]+6bffb8a4[ ]+bltu[ ]+\$a1,[ ]+\$a0,[ ]+-72\(0x3ffb8\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+48:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+4c:[ ]+6fffb485[ ]+bgeu[ ]+\$a0,[ ]+\$a1,[ ]+-76\(0x3ffb4\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+4c:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+50:[ ]+6fffb0a4[ ]+bgeu[ ]+\$a1,[ ]+\$a0,[ ]+-80\(0x3ffb0\)[ ]+#[ ]+0[ ]+<\.L1>
+[ ]+50:[ ]+R_LARCH_B16[ ]+\.L1
+[ ]+54:[ ]+4c000020[ ]+jirl[ ]+\$zero,[ ]+\$ra,[ ]+0
diff --git a/gas/testsuite/gas/loongarch/li.d b/gas/testsuite/gas/loongarch/li.d
index 850a3f48e30..324130ccc74 100644
--- a/gas/testsuite/gas/loongarch/li.d
+++ b/gas/testsuite/gas/loongarch/li.d
@@ -1,6 +1,5 @@
#as:
#objdump: -dr
-#skip: loongarch32-*-*
.*:[ ]+file format .*
@@ -10,9 +9,11 @@ Disassembly of section .text:
00000000.* <_start>:
[ ]+0:[ ]+03803c06[ ]+ori[ ]+\$a2,[ ]+\$zero,[ ]+0xf
[ ]+4:[ ]+1a000005[ ]+pcalau12i[ ]+\$a1,[ ]+0
-[ ]+4:[ ]+R_LARCH_PCALA_HI20[ ]+.rodata
-[ ]+8:[ ]+02c000a5[ ]+addi.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+8:[ ]+R_LARCH_PCALA_LO12[ ]+.rodata
+[ ]+4:[ ]+R_LARCH_PCALA_HI20[ ]+msg
+[ ]+4:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+8:[ ]+02c000a5[ ]+addi\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+8:[ ]+R_LARCH_PCALA_LO12[ ]+msg
+[ ]+8:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+c:[ ]+03800404[ ]+ori[ ]+\$a0,[ ]+\$zero,[ ]+0x1
[ ]+10:[ ]+0381000b[ ]+ori[ ]+\$a7,[ ]+\$zero,[ ]+0x40
[ ]+14:[ ]+002b0000[ ]+syscall[ ]+0x0
diff --git a/gas/testsuite/gas/loongarch/macro_op.d b/gas/testsuite/gas/loongarch/macro_op.d
index d264c4f25c5..450a38e479a 100644
--- a/gas/testsuite/gas/loongarch/macro_op.d
+++ b/gas/testsuite/gas/loongarch/macro_op.d
@@ -1,6 +1,5 @@
#as:
#objdump: -dr
-#skip: loongarch32-*-*
.*:[ ]+file format .*
@@ -9,51 +8,63 @@ Disassembly of section .text:
00000000.* <.text>:
[ ]+0:[ ]+00150004[ ]+move[ ]+\$a0,[ ]+\$zero
-[ ]+4:[ ]+02bffc04[ ]+addi.w[ ]+\$a0,[ ]+\$zero,[ ]+-1\(0xfff\)
+[ ]+4:[ ]+02bffc04[ ]+addi\.w[ ]+\$a0,[ ]+\$zero,[ ]+-1\(0xfff\)
[ ]+8:[ ]+00150004[ ]+move[ ]+\$a0,[ ]+\$zero
-[ ]+c:[ ]+02bffc04[ ]+addi.w[ ]+\$a0,[ ]+\$zero,[ ]+-1\(0xfff\)
+[ ]+c:[ ]+02bffc04[ ]+addi\.w[ ]+\$a0,[ ]+\$zero,[ ]+-1\(0xfff\)
[ ]+10:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+10:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
-[ ]+14:[ ]+28c00084[ ]+ld.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+14:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+10:[ ]+R_LARCH_GOT_PC_HI20[ ]+\.L1
+[ ]+10:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+14:[ ]+28c00084[ ]+ld\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+14:[ ]+R_LARCH_GOT_PC_LO12[ ]+\.L1
+[ ]+14:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+18:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+18:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
-[ ]+1c:[ ]+28c00084[ ]+ld.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+1c:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+18:[ ]+R_LARCH_GOT_PC_HI20[ ]+\.L1
+[ ]+18:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+1c:[ ]+28c00084[ ]+ld\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+1c:[ ]+R_LARCH_GOT_PC_LO12[ ]+\.L1
+[ ]+1c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+20:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+20:[ ]+R_LARCH_PCALA_HI20[ ]+.L1
-[ ]+24:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+24:[ ]+R_LARCH_PCALA_LO12[ ]+.L1
-[ ]+28:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
+[ ]+20:[ ]+R_LARCH_PCALA_HI20[ ]+\.L1
+[ ]+20:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+24:[ ]+02c00084[ ]+addi\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+24:[ ]+R_LARCH_PCALA_LO12[ ]+\.L1
+[ ]+24:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+28:[ ]+14000004[ ]+lu12i\.w[ ]+\$a0,[ ]+0
[ ]+28:[ ]+R_LARCH_MARK_LA[ ]+\*ABS\*
-[ ]+28:[ ]+R_LARCH_ABS_HI20[ ]+.L1
+[ ]+28:[ ]+R_LARCH_ABS_HI20[ ]+\.L1
[ ]+2c:[ ]+03800084[ ]+ori[ ]+\$a0,[ ]+\$a0,[ ]+0x0
-[ ]+2c:[ ]+R_LARCH_ABS_LO12[ ]+.L1
-[ ]+30:[ ]+16000004[ ]+lu32i.d[ ]+\$a0,[ ]+0
-[ ]+30:[ ]+R_LARCH_ABS64_LO20[ ]+.L1
-[ ]+34:[ ]+03000084[ ]+lu52i.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+34:[ ]+R_LARCH_ABS64_HI12[ ]+.L1
+[ ]+2c:[ ]+R_LARCH_ABS_LO12[ ]+\.L1
+[ ]+30:[ ]+16000004[ ]+lu32i\.d[ ]+\$a0,[ ]+0
+[ ]+30:[ ]+R_LARCH_ABS64_LO20[ ]+\.L1
+[ ]+34:[ ]+03000084[ ]+lu52i\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+34:[ ]+R_LARCH_ABS64_HI12[ ]+\.L1
[ ]+38:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+38:[ ]+R_LARCH_PCALA_HI20[ ]+.L1
-[ ]+3c:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+3c:[ ]+R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+38:[ ]+R_LARCH_PCALA_HI20[ ]+\.L1
+[ ]+38:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+3c:[ ]+02c00084[ ]+addi\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+3c:[ ]+R_LARCH_PCALA_LO12[ ]+\.L1
+[ ]+3c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+40:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+40:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
-[ ]+44:[ ]+28c00084[ ]+ld.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+44:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
-[ ]+48:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
+[ ]+40:[ ]+R_LARCH_GOT_PC_HI20[ ]+\.L1
+[ ]+40:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+44:[ ]+28c00084[ ]+ld\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+44:[ ]+R_LARCH_GOT_PC_LO12[ ]+\.L1
+[ ]+44:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+48:[ ]+14000004[ ]+lu12i\.w[ ]+\$a0,[ ]+0
[ ]+48:[ ]+R_LARCH_TLS_LE_HI20[ ]+TLS1
[ ]+4c:[ ]+03800084[ ]+ori[ ]+\$a0,[ ]+\$a0,[ ]+0x0
[ ]+4c:[ ]+R_LARCH_TLS_LE_LO12[ ]+TLS1
[ ]+50:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+50:[ ]+R_LARCH_TLS_IE_PC_HI20[ ]+TLS1
-[ ]+54:[ ]+28c00084[ ]+ld.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+54:[ ]+28c00084[ ]+ld\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
[ ]+54:[ ]+R_LARCH_TLS_IE_PC_LO12[ ]+TLS1
[ ]+58:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+58:[ ]+R_LARCH_TLS_LD_PC_HI20[ ]+TLS1
-[ ]+5c:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+5c:[ ]+02c00084[ ]+addi\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
[ ]+5c:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+5c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+60:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+60:[ ]+R_LARCH_TLS_GD_PC_HI20[ ]+TLS1
-[ ]+64:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+64:[ ]+02c00084[ ]+addi\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
[ ]+64:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+64:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
diff --git a/gas/testsuite/gas/loongarch/macro_op_large_abs.d b/gas/testsuite/gas/loongarch/macro_op_large_abs.d
index c3214a859e6..892d0f88b88 100644
--- a/gas/testsuite/gas/loongarch/macro_op_large_abs.d
+++ b/gas/testsuite/gas/loongarch/macro_op_large_abs.d
@@ -1,77 +1,86 @@
#as:
#objdump: -dr
-#skip: loongarch32-*-*
.*:[ ]+file format .*
Disassembly of section .text:
-00000000.* <.text>:
+00000000.* <.L1>:
[ ]+0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+0:[ ]+R_LARCH_PCALA_HI20[ ]+.text
-[ ]+4:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+4:[ ]+R_LARCH_PCALA_LO12[ ]+.text
-[ ]+8:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+8:[ ]+R_LARCH_PCALA64_LO20[ ]+.text
-[ ]+c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+c:[ ]+R_LARCH_PCALA64_HI12[ ]+.text
-[ ]+10:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+0:[ ]+R_LARCH_PCALA_HI20[ ]+\.L1
+[ ]+0:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+4:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+4:[ ]+R_LARCH_PCALA_LO12[ ]+\.L1
+[ ]+4:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+8:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
+[ ]+8:[ ]+R_LARCH_PCALA64_LO20[ ]+\.L1
+[ ]+c:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+c:[ ]+R_LARCH_PCALA64_HI12[ ]+\.L1
+[ ]+10:[ ]+00109484[ ]+add\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+14:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+14:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
-[ ]+18:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+18:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
-[ ]+1c:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+1c:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.text
-[ ]+20:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+20:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.text
-[ ]+24:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+14:[ ]+R_LARCH_GOT_PC_HI20[ ]+\.L1
+[ ]+14:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+18:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+18:[ ]+R_LARCH_GOT_PC_LO12[ ]+\.L1
+[ ]+18:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+1c:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
+[ ]+1c:[ ]+R_LARCH_GOT64_PC_LO20[ ]+\.L1
+[ ]+20:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+20:[ ]+R_LARCH_GOT64_PC_HI12[ ]+\.L1
+[ ]+24:[ ]+380c1484[ ]+ldx\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+28:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+28:[ ]+R_LARCH_PCALA_HI20[ ]+.text
-[ ]+2c:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+2c:[ ]+R_LARCH_PCALA_LO12[ ]+.text
-[ ]+30:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+30:[ ]+R_LARCH_PCALA64_LO20[ ]+.text
-[ ]+34:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+34:[ ]+R_LARCH_PCALA64_HI12[ ]+.text
-[ ]+38:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+28:[ ]+R_LARCH_PCALA_HI20[ ]+\.L1
+[ ]+28:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+2c:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+2c:[ ]+R_LARCH_PCALA_LO12[ ]+\.L1
+[ ]+2c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+30:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
+[ ]+30:[ ]+R_LARCH_PCALA64_LO20[ ]+\.L1
+[ ]+34:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+34:[ ]+R_LARCH_PCALA64_HI12[ ]+\.L1
+[ ]+38:[ ]+00109484[ ]+add\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+3c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+3c:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
-[ ]+40:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+40:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
-[ ]+44:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+44:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.text
-[ ]+48:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+48:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.text
-[ ]+4c:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
-[ ]+50:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
+[ ]+3c:[ ]+R_LARCH_GOT_PC_HI20[ ]+\.L1
+[ ]+3c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+40:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+40:[ ]+R_LARCH_GOT_PC_LO12[ ]+\.L1
+[ ]+40:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+44:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
+[ ]+44:[ ]+R_LARCH_GOT64_PC_LO20[ ]+\.L1
+[ ]+48:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+48:[ ]+R_LARCH_GOT64_PC_HI12[ ]+\.L1
+[ ]+4c:[ ]+380c1484[ ]+ldx\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+50:[ ]+14000004[ ]+lu12i\.w[ ]+\$a0,[ ]+0
[ ]+50:[ ]+R_LARCH_TLS_LE_HI20[ ]+TLS1
[ ]+54:[ ]+03800084[ ]+ori[ ]+\$a0,[ ]+\$a0,[ ]+0x0
[ ]+54:[ ]+R_LARCH_TLS_LE_LO12[ ]+TLS1
[ ]+58:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+58:[ ]+R_LARCH_TLS_IE_PC_HI20[ ]+TLS1
-[ ]+5c:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+5c:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
[ ]+5c:[ ]+R_LARCH_TLS_IE_PC_LO12[ ]+TLS1
-[ ]+60:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
+[ ]+60:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
[ ]+60:[ ]+R_LARCH_TLS_IE64_PC_LO20[ ]+TLS1
-[ ]+64:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+64:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
[ ]+64:[ ]+R_LARCH_TLS_IE64_PC_HI12[ ]+TLS1
-[ ]+68:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+68:[ ]+380c1484[ ]+ldx\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+6c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+6c:[ ]+R_LARCH_TLS_LD_PC_HI20[ ]+TLS1
-[ ]+70:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+70:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
[ ]+70:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
-[ ]+74:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
+[ ]+70:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+74:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
[ ]+74:[ ]+R_LARCH_GOT64_PC_LO20[ ]+TLS1
-[ ]+78:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+78:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
[ ]+78:[ ]+R_LARCH_GOT64_PC_HI12[ ]+TLS1
-[ ]+7c:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+7c:[ ]+00109484[ ]+add\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+80:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+80:[ ]+R_LARCH_TLS_GD_PC_HI20[ ]+TLS1
-[ ]+84:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+84:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
[ ]+84:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
-[ ]+88:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
+[ ]+84:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+88:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
[ ]+88:[ ]+R_LARCH_GOT64_PC_LO20[ ]+TLS1
-[ ]+8c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+8c:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
[ ]+8c:[ ]+R_LARCH_GOT64_PC_HI12[ ]+TLS1
-[ ]+90:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+90:[ ]+00109484[ ]+add\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
diff --git a/gas/testsuite/gas/loongarch/macro_op_large_pc.d b/gas/testsuite/gas/loongarch/macro_op_large_pc.d
index c3214a859e6..892d0f88b88 100644
--- a/gas/testsuite/gas/loongarch/macro_op_large_pc.d
+++ b/gas/testsuite/gas/loongarch/macro_op_large_pc.d
@@ -1,77 +1,86 @@
#as:
#objdump: -dr
-#skip: loongarch32-*-*
.*:[ ]+file format .*
Disassembly of section .text:
-00000000.* <.text>:
+00000000.* <.L1>:
[ ]+0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+0:[ ]+R_LARCH_PCALA_HI20[ ]+.text
-[ ]+4:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+4:[ ]+R_LARCH_PCALA_LO12[ ]+.text
-[ ]+8:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+8:[ ]+R_LARCH_PCALA64_LO20[ ]+.text
-[ ]+c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+c:[ ]+R_LARCH_PCALA64_HI12[ ]+.text
-[ ]+10:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+0:[ ]+R_LARCH_PCALA_HI20[ ]+\.L1
+[ ]+0:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+4:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+4:[ ]+R_LARCH_PCALA_LO12[ ]+\.L1
+[ ]+4:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+8:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
+[ ]+8:[ ]+R_LARCH_PCALA64_LO20[ ]+\.L1
+[ ]+c:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+c:[ ]+R_LARCH_PCALA64_HI12[ ]+\.L1
+[ ]+10:[ ]+00109484[ ]+add\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+14:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+14:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
-[ ]+18:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+18:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
-[ ]+1c:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+1c:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.text
-[ ]+20:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+20:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.text
-[ ]+24:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+14:[ ]+R_LARCH_GOT_PC_HI20[ ]+\.L1
+[ ]+14:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+18:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+18:[ ]+R_LARCH_GOT_PC_LO12[ ]+\.L1
+[ ]+18:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+1c:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
+[ ]+1c:[ ]+R_LARCH_GOT64_PC_LO20[ ]+\.L1
+[ ]+20:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+20:[ ]+R_LARCH_GOT64_PC_HI12[ ]+\.L1
+[ ]+24:[ ]+380c1484[ ]+ldx\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+28:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+28:[ ]+R_LARCH_PCALA_HI20[ ]+.text
-[ ]+2c:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+2c:[ ]+R_LARCH_PCALA_LO12[ ]+.text
-[ ]+30:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+30:[ ]+R_LARCH_PCALA64_LO20[ ]+.text
-[ ]+34:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+34:[ ]+R_LARCH_PCALA64_HI12[ ]+.text
-[ ]+38:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+28:[ ]+R_LARCH_PCALA_HI20[ ]+\.L1
+[ ]+28:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+2c:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+2c:[ ]+R_LARCH_PCALA_LO12[ ]+\.L1
+[ ]+2c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+30:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
+[ ]+30:[ ]+R_LARCH_PCALA64_LO20[ ]+\.L1
+[ ]+34:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+34:[ ]+R_LARCH_PCALA64_HI12[ ]+\.L1
+[ ]+38:[ ]+00109484[ ]+add\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+3c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+3c:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
-[ ]+40:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+40:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
-[ ]+44:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+44:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.text
-[ ]+48:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+48:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.text
-[ ]+4c:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
-[ ]+50:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
+[ ]+3c:[ ]+R_LARCH_GOT_PC_HI20[ ]+\.L1
+[ ]+3c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+40:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+40:[ ]+R_LARCH_GOT_PC_LO12[ ]+\.L1
+[ ]+40:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+44:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
+[ ]+44:[ ]+R_LARCH_GOT64_PC_LO20[ ]+\.L1
+[ ]+48:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+48:[ ]+R_LARCH_GOT64_PC_HI12[ ]+\.L1
+[ ]+4c:[ ]+380c1484[ ]+ldx\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+50:[ ]+14000004[ ]+lu12i\.w[ ]+\$a0,[ ]+0
[ ]+50:[ ]+R_LARCH_TLS_LE_HI20[ ]+TLS1
[ ]+54:[ ]+03800084[ ]+ori[ ]+\$a0,[ ]+\$a0,[ ]+0x0
[ ]+54:[ ]+R_LARCH_TLS_LE_LO12[ ]+TLS1
[ ]+58:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+58:[ ]+R_LARCH_TLS_IE_PC_HI20[ ]+TLS1
-[ ]+5c:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+5c:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
[ ]+5c:[ ]+R_LARCH_TLS_IE_PC_LO12[ ]+TLS1
-[ ]+60:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
+[ ]+60:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
[ ]+60:[ ]+R_LARCH_TLS_IE64_PC_LO20[ ]+TLS1
-[ ]+64:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+64:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
[ ]+64:[ ]+R_LARCH_TLS_IE64_PC_HI12[ ]+TLS1
-[ ]+68:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+68:[ ]+380c1484[ ]+ldx\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+6c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+6c:[ ]+R_LARCH_TLS_LD_PC_HI20[ ]+TLS1
-[ ]+70:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+70:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
[ ]+70:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
-[ ]+74:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
+[ ]+70:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+74:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
[ ]+74:[ ]+R_LARCH_GOT64_PC_LO20[ ]+TLS1
-[ ]+78:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+78:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
[ ]+78:[ ]+R_LARCH_GOT64_PC_HI12[ ]+TLS1
-[ ]+7c:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+7c:[ ]+00109484[ ]+add\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+80:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+80:[ ]+R_LARCH_TLS_GD_PC_HI20[ ]+TLS1
-[ ]+84:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
+[ ]+84:[ ]+02c00005[ ]+addi\.d[ ]+\$a1,[ ]+\$zero,[ ]+0
[ ]+84:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
-[ ]+88:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
+[ ]+84:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+88:[ ]+16000005[ ]+lu32i\.d[ ]+\$a1,[ ]+0
[ ]+88:[ ]+R_LARCH_GOT64_PC_LO20[ ]+TLS1
-[ ]+8c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
+[ ]+8c:[ ]+030000a5[ ]+lu52i\.d[ ]+\$a1,[ ]+\$a1,[ ]+0
[ ]+8c:[ ]+R_LARCH_GOT64_PC_HI12[ ]+TLS1
-[ ]+90:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+[ ]+90:[ ]+00109484[ ]+add\.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
diff --git a/gas/testsuite/gas/loongarch/relax_align.d b/gas/testsuite/gas/loongarch/relax_align.d
new file mode 100644
index 00000000000..b9ea0827da9
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax_align.d
@@ -0,0 +1,25 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <L1>:
+[ ]+0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
+[ ]+0:[ ]+R_LARCH_PCALA_HI20[ ]+L1
+[ ]+0:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+4:[ ]+02c00084[ ]+addi\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+4:[ ]+R_LARCH_PCALA_LO12[ ]+L1
+[ ]+4:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+8:[ ]+03400000[ ]+andi[ ]+\$zero,[ ]+\$zero,[ ]+0x0
+[ ]+8:[ ]+R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
+[ ]+c:[ ]+03400000[ ]+andi[ ]+\$zero,[ ]+\$zero,[ ]+0x0
+[ ]+10:[ ]+03400000[ ]+andi[ ]+\$zero,[ ]+\$zero,[ ]+0x0
+[ ]+14:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
+[ ]+14:[ ]+R_LARCH_PCALA_HI20[ ]+L1
+[ ]+14:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+18:[ ]+02c00084[ ]+addi\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
+[ ]+18:[ ]+R_LARCH_PCALA_LO12[ ]+L1
+[ ]+18:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
diff --git a/gas/testsuite/gas/loongarch/relax_align.s b/gas/testsuite/gas/loongarch/relax_align.s
new file mode 100644
index 00000000000..3880d783e79
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax_align.s
@@ -0,0 +1,5 @@
+ .text
+L1:
+ la.local $a0, L1
+ .align 4
+ la.local $a0, L1
diff --git a/gas/testsuite/gas/loongarch/uleb128.d b/gas/testsuite/gas/loongarch/uleb128.d
new file mode 100644
index 00000000000..790adf53e7f
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/uleb128.d
@@ -0,0 +1,35 @@
+#as:
+#objdump: -Dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .data:
+
+00000000.* <L1-0x5>:
+[ ]+0:[ ]+80030201[ ]+0x80030201
+[ ]+3:[ ]+R_LARCH_ADD_ULEB128[ ]+L2
+[ ]+3:[ ]+R_LARCH_SUB_ULEB128[ ]+L1
+[ ]+\.\.\.
+
+0000000000000005[ ]+<L1>:
+[ ]+\.\.\.
+[ ]+81:[ ]+ff040000[ ]+0xff040000
+[ ]+85:[ ]+cacop[ ]+0x1f,[ ]+\$t3,[ ]+1\(0x1\)
+
+0000000000000086[ ]+<L2>:
+[ ]+86:[ ]+07060005[ ]+0x07060005
+[ ]+8a:[ ]+0x00008080
+[ ]+8a:[ ]+R_LARCH_ADD_ULEB128[ ]+L4
+[ ]+8a:[ ]+R_LARCH_SUB_ULEB128[ ]+L3
+
+000000000000008d[ ]+<L3>:
+[ ]+\.\.\.
+[ ]+4089:[ ]+ff080000[ ]+0xff080000
+[ ]+408d:[ ]+0x09ffffff
+
+0000000000004090[ ]+<L4>:
+[ ]+4090:[ ]+09090909[ ]+0x09090909
+[ ]+4094:[ ]+09090909[ ]+0x09090909
+[ ]+4098:[ ]+09090909[ ]+0x09090909
+[ ]+409c:[ ]+09090909[ ]+0x09090909
diff --git a/gas/testsuite/gas/loongarch/uleb128.s b/gas/testsuite/gas/loongarch/uleb128.s
new file mode 100644
index 00000000000..104a8956bd6
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/uleb128.s
@@ -0,0 +1,20 @@
+ .data
+ .byte 1, 2, 3
+ .uleb128 L2 - L1
+L1:
+ .space 128 - 2
+ .byte 4
+ .p2align 1, 0xff
+L2:
+ .byte 5
+
+ .p2align 2
+ .byte 6, 7
+ .uleb128 L4 - L3
+L3:
+ .space 128*128 - 2
+ .byte 8
+ .p2align 2, 0xff
+L4:
+ .byte 9
+ .p2align 4, 9
--
2.36.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 6/6] LoongArch: ld: Add support for linker relaxation.
2022-12-13 6:58 [PATCH v2 0/6] LoongArch linker relaxation support mengqinggang
` (4 preceding siblings ...)
2022-12-13 6:58 ` [PATCH v2 5/6] LoongArch: gas: " mengqinggang
@ 2022-12-13 6:58 ` mengqinggang
5 siblings, 0 replies; 8+ messages in thread
From: mengqinggang @ 2022-12-13 6:58 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, liuzhensong, chenglulu, xry111, i.swmail, maskray,
schwab, mengqinggang
Add ld relax support and testsuits.
ld/ChangeLog:
* emultempl/loongarchelf.em: Regenerated.
* testsuite/ld-elf/compressed1d.d: Xfail loongarch*-*.
* testsuite/ld-elf/pr26936.d: Likewise.
* testsuite/ld-loongarch-elf/disas-jirl.d: Regenerated.
* testsuite/ld-loongarch-elf/jmp_op.d: Likewise.
* testsuite/ld-loongarch-elf/macro_op.d: Likewise.
* testsuite/ld-loongarch-elf/relax-align.dd: New test.
* testsuite/ld-loongarch-elf/relax-align.s: New test.
* testsuite/ld-loongarch-elf/relax.exp: New test.
* testsuite/ld-loongarch-elf/relax.s: New test.
* testsuite/ld-loongarch-elf/uleb128.dd: New test.
* testsuite/ld-loongarch-elf/uleb128.s: New test.
---
ld/emultempl/loongarchelf.em | 3 +
ld/testsuite/ld-elf/compressed1d.d | 3 +
ld/testsuite/ld-elf/pr26936.d | 4 +-
ld/testsuite/ld-loongarch-elf/disas-jirl.d | 4 +-
ld/testsuite/ld-loongarch-elf/jmp_op.d | 65 +++++----
ld/testsuite/ld-loongarch-elf/macro_op.d | 138 ++++++++++++-------
ld/testsuite/ld-loongarch-elf/relax-align.dd | 7 +
ld/testsuite/ld-loongarch-elf/relax-align.s | 9 ++
ld/testsuite/ld-loongarch-elf/relax.exp | 73 ++++++++++
ld/testsuite/ld-loongarch-elf/relax.s | 16 +++
ld/testsuite/ld-loongarch-elf/uleb128.dd | 10 ++
ld/testsuite/ld-loongarch-elf/uleb128.s | 21 +++
12 files changed, 276 insertions(+), 77 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align.dd
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax.exp
create mode 100644 ld/testsuite/ld-loongarch-elf/relax.s
create mode 100644 ld/testsuite/ld-loongarch-elf/uleb128.dd
create mode 100644 ld/testsuite/ld-loongarch-elf/uleb128.s
diff --git a/ld/emultempl/loongarchelf.em b/ld/emultempl/loongarchelf.em
index e9e32c5c19c..e0b0bebb003 100644
--- a/ld/emultempl/loongarchelf.em
+++ b/ld/emultempl/loongarchelf.em
@@ -23,6 +23,7 @@ fragment <<EOF
#include "ldmain.h"
#include "ldctor.h"
#include "elf/loongarch.h"
+#include "elfxx-loongarch.h"
static void
larch_elf_before_allocation (void)
@@ -61,6 +62,8 @@ gld${EMULATION_NAME}_after_allocation (void)
}
}
+ enum phase_enum *phase = &(expld.dataseg.phase);
+ bfd_elf${ELFSIZE}_loongarch_set_data_segment_info (&link_info, (int *) phase);
/* gld${EMULATION_NAME}_map_segments (need_layout); */
ldelf_map_segments (need_layout);
}
diff --git a/ld/testsuite/ld-elf/compressed1d.d b/ld/testsuite/ld-elf/compressed1d.d
index 9d891c1933f..b178695e23f 100644
--- a/ld/testsuite/ld-elf/compressed1d.d
+++ b/ld/testsuite/ld-elf/compressed1d.d
@@ -4,10 +4,13 @@
#readelf: -SW
#xfail: [uses_genelf]
#xfail: [riscv_little_endian]
+#xfail: loongarch*-*-*
# Not all ELF targets use the elf.em emulation...
# RISC-V has linker relaxations that delete code, so text label subtractions
# do not get resolved at assembly time, which results in a compressed section
# for little endian targets; but it is uncompressed for big endian targets.
+# LoongArch has linker relaxations that delete code, so text label subtractions
+# do not get resolved at assembly time, which results in a compressed section.
#failif
#...
diff --git a/ld/testsuite/ld-elf/pr26936.d b/ld/testsuite/ld-elf/pr26936.d
index c479f475829..26c80ab90dc 100644
--- a/ld/testsuite/ld-elf/pr26936.d
+++ b/ld/testsuite/ld-elf/pr26936.d
@@ -6,10 +6,10 @@
#readelf: -wL -W
#target: [check_shared_lib_support]
# Assembly source file for the HPPA assembler is renamed and modifed by
-# sed. mn10300 and riscv put different numbers of local symbols in
+# sed. loongarch and mn10300 and riscv put different numbers of local symbols in
# linkonce section and comdat sections. xtensa has more than one member
# in comdat groups.
-#xfail: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* riscv*-*-* xtensa*-*-*
+#xfail: am33_2.0-*-* hppa*-*-hpux* loongarch*-*-* mn10300-*-* riscv*-*-* xtensa*-*-*
#...
CU: .*/pr26936c.s:
diff --git a/ld/testsuite/ld-loongarch-elf/disas-jirl.d b/ld/testsuite/ld-loongarch-elf/disas-jirl.d
index 595c30c7361..eeb8dd05092 100644
--- a/ld/testsuite/ld-loongarch-elf/disas-jirl.d
+++ b/ld/testsuite/ld-loongarch-elf/disas-jirl.d
@@ -6,9 +6,11 @@
Disassembly of section .text:
-00000000.*:
+00000000.* <_start>:
[ ]+0:[ ]+1a000014[ ]+pcalau12i[ ]+\$t8,[ ]+0
[ ]+0:[ ]+R_LARCH_PCALA_HI20[ ]+_start
+[ ]+0:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+4:[ ]+02c00294[ ]+addi.d[ ]+\$t8,[ ]+\$t8,[ ]+0
[ ]+4:[ ]+R_LARCH_PCALA_LO12[ ]+_start
+[ ]+4:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+8:[ ]+4c000281[ ]+jirl[ ]+\$ra,[ ]+\$t8,[ ]+0
diff --git a/ld/testsuite/ld-loongarch-elf/jmp_op.d b/ld/testsuite/ld-loongarch-elf/jmp_op.d
index 218c13f9398..09f89100195 100644
--- a/ld/testsuite/ld-loongarch-elf/jmp_op.d
+++ b/ld/testsuite/ld-loongarch-elf/jmp_op.d
@@ -6,26 +6,45 @@
Disassembly of section .text:
-00000000.* <.text>:
-[ ]+0:[ ]+03400000[ ]+[ ]+andi[ ]+\$zero, \$zero, 0x0
-[ ]+4:[ ]+63fffc04[ ]+[ ]+blt[ ]+\$zero, \$a0, -4\(0x3fffc\)[ ]+# 0x0
-[ ]+8:[ ]+67fff880[ ]+[ ]+bge[ ]+\$a0, \$zero, -8\(0x3fff8\)[ ]+# 0x0
-[ ]+c:[ ]+67fff404[ ]+[ ]+bge[ ]+\$zero, \$a0, -12\(0x3fff4\)[ ]+# 0x0
-[ ]+10:[ ]+43fff09f[ ]+[ ]+beqz[ ]+\$a0, -16\(0x7ffff0\)[ ]+# 0x0
-[ ]+14:[ ]+47ffec9f[ ]+[ ]+bnez[ ]+\$a0, -20\(0x7fffec\)[ ]+# 0x0
-[ ]+18:[ ]+4bffe81f[ ]+[ ]+bceqz[ ]+\$fcc0, -24\(0x7fffe8\)[ ]+# 0x0
-[ ]+1c:[ ]+4bffe51f[ ]+[ ]+bcnez[ ]+\$fcc0, -28\(0x7fffe4\)[ ]+# 0x0
-[ ]+20:[ ]+4c000080[ ]+[ ]+jirl[ ]+\$zero, \$a0, 0
-[ ]+24:[ ]+53ffdfff[ ]+[ ]+b[ ]+-36\(0xfffffdc\)[ ]+# 0x0
-[ ]+28:[ ]+57ffdbff[ ]+[ ]+bl[ ]+-40\(0xfffffd8\)[ ]+# 0x0
-[ ]+2c:[ ]+5bffd485[ ]+[ ]+beq[ ]+\$a0, \$a1, -44\(0x3ffd4\)[ ]+# 0x0
-[ ]+30:[ ]+5fffd085[ ]+[ ]+bne[ ]+\$a0, \$a1, -48\(0x3ffd0\)[ ]+# 0x0
-[ ]+34:[ ]+63ffcc85[ ]+[ ]+blt[ ]+\$a0, \$a1, -52\(0x3ffcc\)[ ]+# 0x0
-[ ]+38:[ ]+63ffc8a4[ ]+[ ]+blt[ ]+\$a1, \$a0, -56\(0x3ffc8\)[ ]+# 0x0
-[ ]+3c:[ ]+67ffc485[ ]+[ ]+bge[ ]+\$a0, \$a1, -60\(0x3ffc4\)[ ]+# 0x0
-[ ]+40:[ ]+67ffc0a4[ ]+[ ]+bge[ ]+\$a1, \$a0, -64\(0x3ffc0\)[ ]+# 0x0
-[ ]+44:[ ]+6bffbc85[ ]+[ ]+bltu[ ]+\$a0, \$a1, -68\(0x3ffbc\)[ ]+# 0x0
-[ ]+48:[ ]+6bffb8a4[ ]+[ ]+bltu[ ]+\$a1, \$a0, -72\(0x3ffb8\)[ ]+# 0x0
-[ ]+4c:[ ]+6fffb485[ ]+[ ]+bgeu[ ]+\$a0, \$a1, -76\(0x3ffb4\)[ ]+# 0x0
-[ ]+50:[ ]+6fffb0a4[ ]+[ ]+bgeu[ ]+\$a1, \$a0, -80\(0x3ffb0\)[ ]+# 0x0
-[ ]+54:[ ]+4c000020[ ]+[ ]+jirl[ ]+\$zero, \$ra, 0
+00000000.* <.L1>:
+[ ]+0:[ ]+03400000[ ]+andi[ ]+\$zero,[ ]+\$zero,[ ]+0x0
+[ ]+4:[ ]+63fffc04[ ]+blt[ ]+\$zero,[ ]+\$a0,[ ]+-4\(0x3fffc\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+4:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+8:[ ]+67fff880[ ]+bge[ ]+\$a0,[ ]+\$zero,[ ]+-8\(0x3fff8\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+8:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+c:[ ]+67fff404[ ]+bge[ ]+\$zero,[ ]+\$a0,[ ]+-12\(0x3fff4\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+c:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+10:[ ]+43fff09f[ ]+beqz[ ]+\$a0,[ ]+-16\(0x7ffff0\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+10:[ ]+R_LARCH_B21[ ]+.L1
+[ ]+14:[ ]+47ffec9f[ ]+bnez[ ]+\$a0,[ ]+-20\(0x7fffec\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+14:[ ]+R_LARCH_B21[ ]+.L1
+[ ]+18:[ ]+4bffe81f[ ]+bceqz[ ]+\$fcc0,[ ]+-24\(0x7fffe8\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+18:[ ]+R_LARCH_B21[ ]+.L1
+[ ]+1c:[ ]+4bffe51f[ ]+bcnez[ ]+\$fcc0,[ ]+-28\(0x7fffe4\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+1c:[ ]+R_LARCH_B21[ ]+.L1
+[ ]+20:[ ]+4c000080[ ]+jirl[ ]+\$zero,[ ]+\$a0,[ ]+0
+[ ]+24:[ ]+53ffdfff[ ]+b[ ]+-36\(0xfffffdc\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+24:[ ]+R_LARCH_B26[ ]+.L1
+[ ]+28:[ ]+57ffdbff[ ]+bl[ ]+-40\(0xfffffd8\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+28:[ ]+R_LARCH_B26[ ]+.L1
+[ ]+2c:[ ]+5bffd485[ ]+beq[ ]+\$a0,[ ]+\$a1,[ ]+-44\(0x3ffd4\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+2c:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+30:[ ]+5fffd085[ ]+bne[ ]+\$a0,[ ]+\$a1,[ ]+-48\(0x3ffd0\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+30:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+34:[ ]+63ffcc85[ ]+blt[ ]+\$a0,[ ]+\$a1,[ ]+-52\(0x3ffcc\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+34:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+38:[ ]+63ffc8a4[ ]+blt[ ]+\$a1,[ ]+\$a0,[ ]+-56\(0x3ffc8\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+38:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+3c:[ ]+67ffc485[ ]+bge[ ]+\$a0,[ ]+\$a1,[ ]+-60\(0x3ffc4\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+3c:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+40:[ ]+67ffc0a4[ ]+bge[ ]+\$a1,[ ]+\$a0,[ ]+-64\(0x3ffc0\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+40:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+44:[ ]+6bffbc85[ ]+bltu[ ]+\$a0,[ ]+\$a1,[ ]+-68\(0x3ffbc\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+44:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+48:[ ]+6bffb8a4[ ]+bltu[ ]+\$a1,[ ]+\$a0,[ ]+-72\(0x3ffb8\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+48:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+4c:[ ]+6fffb485[ ]+bgeu[ ]+\$a0,[ ]+\$a1,[ ]+-76\(0x3ffb4\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+4c:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+50:[ ]+6fffb0a4[ ]+bgeu[ ]+\$a1,[ ]+\$a0,[ ]+-80\(0x3ffb0\)[ ]+#[ ]+0[ ]+<.L1>
+[ ]+50:[ ]+R_LARCH_B16[ ]+.L1
+[ ]+54:[ ]+4c000020[ ]+jirl[ ]+\$zero,[ ]+\$ra,[ ]+0
diff --git a/ld/testsuite/ld-loongarch-elf/macro_op.d b/ld/testsuite/ld-loongarch-elf/macro_op.d
index a1c64fcf00f..2649f63e566 100644
--- a/ld/testsuite/ld-loongarch-elf/macro_op.d
+++ b/ld/testsuite/ld-loongarch-elf/macro_op.d
@@ -6,118 +6,150 @@
Disassembly of section .text:
-00000000.* <.text>:
+00000000.* <.L1>:
[ ]+0:[ ]+00150004[ ]+move[ ]+\$a0,[ ]+\$zero
[ ]+4:[ ]+02bffc04[ ]+addi.w[ ]+\$a0,[ ]+\$zero,[ ]+-1\(0xfff\)
[ ]+8:[ ]+00150004[ ]+move[ ]+\$a0,[ ]+\$zero
[ ]+c:[ ]+02bffc04[ ]+addi.w[ ]+\$a0,[ ]+\$zero,[ ]+-1\(0xfff\)
[ ]+10:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+10:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
+[ ]+10:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+10:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+14:[ ]+28c00084[ ]+ld.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+14:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
+[ ]+14:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+14:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+18:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+18:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
+[ ]+18:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+18:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+1c:[ ]+28c00084[ ]+ld.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+1c:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
+[ ]+1c:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+1c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+20:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+20:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
+[ ]+20:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+20:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+24:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+24:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
+[ ]+24:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+24:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+28:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+28:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.text
+[ ]+28:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.L1
[ ]+2c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+2c:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.text
+[ ]+2c:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.L1
[ ]+30:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+34:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+34:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
+[ ]+34:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+34:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+38:[ ]+28c00084[ ]+ld.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+38:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
+[ ]+38:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+38:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+3c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+3c:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
+[ ]+3c:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+3c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+40:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+40:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
+[ ]+40:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+40:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+44:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+44:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.text
+[ ]+44:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.L1
[ ]+48:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+48:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.text
+[ ]+48:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.L1
[ ]+4c:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+50:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+50:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
+[ ]+50:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+50:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+54:[ ]+28c00084[ ]+ld.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+54:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
+[ ]+54:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+54:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+58:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+58:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
+[ ]+58:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+58:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+5c:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+5c:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
+[ ]+5c:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+5c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+60:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+60:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.text
+[ ]+60:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.L1
[ ]+64:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+64:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.text
+[ ]+64:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.L1
[ ]+68:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+6c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+6c:[ ]+R_LARCH_PCALA_HI20[ ]+.text
+[ ]+6c:[ ]+R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+6c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+70:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+70:[ ]+R_LARCH_PCALA_LO12[ ]+.text
+[ ]+70:[ ]+R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+70:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+74:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+74:[ ]+R_LARCH_PCALA_HI20[ ]+.text
+[ ]+74:[ ]+R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+74:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+78:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+78:[ ]+R_LARCH_PCALA_LO12[ ]+.text
+[ ]+78:[ ]+R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+78:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+7c:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+7c:[ ]+R_LARCH_PCALA64_LO20[ ]+.text
+[ ]+7c:[ ]+R_LARCH_PCALA64_LO20[ ]+.L1
[ ]+80:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+80:[ ]+R_LARCH_PCALA64_HI12[ ]+.text
+[ ]+80:[ ]+R_LARCH_PCALA64_HI12[ ]+.L1
[ ]+84:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+88:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+88:[ ]+R_LARCH_PCALA_HI20[ ]+.text
+[ ]+88:[ ]+R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+88:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+8c:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+8c:[ ]+R_LARCH_PCALA_LO12[ ]+.text
+[ ]+8c:[ ]+R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+8c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+90:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+90:[ ]+R_LARCH_PCALA_HI20[ ]+.text
+[ ]+90:[ ]+R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+90:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+94:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+94:[ ]+R_LARCH_PCALA_LO12[ ]+.text
+[ ]+94:[ ]+R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+94:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+98:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+98:[ ]+R_LARCH_PCALA64_LO20[ ]+.text
+[ ]+98:[ ]+R_LARCH_PCALA64_LO20[ ]+.L1
[ ]+9c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+9c:[ ]+R_LARCH_PCALA64_HI12[ ]+.text
+[ ]+9c:[ ]+R_LARCH_PCALA64_HI12[ ]+.L1
[ ]+a0:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+a4:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
[ ]+a4:[ ]+R_LARCH_MARK_LA[ ]+\*ABS\*
-[ ]+a4:[ ]+R_LARCH_ABS_HI20[ ]+.text
+[ ]+a4:[ ]+R_LARCH_ABS_HI20[ ]+.L1
[ ]+a8:[ ]+03800084[ ]+ori[ ]+\$a0,[ ]+\$a0,[ ]+0x0
-[ ]+a8:[ ]+R_LARCH_ABS_LO12[ ]+.text
+[ ]+a8:[ ]+R_LARCH_ABS_LO12[ ]+.L1
[ ]+ac:[ ]+16000004[ ]+lu32i.d[ ]+\$a0,[ ]+0
-[ ]+ac:[ ]+R_LARCH_ABS64_LO20[ ]+.text
+[ ]+ac:[ ]+R_LARCH_ABS64_LO20[ ]+.L1
[ ]+b0:[ ]+03000084[ ]+lu52i.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+b0:[ ]+R_LARCH_ABS64_HI12[ ]+.text
+[ ]+b0:[ ]+R_LARCH_ABS64_HI12[ ]+.L1
[ ]+b4:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+b4:[ ]+R_LARCH_PCALA_HI20[ ]+.text
+[ ]+b4:[ ]+R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+b4:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+b8:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+b8:[ ]+R_LARCH_PCALA_LO12[ ]+.text
+[ ]+b8:[ ]+R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+b8:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+bc:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+bc:[ ]+R_LARCH_PCALA_HI20[ ]+.text
+[ ]+bc:[ ]+R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+bc:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+c0:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+c0:[ ]+R_LARCH_PCALA_LO12[ ]+.text
+[ ]+c0:[ ]+R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+c0:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+c4:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+c4:[ ]+R_LARCH_PCALA_HI20[ ]+.text
+[ ]+c4:[ ]+R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+c4:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+c8:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+c8:[ ]+R_LARCH_PCALA_LO12[ ]+.text
+[ ]+c8:[ ]+R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+c8:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+cc:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+cc:[ ]+R_LARCH_PCALA64_LO20[ ]+.text
+[ ]+cc:[ ]+R_LARCH_PCALA64_LO20[ ]+.L1
[ ]+d0:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+d0:[ ]+R_LARCH_PCALA64_HI12[ ]+.text
+[ ]+d0:[ ]+R_LARCH_PCALA64_HI12[ ]+.L1
[ ]+d4:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+d8:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+d8:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
+[ ]+d8:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+d8:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+dc:[ ]+28c00084[ ]+ld.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+dc:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
+[ ]+dc:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+dc:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+e0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+e0:[ ]+R_LARCH_GOT_PC_HI20[ ]+.text
+[ ]+e0:[ ]+R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+e0:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+e4:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
-[ ]+e4:[ ]+R_LARCH_GOT_PC_LO12[ ]+.text
+[ ]+e4:[ ]+R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+e4:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+e8:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
-[ ]+e8:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.text
+[ ]+e8:[ ]+R_LARCH_GOT64_PC_LO20[ ]+.L1
[ ]+ec:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
-[ ]+ec:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.text
+[ ]+ec:[ ]+R_LARCH_GOT64_PC_HI12[ ]+.L1
[ ]+f0:[ ]+380c1484[ ]+ldx.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
[ ]+f4:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
[ ]+f4:[ ]+R_LARCH_TLS_LE_HI20[ ]+TLS1
@@ -140,10 +172,12 @@ Disassembly of section .text:
[ ]+118:[ ]+R_LARCH_TLS_LD_PC_HI20[ ]+TLS1
[ ]+11c:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
[ ]+11c:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+11c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+120:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+120:[ ]+R_LARCH_TLS_LD_PC_HI20[ ]+TLS1
[ ]+124:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
[ ]+124:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+124:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+128:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
[ ]+128:[ ]+R_LARCH_GOT64_PC_LO20[ ]+TLS1
[ ]+12c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
@@ -153,10 +187,12 @@ Disassembly of section .text:
[ ]+134:[ ]+R_LARCH_TLS_GD_PC_HI20[ ]+TLS1
[ ]+138:[ ]+02c00084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+0
[ ]+138:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+138:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+13c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
[ ]+13c:[ ]+R_LARCH_TLS_GD_PC_HI20[ ]+TLS1
[ ]+140:[ ]+02c00005[ ]+addi.d[ ]+\$a1,[ ]+\$zero,[ ]+0
[ ]+140:[ ]+R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+140:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+144:[ ]+16000005[ ]+lu32i.d[ ]+\$a1,[ ]+0
[ ]+144:[ ]+R_LARCH_GOT64_PC_LO20[ ]+TLS1
[ ]+148:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+0
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align.dd b/ld/testsuite/ld-loongarch-elf/relax-align.dd
new file mode 100644
index 00000000000..3149738ff71
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align.dd
@@ -0,0 +1,7 @@
+#...
+.*pcaddi.*
+.*pcaddi.*
+.*andi.*
+.*andi.*
+.*0:.*pcaddi.*
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align.s b/ld/testsuite/ld-loongarch-elf/relax-align.s
new file mode 100644
index 00000000000..9617c02d8e5
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align.s
@@ -0,0 +1,9 @@
+# relax-align.o has 3 andi(nop) insns.
+# relax-align has 2 andi insns, ld relax delete andi insns.
+# the last pcaddi 16 bytes align.
+ .text
+L1:
+ la.local $a0, L1
+ la.local $a0, L1
+ .align 4
+ la.local $a0, L1
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
new file mode 100644
index 00000000000..88660022613
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -0,0 +1,73 @@
+# Expect script for LoongArch ELF linker tests
+# Copyright (C) 2022 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+if [istarget loongarch*-*-*] {
+
+ set testname "loongarch relax build"
+ set pre_builds [list \
+ [list \
+ "$testname" \
+ "" \
+ "" \
+ {relax.s} \
+ {} \
+ "relax" \
+ ] \
+ ]
+
+ run_cc_link_tests $pre_builds
+
+ set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax"]
+ if { [ regexp ".*pcaddi.*pcaddi.*" $objdump_output] } {
+ pass "loongarch relax"
+ } {
+ fail "loongarch relax"
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "relax-align" \
+ "-e 0x0 -z relro" "" \
+ "" \
+ {relax-align.s} \
+ [list \
+ [list objdump -d relax-align.dd] \
+ ] \
+ "relax-align" \
+ ] \
+ ]
+
+ set objdump_flags "-s -j .data"
+ run_ld_link_tests \
+ [list \
+ [list \
+ "uleb128" \
+ "-e 0x0" "" \
+ "" \
+ {uleb128.s} \
+ [list \
+ [list objdump $objdump_flags uleb128.dd] \
+ ] \
+ "uleb128" \
+ ] \
+ ]
+}
diff --git a/ld/testsuite/ld-loongarch-elf/relax.s b/ld/testsuite/ld-loongarch-elf/relax.s
new file mode 100644
index 00000000000..2979ffa3714
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax.s
@@ -0,0 +1,16 @@
+ .data
+ .global a
+ .type a, @object
+a:
+ .word 123
+
+ .text
+ .global main
+ .type main, @function
+main:
+ la.local $a0, a
+ ld.w $a1, $a0, 0
+ la.global $a0, a
+ ld.w $a0, $a0, 0
+ sub.d $a0, $a0, $a1
+ jr $ra
diff --git a/ld/testsuite/ld-loongarch-elf/uleb128.dd b/ld/testsuite/ld-loongarch-elf/uleb128.dd
new file mode 100644
index 00000000000..c4ad3070ee1
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/uleb128.dd
@@ -0,0 +1,10 @@
+.*: .*
+
+Contents of section .*
+ [0-9a-f]+ 01020381 01000000 00000000 00000000.*
+#...
+ [0-9a-f]+ 00000004 ffff0500 06078380 01000000.*
+#...
+ [0-9a-f]+ 00000000 00000000 00000008 ffffffff.*
+ [0-9a-f]+ 09090909 09090909 09090909 09090909.*
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/uleb128.s b/ld/testsuite/ld-loongarch-elf/uleb128.s
new file mode 100644
index 00000000000..7299fb91a25
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/uleb128.s
@@ -0,0 +1,21 @@
+# From gas/all/relax.s, test ld process add_uleb128/sub_uleb128 reloc pair.
+ .data
+ .byte 1, 2, 3
+ .uleb128 L2 - L1
+L1:
+ .space 128 - 2
+ .byte 4
+ .p2align 1, 0xff
+L2:
+ .byte 5
+
+ .p2align 2
+ .byte 6, 7
+ .uleb128 L4 - L3
+L3:
+ .space 128*128 - 2
+ .byte 8
+ .p2align 2, 0xff
+L4:
+ .byte 9
+ .p2align 4, 9
--
2.36.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 3/6] LoongArch: opcodes: Add support for linker relaxation.
2022-12-13 6:58 ` [PATCH v2 3/6] LoongArch: opcodes: " mengqinggang
@ 2022-12-14 19:21 ` Hans-Peter Nilsson
0 siblings, 0 replies; 8+ messages in thread
From: Hans-Peter Nilsson @ 2022-12-14 19:21 UTC (permalink / raw)
To: mengqinggang; +Cc: binutils
On Tue, 13 Dec 2022, mengqinggang wrote:
> Set gas default to enable relax.
>
> opcodes/ChangeLog:
>
> * loongarch-opc.c (struct loongarch_ASEs_option): New member relax and
> the default value is 1.
Not that ChangeLog entries are required anymore, but seeing this
consistent formatting error hurts my nits. Here and the rest of
your patches:
ChangeLog continuation lines line up with a TAB character to the
"*" on the first line, not the text on that line. Like so:
<TAB>* loongarch-opc.c (struct ...
<TAB>the default value ...
See existing ChangeLog entries.
Also, now that I can take my eyes away from the error, I think
it's "New member relax with the default value 1" but I guess
that's more up to poetic freedom.
brgds, H-P
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-12-14 19:21 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-13 6:58 [PATCH v2 0/6] LoongArch linker relaxation support mengqinggang
2022-12-13 6:58 ` [PATCH v2 1/6] LoongArch: include: Add support for linker relaxation mengqinggang
2022-12-13 6:58 ` [PATCH v2 2/6] LoongArch: bfd: " mengqinggang
2022-12-13 6:58 ` [PATCH v2 3/6] LoongArch: opcodes: " mengqinggang
2022-12-14 19:21 ` Hans-Peter Nilsson
2022-12-13 6:58 ` [PATCH v2 4/6] LoongArch: binutils: " mengqinggang
2022-12-13 6:58 ` [PATCH v2 5/6] LoongArch: gas: " mengqinggang
2022-12-13 6:58 ` [PATCH v2 6/6] LoongArch: ld: " 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).