Bug 27215

Summary: as: Error: non-constant .uleb128 is not supported on riscv64
Product: binutils Reporter: Martin Liska <mliska>
Component: gasAssignee: Not yet assigned to anyone <unassigned>
Severity: normal CC: i, mark, maskray, ndesaulniers, nelsonc1225, vries, wilson
Priority: P2    
Version: 2.35   
Target Milestone: 2.41   
Host: Target: riscv64-*-*
Build: Last reconfirmed:

Description Martin Liska 2021-01-20 11:50:10 UTC
The following test-case comes from dwz test-suite:

$ cat repro.S
.uleb128        .Lexpr_end4 - .Lexpr_start3

$ ./gas/as-new repro.S
repro.S: Assembler messages:
repro.S:1: Error: non-constant .uleb128 is not supported

$ ./gas/as-new --version
GNU assembler (GNU Binutils)
Copyright (C) 2021 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `riscv64-linux'.
Comment 1 Andreas Schwab 2021-01-20 12:04:35 UTC
/* Parse the .sleb128 and .uleb128 pseudos.  Only allow constant expressions,
   since these directives break relaxation when used with symbol deltas.  */
Comment 2 Jim Wilson 2021-02-03 23:03:04 UTC
There is a proposal to add special relaxable relocations for uleb128 to make this work, but there were a number of problems with the initial implementation, and I haven't had a chance to look at the last implementation.  We also don't have a functioning psABI committee at the moment to deal with new relocations.

We could make this work if you disable relaxation, but that will cause code size and performance problems, and can only work properly if everything linked together was compiled with relaxation disabled, including any system libraries linked in, so this is unlikely to be feasible for most applications.  Linux kernel loadable modules are compiled this way though.  But this isn't recommended in general.
Comment 3 Tom de Vries 2021-02-26 12:00:51 UTC
Comment from dwz ml ( https://sourceware.org/pipermail/dwz/2021q1/000988.html ):
> The construct seems like it is represented by a known constant at compile time:
>         .uleb128        .Lexpr_end4 - .Lexpr_start3/* expression */ 
> .Lexpr_start3: 
>         .byte        0xf2               /* DW_OP_GNU_implicit_pointer */ 
>         .4byte        .Llabel2 
>         .sleb128        0 
> .Lexpr_end4: 
> There isn't anything between the two labels that can have a variable
> size.  So it might be a good idea to file a bug report against
> binutils as for not allowing this on riscv64.

I believe the riscv people explain it by aggressive linker optimizations
that make those not to work, but perhaps that applies to normal sections,
but don't see how can that apply to .debug* sections...
They shouldn't be doing any kind of aggressive linker relaxations on
Comment 4 Tom de Vries 2021-02-26 12:02:06 UTC
Cross-referencing gcc PR https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99090
Comment 5 Jakub Jelinek 2021-02-26 12:03:44 UTC
Any reason why at least for now you can't add partial .{s,u}leb128 support?
I.e. support non-constant .{s,u}leb128 in .debug* sections as long as it refers to .debug* section labels and not to code section?
I mean, the DWARF producers heavily rely on .debug* sections not being relaxed in any way by the linker, they can have offsets computed etc. and it isn't a normal code section.
I bet the relaxation you talk about applies to code sections, doesn't it?
Comment 6 Jim Wilson 2021-02-26 16:29:04 UTC
There is a problem if at least one label is in the text section.  So yes, we could support this for debug info sections.  On the compiler side, there is no way currently to tell the compiler that uleb128 is OK for debug section labels but not text section labels.

All targets that do linker relaxation are broken with respect to uleb128 except RISC-V.  The others just haven't noticed the problem yet.  The problem is more noticeable for RISC-V than the other targets, because we do more linker relaxation than most other targets.  See for instance https://sourceware.org/bugzilla/show_bug.cgi?id=22756#c2 for some other linker relaxation issues that are broken everywhere except RISC-V.
Comment 7 Nick Desaulniers 2022-09-26 20:52:19 UTC
Looks like this is an issue for DWARF v5 compatibility with Clang.
Comment 8 Fangrui Song 2023-11-30 16:11:06 UTC
Implemented by https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f1cd8b94e7c941c2a9107c1112ab2339916b8efd "RISC-V: Support subtraction of .uleb128." in 2023-05 (milestone: binutils 2.41).

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=2029e13917d53d2289d3ebb390c4f40bd2112d21 (2023-10) fixed cases like .word (A + 3) - (B + 2) . GCC debug info probably doesn't emit expressions like this.