LLVM/GNU binutils interop: non-constant .uleb128 is not supported
ConchuOD opened this issue · 18 comments
Looks like this may be a gas issue that has been fixed, but idk what the gnu toolchain lads do by way of backporting.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91602#c16
Seems like the fix was for GCC to do configure time checking of GAS' capabilities. We don't have such luxury when building clang itself; we probably need some kind of as-option
check for this and see if we can get clang to disable emitting these directives when LLVM_IAS=0.
Seems like the fix was for GCC to do configure time checking of GAS' capabilities. We don't have such luxury when building clang itself; we probably need some kind of
as-option
check for this and see if we can get clang to disable emitting these directives when LLVM_IAS=0.
I'll take your word for it! I mentioned backporting as I could not repro with newer versions of binutils.
This is reproducible with binutils master, which appears not to have support for non-constant .uleb128
or .sleb128
.
$ sed -n '4427,4440p' gas/config/tc-riscv.c
static void
s_riscv_leb128 (int sign)
{
expressionS exp;
char *save_in = input_line_pointer;
expression (&exp);
if (exp.X_op != O_constant)
as_bad (_("non-constant .%cleb128 is not supported"), sign ? 's' : 'u');
demand_empty_rest_of_line ();
input_line_pointer = save_in;
return s_leb128 (sign);
}
It looks like the .uleb128
comes from debug info? If I manually generate arch/riscv/kernel/vdso/vgettimeofday.s
from arch/riscv/kernel/vdso/vgettimeofday.c
using -fverbose-asm -S
, I see:
...
.Ldebug_loc0:
.byte 4 # DW_LLE_offset_pair
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
.byte 1 # Loc expr size
.byte 90 # DW_OP_reg10
.byte 0 # DW_LLE_end_of_list
.Ldebug_loc1:
.byte 4 # DW_LLE_offset_pair
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
.byte 1 # Loc expr size
.byte 91 # DW_OP_reg11
.byte 0 # DW_LLE_end_of_list
.Ldebug_loc2:
.byte 4 # DW_LLE_offset_pair
.uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
.byte 1 # Loc expr size
.byte 90 # DW_OP_reg10
.byte 0 # DW_LLE_end_of_list
.Ldebug_loc3:
.byte 4 # DW_LLE_offset_pair
.uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
.byte 1 # Loc expr size
.byte 91 # DW_OP_reg11
.byte 0 # DW_LLE_end_of_list
...
.Ldebug_ranges0:
.byte 4 # DW_RLE_offset_pair
.uleb128 .Ltmp6-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp27-.Lfunc_begin0 # ending offset
.byte 4 # DW_RLE_offset_pair
.uleb128 .Ltmp28-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp30-.Lfunc_begin0 # ending offset
.byte 0 # DW_RLE_end_of_list
.Ldebug_ranges1:
.byte 4 # DW_RLE_offset_pair
.uleb128 .Ltmp6-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp27-.Lfunc_begin0 # ending offset
.byte 4 # DW_RLE_offset_pair
.uleb128 .Ltmp28-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp30-.Lfunc_begin0 # ending offset
.byte 0 # DW_RLE_end_of_list
.Ldebug_ranges2:
.byte 4 # DW_RLE_offset_pair
.uleb128 .Ltmp6-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp16-.Lfunc_begin0 # ending offset
.byte 4 # DW_RLE_offset_pair
.uleb128 .Ltmp17-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp22-.Lfunc_begin0 # ending offset
.byte 4 # DW_RLE_offset_pair
.uleb128 .Ltmp25-.Lfunc_begin0 # starting offset
.uleb128 .Ltmp27-.Lfunc_begin0 # ending offset
.byte 0 # DW_RLE_end_of_list
...
Which seems to correspond to
https://github.com/llvm/llvm-project/blob/c418f00536001169f40d09bf3bff568aacfc9c30/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp#L303-L307
https://github.com/llvm/llvm-project/blob/bc13437b156abc41f835a6a3ef5efb571b815872/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp#L2797-L2803
I guess we could just restrict CONFIG_DEBUG_INFO_DWARF5
to require the integrated assembler when building with clang
to workaround this?
I was sure tried 2.37 & 2.38 before 2.35.2 and could not repro it there.. Consider me very confused now as to what I actually tested!
I guess we could just restrict CONFIG_DEBUG_INFO_DWARF5 to require the integrated assembler when building with clang to workaround this?
Do you even have another option?
Looks like there's an open bug report for this against GNU binutils.
https://sourceware.org/bugzilla/show_bug.cgi?id=27215
I guess we could just restrict CONFIG_DEBUG_INFO_DWARF5 to require the integrated assembler when building with clang to workaround this?
and just for riscv. Or use as-instr
.
Or use
as-instr
.
Ah, great idea, especially with Martin's reproducer from the binutils issue. Something like the following, perhaps?
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index d3e5f36bb01e..77bc73d0d8dc 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -231,6 +231,9 @@ config DEBUG_INFO
in the "Debug information" choice below, indicating that debug
information will be generated for build targets.
+config AS_HAS_NON_CONST_LEB128
+ def_bool $(as-instr,.uleb128 .Lexpr_end4 - .Lexpr_start3\n.Lexpr_start3:\n.Lexpr_end4:)
+
choice
prompt "Debug information"
depends on DEBUG_KERNEL
@@ -276,7 +279,7 @@ config DEBUG_INFO_DWARF4
config DEBUG_INFO_DWARF5
bool "Generate DWARF Version 5 debuginfo"
select DEBUG_INFO
- depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)))
+ depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)) && AS_HAS_NON_CONST_LEB128)
help
Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc
5.0+ accepts the -gdwarf-5 flag but only had partial support for some
The above works, but maybe the line length could do with some improvement!
Something like the following, perhaps?
Maybe add another depends on line, and make it riscv specific?
Maybe add another depends on line, and make it riscv specific?
I can move it to a different depends on
line (although that unnecessarily applies this restriction to GCC, which clearly does not have this issue) but I don't really see the point in special casing RISC-V here. CONFIG_AS_HAS_NON_CONST_LEB128
should be true for every other architecture so there is not much point in limiting its scope.
Maybe add another depends on line, and make it riscv specific?
I can move it to a different
depends on
line (although that unnecessarily applies this restriction to GCC, which clearly does not have this issue) but I don't really see the point in special casing RISC-V here.CONFIG_AS_HAS_NON_CONST_LEB128
should be true for every other architecture so there is not much point in limiting its scope.
Is there something that prevents you from also starting the second depends on line with a !GCC ?
No, I am sure this would work just fine:
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index d3e5f36bb01e..19de03ead2ed 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -231,6 +231,9 @@ config DEBUG_INFO
in the "Debug information" choice below, indicating that debug
information will be generated for build targets.
+config AS_HAS_NON_CONST_LEB128
+ def_bool $(as-instr,.uleb128 .Lexpr_end4 - .Lexpr_start3\n.Lexpr_start3:\n.Lexpr_end4:)
+
choice
prompt "Debug information"
depends on DEBUG_KERNEL
@@ -277,6 +280,10 @@ config DEBUG_INFO_DWARF5
bool "Generate DWARF Version 5 debuginfo"
select DEBUG_INFO
depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)))
+ # Clang is known to generate .{s,u}leb128 with symbol deltas with
+ # DWARF5, which some targets may not support.
+ # https://sourceware.org/bugzilla/show_bug.cgi?id=27215
+ depends on !CC_IS_CLANG || AS_HAS_NON_CONST_LEB128
help
Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc
5.0+ accepts the -gdwarf-5 flag but only had partial support for some
No, I am sure this would work just fine:
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index d3e5f36bb01e..19de03ead2ed 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -231,6 +231,9 @@ config DEBUG_INFO in the "Debug information" choice below, indicating that debug information will be generated for build targets. +config AS_HAS_NON_CONST_LEB128 + def_bool $(as-instr,.uleb128 .Lexpr_end4 - .Lexpr_start3\n.Lexpr_start3:\n.Lexpr_end4:) + choice prompt "Debug information" depends on DEBUG_KERNEL @@ -277,6 +280,10 @@ config DEBUG_INFO_DWARF5 bool "Generate DWARF Version 5 debuginfo" select DEBUG_INFO depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502))) + # Clang is known to generate .{s,u}leb128 with symbol deltas with + # DWARF5, which some targets may not support. + # https://sourceware.org/bugzilla/show_bug.cgi?id=27215 + depends on !CC_IS_CLANG || AS_HAS_NON_CONST_LEB128 help Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc 5.0+ accepts the -gdwarf-5 flag but only had partial support for some
This looks good to me! Feel free to submit with a:
Tested-by: Conor Dooley conor.dooley@microchip.com
Patch submitted: https://lore.kernel.org/20220928182523.3105953-1-nathan@kernel.org/
I have requested a backport to 5.15, 5.19, and 6.0: https://lore.kernel.org/Y02WW7iIeWPFTV8L@dev-arch.thelio-3990X/