LoongArch: gas: Relocations simplification when -mno-relax
authormengqinggang <mengqinggang@loongson.cn>
Fri, 2 Jun 2023 09:24:10 +0000 (17:24 +0800)
committerliuzhensong <liuzhensong@loongson.cn>
Mon, 12 Jun 2023 01:30:48 +0000 (09:30 +0800)
  Gas does not emit ADD/SUB relocation pairs for label differences
  when -mno-relax.

gas/config/tc-loongarch.c
gas/config/tc-loongarch.h

index c55d4ee234aa2652d2c07939440430f25e05849f..5ca9de47629491bfb799f6b71eb58abd1279baea 100644 (file)
@@ -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
index 8517bdebf138ff6edf6153621a57a993b2bfa2d9..a9f2a0a17cc987a52c9e15a555356828db9ce481 100644 (file)
@@ -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))