Impossible address ranges in DWARF debug info
I've been working on a tool that parses DWARF debug info embedded in WebAssembly binaries. The files I'm examining are optimized for size using wasm-opt -Oz -g. I've run into an issue where the address ranges of inlined subroutines will occasionally be impossibly large. Specifically, I'll find a DW_TAG_inlined_subroutine entry with a reasonable DW_AT_low_pc paired with a DW_AT_high_pc with a value of precisely 0x100000000. (Needless to say, the subroutine in question is not actually four gigabytes large.)
I encountered the issue on a bigger codebase, but I've narrowed it down to this simple program that reproduces the issue:
static void increment(int* array, int length) {
for (int i = 0; i < length; i++) {
array[i]++;
}
}
void _start(void) {
int array[2] = {0, 0};
increment(array, 2);
}
Compile and optimize like so:
$ clang bug.c -o bug.wasm -Oz -g --target=wasm32 -nostdlib
$ wasm-opt bug.wasm -o bug.wasm -Oz -g
The bug can be confirmed using llvm-dwarfdump:
$ llvm-dwarfdump bug.wasm --name increment
bug.wasm: file format WASM
0x00000022: DW_TAG_subprogram
DW_AT_name ("increment")
DW_AT_decl_file ("bug.c")
DW_AT_decl_line (1)
DW_AT_prototyped (true)
DW_AT_inline (DW_INL_inlined)
0x0000007c: DW_TAG_inlined_subroutine
DW_AT_abstract_origin (0x00000022 "increment")
DW_AT_low_pc (0x0000001a)
DW_AT_high_pc (0x100000000)
DW_AT_call_file ("bug.c")
DW_AT_call_line (9)
DW_AT_call_column (0x05)
I don't know the specific cause, but it only happens to code optimized by wasm-opt; clang's output is unaffected. It also only seems to affect DW_TAG_inlined_subroutine DIEs, from what I can tell.
Our DWARF support is not very robust at this time, so this is likely hitting some limitation there. In general I'd recommend using source maps for tracking debug info, as our support for that is very stable. However, if you or someone else is interested to investigate and fix issues like this, that would be welcome of course.