I see it here: https://build.opensuse.org/package/show/devel:gcc/gcc11 [ 1637s] dwz: Multi-file optimization not allowed for differentpointer sizes or endianity [ 1637s] dwz: ./usr/bin/gnatfind-11-11.0.0+git181757-0.x86_64.debug: Unknown DWARF DW_OP_255 [ 1637s] dwz: ./usr/bin/gnatname-11-11.0.0+git181757-0.x86_64.debug: Unknown DWARF DW_OP_255 [ 1638s] dwz: ./usr/bin/gnatclean-11-11.0.0+git181757-0.x86_64.debug: Unknown DWARF DW_OP_255 [ 1638s] dwz: ./usr/bin/gnatls-11-11.0.0+git181757-0.x86_64.debug: Unknown DWARF DW_OP_255 [ 1638s] dwz: ./usr/bin/gnatprep-11-11.0.0+git181757-0.x86_64.debug: Unknown DWARF DW_OP_255 [ 1638s] dwz: ./usr/bin/gnatmake-11-11.0.0+git181757-0.x86_64.debug: Unknown DWARF DW_OP_255 [ 1639s] dwz: ./usr/bin/gnatchop-11-11.0.0+git181757-0.x86_64.debug: Unknown DWARF DW_OP_255 [ 1639s] dwz: ./usr/bin/gnatxref-11-11.0.0+git181757-0.x86_64.debug: Unknown DWARF DW_OP_255 [ 1797s] dwz: ./usr/lib64/libgnat-11.so-11.0.0+git181757-0.x86_64.debug: Unknown DWARF DW_OP_0
The differentpointer bug seems to be fixed already in d70cbeaa Otherwise, is e.g. readelf -wi happy with the debug info? DWARF_OP_ 0 is certainly not valid, 0xff could be valid, but it hasn't been assigned yet (and I bet we'll want to use it as a multiplexor for further ops, i.e. use 0xff followed by uleb128 extended code followed by optional operands depending on the extended code, when we run out of DW_OP_* in the user range.
(In reply to Jakub Jelinek from comment #1) > The differentpointer bug seems to be fixed already in d70cbeaa All right. > Otherwise, is e.g. readelf -wi happy with the debug info? No, it's not happy: $ readelf --debug=info ./gcc/gnatmake >/dev/null readelf: Error: ../../binutils/dwarf.c:1989: read LEB value is too large to store in destination variable Should I create an upstream GCC bug for it?
(In reply to Martin Liska from comment #2) > (In reply to Jakub Jelinek from comment #1) > > Otherwise, is e.g. readelf -wi happy with the debug info? > > No, it's not happy: > > $ readelf --debug=info ./gcc/gnatmake >/dev/null > readelf: Error: ../../binutils/dwarf.c:1989: read LEB value is too large to > store in destination variable > > Should I create an upstream GCC bug for it? Maybe, depends on how binutils readelf reads the LEB value. That warning is produced if the variable type used cannot contain the (signed) value of the (s)leb128. It might be that binutils readelf uses a too small (or signed instead of unsigned) type here. Is the gnatmake binary (or the debuginfo) available somewhere for inspection?
Created attachment 13020 [details] Binary The binary can be easily built as it's part of the GCC: $ ../configure --enable-languages=c,c++,fortran,ada --prefix=/home/marxin/bin/gcc --disable-bootstrap --disable-multilib --disable-libsanitizer $ make -j123
My local build of binutils readelf doesn't show this issue. Might it be https://sourceware.org/bugzilla/show_bug.cgi?id=26548 (which should be part of 2.35.1, but was a bug in 2.35) Also dwz gnatmake doesn't show any issues. So I assume it is an issue when doing dwz -m ?
(In reply to Mark Wielaard from comment #5) > My local build of binutils readelf doesn't show this issue. Might it be > https://sourceware.org/bugzilla/show_bug.cgi?id=26548 (which should be part > of 2.35.1, but was a bug in 2.35) It's actually the following commit: commit ef5e3e92dc7234f64e77e8c8af5d61685d96263b Author: Nick Clifton <nickc@redhat.com> Date: Tue Oct 27 16:17:13 2020 +0000 Fix the decoding of DW_FORM_ref_addr DWARF attribute. * dwarf.c (struct abbrev_list): New structure. Used to collect lists of abbreviation sets. (struct abbrev_map): New structure. Used to map CU offsets to abbreviation offsets. (record_abbrev_list): New function. A new entry to an abbreviation list. (free_all_abbrevs): Update to free abbreviation lists. (new_abbrev_list): New function. Start a new abbreviation list. (find_abbrev_list_by_abbrev_offset): New function. (find_abbrev_map_by_offset): New function. (add_abbrev): Add abbrev_list parameter. (add_abbrev_attr): Likewise. (process_abbrev_section): Rename to process_abbrev_set and add list parameter. (get_type_abbrev_from_form): New function. Attempts to decode the forms used by DW_AT_type attributes. (get_type_signedness): Display type names if operating in wide mode. Use get_type_abbrev_from_form. (read_and_display_attr_value): Use get_type_abbrev_from_form. (process_debug_info): Pre-parse the CU headers to collate all the abbrevs before starting the main scan. (process_debug_abbrev): Do not free any loaded abbrevs. (free_debug_memory): Free the abbrev maps. (cherry picked from commit bcd213b2cfbca2df53fb7e5d187fd67ea8eb7185) The commit was installed after 2.35.1 was released. > > Also dwz gnatmake doesn't show any issues. > So I assume it is an issue when doing dwz -m ? Yes, I'll attach you a file from gcc11 package build that suffers from that.
Created attachment 13021 [details] Problematic binary 2 $ cp gnatname-11-11.0.0+git181796-0.x86_64.debug 1 $ cp gnatname-11-11.0.0+git181796-0.x86_64.debug 2 $ ./dwz -m o 1 2 ./dwz: 1: Unknown DWARF DW_OP_255 ./dwz: 2: Unknown DWARF DW_OP_255 ./dwz: Too few files for multifile optimization error is reported here: #0 0x00007ffff7ea5920 in error () from /lib64/libc.so.6 #1 0x0000000000405c9b in error (__format=0x433134 "%s: Unknown DWARF %s", __errnum=0, __status=0) at /usr/include/bits/error.h:42 #2 read_exprloc (dso=0x445660, die=0x7ffff65955e0, ptr=0x7ffff7506d04 '\377' <repeats 15 times>, "\366^\n", len=16, need_adjust=0x0) at dwz.c:1844 #3 0x00000000004082d4 in checksum_die (dso=0x445660, cu=0x7ffff65951c0, top_die=0x7ffff65955e0, die=0x7ffff65955e0) at dwz.c:2717 #4 0x000000000040849a in checksum_die (dso=0x445660, cu=0x7ffff65951c0, top_die=0x0, die=0x7ffff6595220) at dwz.c:2748 #5 0x0000000000411fb7 in read_debug_info (dso=0x445660, kind=0, die_count=0x4432c0) at dwz.c:5805 #6 0x0000000000424b55 in read_dwarf (dso=0x445660, quieter=false, die_count=0x4432c0) at dwz.c:10992 #7 0x000000000042adac in dwz (file=0x7fffffffe3e1 "1", outfile=0x0, res=0x4432a0, resa=0x0, files=0x7fffffffdfd0) at dwz.c:12540 #8 0x000000000042db05 in main (argc=5, argv=0x7fffffffdfb8) at dwz.c:13562
I believe this comes from: <1><54630>: Abbrev Number: 32 (DW_TAG_subrange_type) <54631> DW_AT_lower_bound : 16 byte block: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 80 ((Unknown location op 0x0)) <54642> DW_AT_upper_bound : 16 byte block: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 7f ((User defined location op 0xff)) <54653> DW_AT_name : (indirect string, offset: 0xa6088): system__put_images__lll_integer_images__integer_typeXn <54657> DW_AT_type : <0x54660> Where it seems that gnat thinks it is emitting a "constant" defined as block, but dwz (and readelf) interpret it as expression block.
This is what eu-readelf says about the same: [ 54630] subrange_type abbrev: 32 lower_bound (block1) [ 0] ??? (0) [ 1] ??? (0) [ 2] ??? (0) [ 3] ??? (0) [ 4] ??? (0) [ 5] ??? (0) [ 6] ??? (0) [ 7] ??? (0) [ 8] ??? (0) [ 9] ??? (0) [10] ??? (0) [11] ??? (0) [12] ??? (0) [13] ??? (0) [14] ??? (0) [15] breg16 <TRUNCATED> upper_bound (block1) [ 0] lo_user+0x1f [ 1] lo_user+0x1f [ 2] lo_user+0x1f [ 3] lo_user+0x1f [ 4] lo_user+0x1f [ 5] lo_user+0x1f [ 6] lo_user+0x1f [ 7] lo_user+0x1f [ 8] lo_user+0x1f [ 9] lo_user+0x1f [10] lo_user+0x1f [11] lo_user+0x1f [12] lo_user+0x1f [13] lo_user+0x1f [14] lo_user+0x1f [15] breg15 <TRUNCATED> name (strp) "system__put_images__lll_integer_images__integer_typeXn" type (ref4) [ 54660] So this is encoded as DW_FORM_block1, which is not a valid form for DW_AT_upper_bound or DW_AT_lower_bound. According the the DWARF spec only constant, exprloc, reference classes are. Both readelfs and dwz seem to interpret this DW_FORM_block1 as an exprloc, which is arguably wrong (since DWARF4 there is DW_FORM_exprloc). In DWARF3 a DW_AT_upperbound could be represented by block, constant, reference. But then section 2.19 said: "For a block, the value is interpreted as a DWARF expression; evaluation of the expression yields the value of the attribute." In DWARF5 there is DW_FORM_data16, which could be used as a constant to express really big constants.
(In reply to Mark Wielaard from comment #9) > So this is encoded as DW_FORM_block1, which is not a valid form for > DW_AT_upper_bound or DW_AT_lower_bound. According the the DWARF spec only > constant, exprloc, reference classes are. My understanding is that this is a small extension to DWARF, because... > In DWARF5 there is DW_FORM_data16, which could be used as a constant to > express really big constants. ... there's no other way to do this in earlier versions of DWARF. I think if you use -gdwarf-5, GNAT will switch to DW_FORM_data16. I have a gdb patch to deal with this for fixed-point (not yet submitted). I haven't made gdb handle the bounds case, because gdb generally doesn't handle 128-bit types there, so it would be a much larger change.
(In reply to Tom Tromey from comment #10) > (In reply to Mark Wielaard from comment #9) > > > So this is encoded as DW_FORM_block1, which is not a valid form for > > DW_AT_upper_bound or DW_AT_lower_bound. According the the DWARF spec only > > constant, exprloc, reference classes are. > > My understanding is that this is a small extension to DWARF, because... If it is DWARF4 only, then it could be considered an extension, but if it applies to DWARF3 too, then it is certainly invalid. I don't speak Ada, do you have some minimal testcase? I've tried to write it in Fortran, but it seems to ignore it alltogether (probably a bug): integer(kind=16), parameter :: a = 18014398509481984_16 integer(kind=16), parameter :: b = a * a integer(kind=4) :: c (b : b + 32) c(b + 2) = 1 end
I am working on a workaround for DWARF4+. But the obvious one (if (cu->cu_version < 4 && form == DW_FORM_block1)) doesn't work because at least some older versions of g++ (but not gcc!?!) do emit DW_AT_location as DW_FORM_block even when emitting DWARF4, so I need to figure out which DWARF4+ blocks are really (buggy?) exprlocs and which are (extension) "constants".
I think we should just fix GCC, not add workarounds.
From DWARF POV, I think the right solution is to use DW_FORM_sdata or DW_FORM_udata depending on whether the value is signed or unsigned. Which means else /* Otherwise represent the bound as an unsigned value with the precision of its type. The precision and signedness of the type will be necessary to re-interpret it unambiguously. */ add_AT_wide (die, attr, wi::to_wide (value)); needs to be replaced by add_AT_{signed,unsigned}_wide with a new classes that will also have wide_int argument, but will emit DW_FORM_sdata or DW_FORM_udata from the wide_int, and will be able to deal with values that don't fit into HOST_WIDE_INT/unsigned HOST_WIDE_INT. On the consumer side the question is if consumers will be able to cope with such large leb128 values. Another option (for DWARF4+ or non-strict DWARF2/3) is for these large constants in attributes that interpret in DWARF3 block class as a DWARF expression to use DW_FORM_block (DW_FORM_exprloc for DWARF4/5) and in there after the uleb128 size put DW_OP_implicit_value with operands the size of the constant and the constant. Yes, it will be 3 bytes larger, but it will not be invalid for DWARF3 and very questionable extension for DWARF4+.
BTW. I was wrong about gcc/g++ emitting a DW_AT_location with DW_FORM_block for DWARF4. We have a testcase testsuite/dwz.tests/varval.S which was generated using gdb/testsuite/gdb.dwarf2/varval.exp from repo git://sourceware.org/git/binutils-gdb.git which does this. It has a special rule that says: # If FORM is 'SPECIAL_expr', then VALUE is treated as a location # expression. The effective form is then DW_FORM_block, and VALUE # is passed to the (internal) '_location' proc to be translated. # This proc implements a miniature DW_OP_ assembler. Which is obviously wrong for DWARF version 4+.
> On the consumer side the question is if consumers will be able to cope with such large leb128 values. In general no. At least elfutils and binutils only deal with max 64bit leb128 values. Both also treat the new DWARF5 DW_FORM_data16 as a block class (and not a constant class as a strict reading of the spec would imply).
For the DW_FORM_{block,exprloc} case, I'd think something like: --- gcc/dwarf2out.c 2020-12-01 14:39:32.175882586 +0100 +++ gcc/dwarf2out.c 2020-12-02 16:16:44.189189583 +0100 @@ -20780,7 +20780,14 @@ add_scalar_info (dw_die_ref die, enum dw the precision of its type. The precision and signedness of the type will be necessary to re-interpret it unambiguously. */ - add_AT_wide (die, attr, wi::to_wide (value)); + { + rtx v = immed_wide_int_const (value, TYPE_MODE (TREE_TYPE (value))); + dw_loc_descr_ref loc + = loc_descriptor (v, TYPE_MODE (TREE_TYPE (value)), + VAR_INIT_STATUS_INITIALIZED); + if (loc) + add_AT_loc (die, attr, loc); + } return; } could do it, but as I don't speak Ada I can't verify easily.
(In reply to Mark Wielaard from comment #16) > > On the consumer side the question is if consumers will be able to cope with such large leb128 values. > > In general no. At least elfutils and binutils only deal with max 64bit > leb128 values. Both also treat the new DWARF5 DW_FORM_data16 as a block > class (and not a constant class as a strict reading of the spec would imply). Strict reading of the spec says that constant class is DW_FORM_data{1,2,4,8,16}, DW_FORM_{s,u}data and DW_FORM_implicit_const, at least in DWARF5.
(In reply to Jakub Jelinek from comment #18) > (In reply to Mark Wielaard from comment #16) > > > On the consumer side the question is if consumers will be able to cope with such large leb128 values. > > > > In general no. At least elfutils and binutils only deal with max 64bit > > leb128 values. Both also treat the new DWARF5 DW_FORM_data16 as a block > > class (and not a constant class as a strict reading of the spec would imply). > > Strict reading of the spec says that constant class is > DW_FORM_data{1,2,4,8,16}, > DW_FORM_{s,u}data and DW_FORM_implicit_const, at least in DWARF5. Right, but given that most/all consumers represent constants with max 64bit signed/unsigned types, they cannot easily deal with DW_FORM_data16 or excessively large leb128 values.
(In reply to Jakub Jelinek from comment #18) > Strict reading of the spec says that constant class is > DW_FORM_data{1,2,4,8,16}, > DW_FORM_{s,u}data and DW_FORM_implicit_const, at least in DWARF5. I'd rather we not do strict readings of the spec, though, unless the strict-dwarf setting is enabled. DWARF extensibility is useful. In this case it is just for backward compatibility of some kind, since the problem is solved in DWARF 5. The problem with using sdata/udata is that it's unpredictable when a 128-bit value might be needed. This means all the readers will have to handle this at the lowest level. Using a block form avoids this, because gdb can decide at certain points to just drop things it doesn't understand. Here's the internal test case that shows the issue. A similar, but slightly different, test case is in gdb, see gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb. Anyway save this as "test_case.adb" and then do: $ gnatmake -g test_case I see the subrange DIE in the test_case.abd CU. I used today's gcc trunk. with System; procedure Test_Case is type Base_Fixed_Point_Type is delta 1.0 / 16.0 range (System.Min_Int / 2) * 1.0 / 16.0 .. (System.Max_Int / 2) * 1.0 / 16.0; subtype Fixed_Point_Subtype is Base_Fixed_Point_Type range -50.0 .. 50.0; type New_Fixed_Point_Type is new Base_Fixed_Point_Type range -50.0 .. 50.0; Base_Object : Base_Fixed_Point_Type := -50.0; Subtype_Object : Fixed_Point_Subtype := -50.0; New_Type_Object : New_Fixed_Point_Type := -50.0; begin Base_Object := 1.0/16.0; -- BREAK Subtype_Object := 1.0/16.0; end Test_Case;
My understanding is that in most cases these 128-bit subtypes with problematic DW_AT_upper_bound & DW_AT_lower_bound are useless so we could try to drop the bounds if DW_FORM_data16 is not available.
https://gcc.gnu.org/g:4ec9d0962371c134d881d7dcfcef5effc8ed847f
Although this was fixed in gcc we can make dwz more robust by not trying to interpret a block as locexpr for DWARF version 4 or higher. https://sourceware.org/pipermail/dwz/2021q1/000859.html
commit bd3c7500ef144480bff353064195212f2e330e3d Author: Mark Wielaard <mark@klomp.org> Date: Sat Feb 13 23:34:55 2021 +0100 Don't handle blocks as exprlocs for DWARF version 4 or higher. Since DWARF version 4 blocks just contain bytes, trying to interpret them as exprlocs will most likely fail. Also make sure block1 form and len are correctly passed to add_locexpr_dummy_dies. * dwz.c (add_locexpr_dummy_dies): Only handle block as exprloc for cu_version < 4. (checksum_die): Likewise. (write_die): Likewise. (read_debug_info): Get block length before calling add_locexpr_dummy_dies. https://sourceware.org/bugzilla/show_bug.cgi?id=26987