From 601c741d5ce6cae53dad8b19da8ed9c5cae4b797 Mon Sep 17 00:00:00 2001 From: mengqinggang Date: Thu, 18 Jan 2024 19:03:11 +0800 Subject: LoongArch: gas: Start a new frag after instructions that can be relaxed For R_LARCH_TLS_{LE_HI20_R,LE_ADD_R,LD_PC_HI20,GD_PC_HI20, DESC_PC_HI20} relocations, start a new frag to get correct eh_frame Call Frame Information FDE DW_CFA_advance_loc info. --- gas/config/tc-loongarch.c | 19 ++++++--- .../loongarch/relax-cfi-fde-DW_CFA_advance_loc.d | 46 ++++++++++++++++++++++ .../loongarch/relax-cfi-fde-DW_CFA_advance_loc.s | 33 ++++++++++++++++ 3 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d create mode 100644 gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index 3c7d400..e6a9901 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -1070,13 +1070,22 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip) 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))) */ + This is necessary to get correct .eh_frame FDE DW_CFA_advance_loc info. + If one cfi_insn_data's two symbols are not in the same frag, it will + generate ADD and SUB relocations pairs to calculate DW_CFA_advance_loc. + (gas/dw2gencfi.c: output_cfi_insn: + if (symbol_get_frag (to) == symbol_get_frag (from))) + + For macro instructions, only the first instruction expanded from macro + need to start a new frag. */ if (LARCH_opts.relax && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_info[0].type - || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type)) + || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_LE_ADD_R == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_info[0].type + || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_info[0].type)) { frag_wane (frag_now); frag_new (0); diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d new file mode 100644 index 0000000..367039e --- /dev/null +++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d @@ -0,0 +1,46 @@ +#as: -mrelax +#objdump: -Dr -j .eh_frame +#skip: loongarch32-*-* + +.*:[ ]+file format .* + + +Disassembly of section .eh_frame: + +[ ]*0000000000000000 <.eh_frame>: +[ ]+0:[ ]+00000014[ ]+.word[ ]+[ ]+0x00000014 +[ ]+4:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000 +[ ]+8:[ ]+00527a01[ ]+.word[ ]+[ ]+0x00527a01 +[ ]+c:[ ]+01017c01[ ]+fadd.d[ ]+\$fa1, \$fa0, \$fs7 +[ ]+10:[ ]+0c030d1b[ ]+.word[ ]+[ ]+0x0c030d1b +[ ]+14:[ ]+00000016[ ]+.word[ ]+[ ]+0x00000016 +[ ]+18:[ ]+00000034[ ]+.word[ ]+[ ]+0x00000034 +[ ]+1c:[ ]+0000001c[ ]+.word[ ]+[ ]+0x0000001c +[ ]+... +[ ]+20: R_LARCH_32_PCREL[ ]+L0\^A +[ ]+24: R_LARCH_ADD32[ ]+L0\^A +[ ]+24: R_LARCH_SUB32[ ]+L0\^A +[ ]+28:[ ]+0cd64000[ ]+.word[ ]+[ ]+0x0cd64000 +[ ]+29: R_LARCH_ADD6[ ]+L0\^A +[ ]+29: R_LARCH_SUB6[ ]+L0\^A +[ ]+2c:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016 +[ ]+2e: R_LARCH_ADD6[ ]+L0\^A +[ ]+2e: R_LARCH_SUB6[ ]+L0\^A +[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 +[ ]+33: R_LARCH_ADD6[ ]+L0\^A +[ ]+33: R_LARCH_SUB6[ ]+L0\^A +[ ]+34:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp +[ ]+38:[ ]+160cd640[ ]+lu32i.d[ ]+\$zero, 26290 +[ ]+38: R_LARCH_ADD6[ ]+L0\^A +[ ]+38: R_LARCH_SUB6[ ]+L0\^A +[ ]+3c:[ ]+0cd64000[ ]+.word[ ]+[ ]+0x0cd64000 +[ ]+3d: R_LARCH_ADD6[ ]+L0\^A +[ ]+3d: R_LARCH_SUB6[ ]+L0\^A +[ ]+40:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016 +[ ]+42: R_LARCH_ADD6[ ]+L0\^A +[ ]+42: R_LARCH_SUB6[ ]+L0\^A +[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 +[ ]+47: R_LARCH_ADD6[ ]+L0\^A +[ ]+47: R_LARCH_SUB6[ ]+L0\^A +[ ]+48:[ ]+000000d6[ ]+.word[ ]+[ ]+0x000000d6 +[ ]+4c:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000 diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s new file mode 100644 index 0000000..6e4c9b8 --- /dev/null +++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s @@ -0,0 +1,33 @@ +# Emits ADD/SUB relocations for CFA FDE DW_CFA_advance_loc with -mrelax option. +.text +.cfi_startproc + +.cfi_def_cfa 22, 0 +la.local $t0, a +.cfi_restore 22 + +.cfi_def_cfa 22, 0 +la.got $t0, a +.cfi_restore 22 + +.cfi_def_cfa 22, 0 +la.tls.ld $t0, a +.cfi_restore 22 + +.cfi_def_cfa 22, 0 +la.tls.gd $t0, a +.cfi_restore 22 + +.cfi_def_cfa 22, 0 +la.tls.desc $t0, a +.cfi_restore 22 + +.cfi_def_cfa 22, 0 +pcalau12i $t0, %le_hi20_r(a) +.cfi_restore 22 + +.cfi_def_cfa 22, 0 +add.d $t0, $tp, $t0, %le_add_r(a) +.cfi_restore 22 + +.cfi_endproc -- cgit v1.1