[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
  

Comments

Yu-Cheng Liang Dec. 1, 2025, 6:59 a.m. UTC | #1
On Thu, Mar 6, 2025 at 5:27 PM Yu-Cheng Liang <yclwlcy@gmail.com> wrote:
>
> 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
>
> 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\)
> + <1><[0-9a-f]+>: Abbrev Number: 0
> --
> 2.47.1

Hi Nelson,

Just a quick ping on this patch.
Let me know if you need anything from my side.

Thanks,
Yu-Cheng
  
Nelson Chu Dec. 1, 2025, 7:37 a.m. UTC | #2
Sorry I cannot approve the gdb patch and the generic change, so cc this one
to gdb mailing list.

Nelson

On Mon, Dec 1, 2025 at 2:59 PM Yu-Cheng Liang <yclwlcy@gmail.com> wrote:

> On Thu, Mar 6, 2025 at 5:27 PM Yu-Cheng Liang <yclwlcy@gmail.com> wrote:
> >
> > 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
> >
> > 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\)
> > + <1><[0-9a-f]+>: Abbrev Number: 0
> > --
> > 2.47.1
>
> Hi Nelson,
>
> Just a quick ping on this patch.
> Let me know if you need anything from my side.
>
> Thanks,
> Yu-Cheng
>
  
Yu-Cheng Liang Dec. 1, 2025, 8:37 a.m. UTC | #3
Hi Nelson,

It seems to me that this patch is related to GAS rather than GDB.
Maybe it should be forwarded to the global maintainer of binutils,
though I'm not completely sure.

Thanks,
Yu-Cheng

On Mon, Dec 1, 2025 at 3:37 PM Nelson Chu <nelson@rivosinc.com> wrote:
>
> Sorry I cannot approve the gdb patch and the generic change, so cc this one to gdb mailing list.
>
> Nelson
>
> On Mon, Dec 1, 2025 at 2:59 PM Yu-Cheng Liang <yclwlcy@gmail.com> wrote:
>>
>> On Thu, Mar 6, 2025 at 5:27 PM Yu-Cheng Liang <yclwlcy@gmail.com> wrote:
>> >
>> > 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
>> >
>> > 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\)
>> > + <1><[0-9a-f]+>: Abbrev Number: 0
>> > --
>> > 2.47.1
>>
>> Hi Nelson,
>>
>> Just a quick ping on this patch.
>> Let me know if you need anything from my side.
>>
>> Thanks,
>> Yu-Cheng
  

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\)