https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104238
Bug ID: 104238
Summary: dwarf DW_AT_const_value causes overflow in readelf
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: debug
Assignee: unassigned at gcc dot gnu.org
Reporter: tbuyukliev at vmware dot com
Target Milestone: ---
minimal reproduction with gcc 4, 6, 9 and 12.
test.c
---
void func() {
long unsigned int var = 0x8000000000000000UL;
}
---
gcc -g -O1 -c test.c
readelf --debug-dump=info,abbrev test.o 2>&1
...
<2><4a>: Abbrev Number: 3 (DW_TAG_variable)
<4b> DW_AT_name : var
<4f> DW_AT_decl_file : 1
<50> DW_AT_decl_line : 2
<51> DW_AT_type : <0x60>
<55> DW_AT_const_value :readelf: Error: LEB value too large
-9223372036854775808
...
3 DW_TAG_variable [no children]
DW_AT_name DW_FORM_string
DW_AT_decl_file DW_FORM_data1
DW_AT_decl_line DW_FORM_data1
DW_AT_type DW_FORM_ref4
DW_AT_const_value DW_FORM_sdata
DW_AT value: 0 DW_FORM value: 0
...
i have very limited knowledge of dwarf, but i think there are two gcc problems
here.
the first problem is that the value is of signed type DW_FORM_sdata, while the
constant in the source is unsigned.
next, looking at the readelf run in gdb
#0 read_and_display_attr_value (attribute=attribute@entry=28,
form=form@entry=13, implicit_const=implicit_const@entry=-1,
start=start@entry=0x6c0680 "`",
data=0x6c06e2 "", data@entry=0x6c06d8
"\200\200\200\200\200\200\200\200\200\177", end=end@entry=0x6c06e4 "",
cu_offset=0, pointer_size=8, offset_size=4,
dwarf_version=4, debug_info_p=0x0, do_loc=0, section=0x6b7410
<debug_displays+336>, this_set=0x0, delimiter=32 ' ', level=2)
at .../src/binutils/dwarf.c:2184
...
case DW_FORM_sdata:
READ_SLEB (svalue, data, end);
uvalue = svalue;
break;
the hex bytes of data are 8080808080808080807f .
the second problem is that the above has 70 bits, instead of 64, so i agree
with the readelf error.
i think the correct value would have been 80808080808080808001.
in summary, the constant shouldn't have been treated as negative and it
shouldn't have been represented with 70 bits in LEB128.
readelf 2.34 or newer needed, as older ones don't have the "LEB value too
large" check.
the system is linux.
details about the newest gcc version i tried, but this happens on all:
gcc -v
Using built-in specs.
COLLECT_GCC=/opt/gcc-latest/bin/gcc
COLLECT_LTO_WRAPPER=/opt/gcc-latest/libexec/gcc/x86_64-pc-linux-gnu/12.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure --prefix=/opt/gcc-latest --enable-languages=c,c++
--enable-libstdcxx-debug --disable-bootstrap --disable-multilib
--disable-libvtv --with-system-zlib --without-isl --enable-multiarch
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 12.0.0 20220116 (experimental) (GCC)