[v2] RISC-V: Fix incorrect DW_AT_high_pc after linker relaxation

Message ID CALWc1WBE4XcmdSU9ET2S06cVJ-Ev96qCOV_-zGCCFGV6etcYsQ@mail.gmail.com
State New
Headers
Series [v2] RISC-V: Fix incorrect DW_AT_high_pc after linker relaxation |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply

Commit Message

Yu-Cheng Liang March 6, 2025, 9:27 a.m. UTC
  Fix the issue reported in https://sourceware.org/bugzilla/show_bug.cgi?id=28878

Signed-off-by: Yu-Cheng Liang <yclwlcy@gmail.com>
---
 gas/as.c                                      |  4 +++
 gas/config/tc-riscv.c                         |  9 ++++--
 gas/config/tc-riscv.h                         |  3 ++
 gas/dwarf2dbg.c                               | 28 +++++++++++++++----
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    |  4 +++
 .../ld-riscv-elf/relax-dwarf-high-pc.s        |  6 ++++
 .../ld-riscv-elf/relax-dwarf2-high-pc.d       | 20 +++++++++++++
 .../ld-riscv-elf/relax-dwarf3-high-pc.d       | 22 +++++++++++++++
 .../ld-riscv-elf/relax-dwarf4-high-pc.d       | 22 +++++++++++++++
 .../ld-riscv-elf/relax-dwarf5-high-pc.d       | 23 +++++++++++++++
 10 files changed, 133 insertions(+), 8 deletions(-)
 create mode 100644 ld/testsuite/ld-riscv-elf/relax-dwarf-high-pc.s
 create mode 100644 ld/testsuite/ld-riscv-elf/relax-dwarf2-high-pc.d
 create mode 100644 ld/testsuite/ld-riscv-elf/relax-dwarf3-high-pc.d
 create mode 100644 ld/testsuite/ld-riscv-elf/relax-dwarf4-high-pc.d
 create mode 100644 ld/testsuite/ld-riscv-elf/relax-dwarf5-high-pc.d

+ <1><[0-9a-f]+>: Abbrev Number: 0
  

Patch

diff --git a/gas/as.c b/gas/as.c
index 449167db595..4f41029caa0 100644
--- a/gas/as.c
+++ b/gas/as.c
@@ -1464,6 +1464,10 @@  main (int argc, char ** argv)
      directives from the user or by the backend, emit it now.  */
   cfi_finish ();

+#ifdef md_insert_uleb128_fixes
+  md_insert_uleb128_fixes ();
+#endif
+
   keep_it = 0;
   if (seen_at_least_1_file ())
     {
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 493c393f5b2..9e7110bc3ef 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -5632,8 +5632,6 @@  void
 riscv_md_finish (void)
 {
   riscv_set_public_attributes ();
-  if (riscv_opts.relax)
-    bfd_map_over_sections (stdoutput, riscv_insert_uleb128_fixes, NULL);
 }

 /* Called just before the assembler exits.  */
@@ -5644,6 +5642,13 @@  riscv_md_end (void)
   htab_delete (riscv_pcrel_hi_fixup_hash);
 }

+void
+riscv_md_insert_uleb128_fixes (void)
+{
+  if (riscv_opts.relax)
+    bfd_map_over_sections (stdoutput, riscv_insert_uleb128_fixes, NULL);
+}
+
 /* Adjust the symbol table.  */

 void
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index e2e8e7af876..6363ca9a228 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -147,6 +147,9 @@  bool riscv_parse_name (const char *, struct
expressionS *, enum expr_mode);
 extern void riscv_md_finish (void);
 extern int riscv_convert_symbolic_attribute (const char *);

+#define md_insert_uleb128_fixes riscv_md_insert_uleb128_fixes
+extern void riscv_md_insert_uleb128_fixes (void);
+
 /* Set mapping symbol states.  */
 #define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
 void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index 2963e52958a..b2f62824661 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -2991,14 +2991,30 @@  out_debug_info (segT info_seg, segT
abbrev_seg, segT line_seg, segT str_seg,
    if (DWARF2_VERSION < 4)
      {
        if (size.X_op == O_constant)
- size.X_op = O_symbol;
-       size.X_add_symbol = symp;
-       emit_expr (&size, sizeof_address);
+ {
+   exp.X_op = O_symbol;
+   exp.X_add_symbol = symp;
+   exp.X_add_number = size.X_add_number;
+   emit_expr (&exp, sizeof_address);
+ }
+       else
+ {
+   exp.X_op = O_symbol;
+   exp.X_add_symbol
+       = symbol_get_value_expression (size.X_op_symbol)
+     ->X_add_symbol;
+   exp.X_add_number = 0;
+   emit_expr (&exp, sizeof_address);
+ }
      }
-   else if (size.X_op == O_constant)
-     out_uleb128 (size.X_add_number);
    else
-     emit_leb128_expr (symbol_get_value_expression (size.X_op_symbol), 0);
+     {
+       if (size.X_op == O_constant)
+ out_uleb128 (size.X_add_number);
+       else
+ emit_leb128_expr (
+     symbol_get_value_expression (size.X_op_symbol), 0);
+     }
  }

       if (DWARF2_VERSION > 2)
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 9cb847d3d8a..fb4cabfca6c 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -168,6 +168,10 @@  if [istarget "riscv*-*-*"] {
     run_dump_test "attr-phdr"
     run_dump_test "relax-max-align-gp"
     run_dump_test "relax-data-segment-align"
+    run_dump_test "relax-dwarf2-high-pc"
+    run_dump_test "relax-dwarf3-high-pc"
+    run_dump_test "relax-dwarf4-high-pc"
+    run_dump_test "relax-dwarf5-high-pc"
     run_dump_test "uleb128"
     run_dump_test "pr31179"
     run_dump_test "pr31179-r"
diff --git a/ld/testsuite/ld-riscv-elf/relax-dwarf-high-pc.s
b/ld/testsuite/ld-riscv-elf/relax-dwarf-high-pc.s
new file mode 100644
index 00000000000..c7d4143a01c
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-dwarf-high-pc.s
@@ -0,0 +1,6 @@ 
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ call _start
+ .size _start, .-_start
diff --git a/ld/testsuite/ld-riscv-elf/relax-dwarf2-high-pc.d
b/ld/testsuite/ld-riscv-elf/relax-dwarf2-high-pc.d
new file mode 100644
index 00000000000..8a3e8ddce4c
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-dwarf2-high-pc.d
@@ -0,0 +1,20 @@ 
+#source: relax-dwarf-high-pc.s
+#as: -march=rv32i --gdwarf-2
+#ld: -m[riscv_choose_ilp32_emul] -Ttext=0x1000
+#readelf: -wi
+
+Contents of the .debug_info section:
+
+ +Compilation Unit @ offset (0x)?0:
+ +Length: .*
+ +Version: +2
+ +Abbrev Offset: +(0x)?0
+ +Pointer Size: .*
+ <0><[0-9a-f]+>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
+#...
+ <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\)
+ +<[0-9a-f]+> +DW_AT_name +: \(indirect string, offset:
(0x)?[0-9a-f]+\): _start
+ +<[0-9a-f]+> +DW_AT_external +: 1
+ +<[0-9a-f]+> +DW_AT_low_pc +: 0x1000
+ +<[0-9a-f]+> +DW_AT_high_pc +: 0x1004
+ <1><[0-9a-f]+>: Abbrev Number: 0
diff --git a/ld/testsuite/ld-riscv-elf/relax-dwarf3-high-pc.d
b/ld/testsuite/ld-riscv-elf/relax-dwarf3-high-pc.d
new file mode 100644
index 00000000000..7252fa2b68b
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-dwarf3-high-pc.d
@@ -0,0 +1,22 @@ 
+#source: relax-dwarf-high-pc.s
+#as: -march=rv32i --gdwarf-3
+#ld: -m[riscv_choose_ilp32_emul] -Ttext=0x1000
+#readelf: -wi
+
+Contents of the .debug_info section:
+
+ +Compilation Unit @ offset (0x)?0:
+ +Length: .*
+ +Version: +3
+ +Abbrev Offset: +(0x)?0
+ +Pointer Size: .*
+ <0><[0-9a-f]+>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
+#...
+ <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\)
+ +<[0-9a-f]+> +DW_AT_name +: \(indirect string, offset:
(0x)?[0-9a-f]+\): _start
+ +<[0-9a-f]+> +DW_AT_external +: 1
+ +<[0-9a-f]+> +DW_AT_type +: <0x[0-9a-f]+>
+ +<[0-9a-f]+> +DW_AT_low_pc +: 0x1000
+ +<[0-9a-f]+> +DW_AT_high_pc +: 0x1004
+ <1><[0-9a-f]+>: Abbrev Number: 3 \(DW_TAG_unspecified_type\)
+ <1><[0-9a-f]+>: Abbrev Number: 0
diff --git a/ld/testsuite/ld-riscv-elf/relax-dwarf4-high-pc.d
b/ld/testsuite/ld-riscv-elf/relax-dwarf4-high-pc.d
new file mode 100644
index 00000000000..d364bf28cd0
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-dwarf4-high-pc.d
@@ -0,0 +1,22 @@ 
+#source: relax-dwarf-high-pc.s
+#as: -march=rv32i --gdwarf-4
+#ld: -m[riscv_choose_ilp32_emul] -Ttext=0x1000
+#readelf: -wi
+
+Contents of the .debug_info section:
+
+ +Compilation Unit @ offset (0x)?0:
+ +Length: .*
+ +Version: +4
+ +Abbrev Offset: +(0x)?0
+ +Pointer Size: .*
+ <0><[0-9a-f]+>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
+#...
+ <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\)
+ +<[0-9a-f]+> +DW_AT_name +: \(indirect string, offset:
(0x)?[0-9a-f]+\): _start
+ +<[0-9a-f]+> +DW_AT_external +: 1
+ +<[0-9a-f]+> +DW_AT_type +: <0x[0-9a-f]+>
+ +<[0-9a-f]+> +DW_AT_low_pc +: 0x1000
+ +<[0-9a-f]+> +DW_AT_high_pc +: 4
+ <1><[0-9a-f]+>: Abbrev Number: 3 \(DW_TAG_unspecified_type\)
+ <1><[0-9a-f]+>: Abbrev Number: 0
diff --git a/ld/testsuite/ld-riscv-elf/relax-dwarf5-high-pc.d
b/ld/testsuite/ld-riscv-elf/relax-dwarf5-high-pc.d
new file mode 100644
index 00000000000..eaf0ded2ecf
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-dwarf5-high-pc.d
@@ -0,0 +1,23 @@ 
+#source: relax-dwarf-high-pc.s
+#as: -march=rv32i --gdwarf-5
+#ld: -m[riscv_choose_ilp32_emul] -Ttext=0x1000
+#readelf: -wi
+
+Contents of the .debug_info section:
+
+ +Compilation Unit @ offset (0x)?0:
+ +Length: .*
+ +Version: +5
+ +Unit Type: +DW_UT_compile \(1\)
+ +Abbrev Offset: +(0x)?0
+ +Pointer Size: .*
+ <0><[0-9a-f]+>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
+#...
+ <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\)
+ +<[0-9a-f]+> +DW_AT_name +: \(indirect string, offset:
(0x)?[0-9a-f]+\): _start
+ +<[0-9a-f]+> +DW_AT_external +: 1
+ +<[0-9a-f]+> +DW_AT_type +: <0x[0-9a-f]+>
+ +<[0-9a-f]+> +DW_AT_low_pc +: 0x1000
+ +<[0-9a-f]+> +DW_AT_high_pc +: 4
+ <1><[0-9a-f]+>: Abbrev Number: 3 \(DW_TAG_unspecified_type\)