From 55e1609e53a42eba877462de0320a4a0c9327f76 Mon Sep 17 00:00:00 2001 From: mengqinggang Date: Fri, 2 Jun 2023 17:24:10 +0800 Subject: [PATCH] LoongArch: gas: Relocations simplification when -mno-relax Gas does not emit ADD/SUB relocation pairs for label differences when -mno-relax. --- gas/config/tc-loongarch.c | 11 ++++++++--- gas/config/tc-loongarch.h | 24 ++++++++++++++++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index c55d4ee234a..5ca9de47629 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -915,8 +915,9 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip) 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) + if (LARCH_opts.relax + && (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); @@ -1470,6 +1471,9 @@ loongarch_pre_output_hook (void) const frchainS *frch; segT s; + if (!LARCH_opts.relax) + return; + /* Save the current segment info. */ segT seg = now_seg; subsegT subseg = now_subseg; @@ -1665,7 +1669,8 @@ 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); + if (LARCH_opts.relax) + bfd_map_over_sections (stdoutput, loongarch_insert_uleb128_fixes, NULL); } void diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h index 8517bdebf13..a9f2a0a17cc 100644 --- a/gas/config/tc-loongarch.h +++ b/gas/config/tc-loongarch.h @@ -21,6 +21,8 @@ #ifndef TC_LOONGARCH #define TC_LOONGARCH +#include "opcode/loongarch.h" + #define TARGET_BYTES_BIG_ENDIAN 0 #define TARGET_ARCH bfd_arch_loongarch @@ -57,23 +59,33 @@ extern bool loongarch_frag_align_code (int); /* The following two macros let the linker resolve all the relocs due to relaxation. + This is called to see whether a reloc against a defined symbol - should be converted into a reloc against a section. */ + should be converted into a reloc against a section. + + If relax and norelax have different value may cause ld ".eh_frame_hdr + refers to overlapping FDEs" error when link relax .o and norelax .o. */ #define tc_fix_adjustable(fixp) 0 -/* The difference between same-section symbols may be affected by linker + +/* Tne difference between same-section symbols may be affected by linker relaxation, so do not resolve such expressions in the assembler. */ #define md_allow_local_subtract(l,r,s) 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 +/* Postpone text-section label subtraction calculation until linking, since + linker relaxations might change the deltas. */ #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)) + (LARCH_opts.relax ? \ + (GENERIC_FORCE_RELOCATION_SUB_SAME (FIX, SEC) \ + || ((SEC)->flags & SEC_CODE) != 0 \ + || ((SEC)->flags & SEC_DEBUGGING) != 0 \ + || TC_FORCE_RELOCATION (FIX)) \ + : (GENERIC_FORCE_RELOCATION_SUB_SAME (FIX, SEC))) \ #define TC_LINKRELAX_FIXUP(seg) ((seg->flags & SEC_CODE) \ || (seg->flags & SEC_DEBUGGING)) -- 2.30.2