The following test-case comes from dwz test-suite: $ cat repro.S .uleb128 .Lexpr_end4 - .Lexpr_start3 .Lexpr_start3: .Lexpr_end4: $ ./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) 2.36.50.20210120 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'.
/* Parse the .sleb128 and .uleb128 pseudos. Only allow constant expressions, since these directives break relaxation when used with symbol deltas. */
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 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 .debug*. ...
Cross-referencing gcc PR https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99090
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?
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.
Looks like this is an issue for DWARF v5 compatibility with Clang. https://github.com/ClangBuiltLinux/linux/issues/1719
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.