[lldb] Support DWARF-5 DW_FORM_line_strp (used by GCC)

LLDB has been failing on binaries produced by new GCC 11.0 with -gdwarf-5.

Differential Revision: https://reviews.llvm.org/D97721
This commit is contained in:
Jan Kratochvil 2021-03-02 15:17:23 +01:00
parent 818772a594
commit 4096ae06f4
3 changed files with 220 additions and 35 deletions

View File

@ -173,6 +173,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
break;
case DW_FORM_strp:
case DW_FORM_line_strp:
case DW_FORM_sec_offset:
data.GetU32(&offset);
break;

View File

@ -150,40 +150,40 @@ struct FormSize {
uint8_t valid:1, size:7;
};
static FormSize g_form_sizes[] = {
{0,0}, // 0x00 unused
{0,0}, // 0x01 DW_FORM_addr
{0,0}, // 0x02 unused
{0,0}, // 0x03 DW_FORM_block2
{0,0}, // 0x04 DW_FORM_block4
{1,2}, // 0x05 DW_FORM_data2
{1,4}, // 0x06 DW_FORM_data4
{1,8}, // 0x07 DW_FORM_data8
{0,0}, // 0x08 DW_FORM_string
{0,0}, // 0x09 DW_FORM_block
{0,0}, // 0x0a DW_FORM_block1
{1,1}, // 0x0b DW_FORM_data1
{1,1}, // 0x0c DW_FORM_flag
{0,0}, // 0x0d DW_FORM_sdata
{1,4}, // 0x0e DW_FORM_strp
{0,0}, // 0x0f DW_FORM_udata
{0,0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
// DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
{1,1}, // 0x11 DW_FORM_ref1
{1,2}, // 0x12 DW_FORM_ref2
{1,4}, // 0x13 DW_FORM_ref4
{1,8}, // 0x14 DW_FORM_ref8
{0,0}, // 0x15 DW_FORM_ref_udata
{0,0}, // 0x16 DW_FORM_indirect
{1,4}, // 0x17 DW_FORM_sec_offset
{0,0}, // 0x18 DW_FORM_exprloc
{1,0}, // 0x19 DW_FORM_flag_present
{0,0}, // 0x1a
{0,0}, // 0x1b
{0,0}, // 0x1c
{0,0}, // 0x1d
{0,0}, // 0x1e
{0,0}, // 0x1f
{1,8}, // 0x20 DW_FORM_ref_sig8
{0, 0}, // 0x00 unused
{0, 0}, // 0x01 DW_FORM_addr
{0, 0}, // 0x02 unused
{0, 0}, // 0x03 DW_FORM_block2
{0, 0}, // 0x04 DW_FORM_block4
{1, 2}, // 0x05 DW_FORM_data2
{1, 4}, // 0x06 DW_FORM_data4
{1, 8}, // 0x07 DW_FORM_data8
{0, 0}, // 0x08 DW_FORM_string
{0, 0}, // 0x09 DW_FORM_block
{0, 0}, // 0x0a DW_FORM_block1
{1, 1}, // 0x0b DW_FORM_data1
{1, 1}, // 0x0c DW_FORM_flag
{0, 0}, // 0x0d DW_FORM_sdata
{1, 4}, // 0x0e DW_FORM_strp
{0, 0}, // 0x0f DW_FORM_udata
{0, 0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes
// for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
{1, 1}, // 0x11 DW_FORM_ref1
{1, 2}, // 0x12 DW_FORM_ref2
{1, 4}, // 0x13 DW_FORM_ref4
{1, 8}, // 0x14 DW_FORM_ref8
{0, 0}, // 0x15 DW_FORM_ref_udata
{0, 0}, // 0x16 DW_FORM_indirect
{1, 4}, // 0x17 DW_FORM_sec_offset
{0, 0}, // 0x18 DW_FORM_exprloc
{1, 0}, // 0x19 DW_FORM_flag_present
{0, 0}, // 0x1a DW_FORM_strx (ULEB128)
{0, 0}, // 0x1b DW_FORM_addrx (ULEB128)
{1, 4}, // 0x1c DW_FORM_ref_sup4
{0, 0}, // 0x1d DW_FORM_strp_sup (4 bytes for DWARF32, 8 bytes for DWARF64)
{1, 16}, // 0x1e DW_FORM_data16
{1, 4}, // 0x1f DW_FORM_line_strp
{1, 8}, // 0x20 DW_FORM_ref_sig8
};
llvm::Optional<uint8_t>
@ -286,6 +286,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
// 32 bit for DWARF 32, 64 for DWARF 64
case DW_FORM_sec_offset:
case DW_FORM_strp:
case DW_FORM_line_strp:
*offset_ptr += 4;
return true;
@ -398,7 +399,8 @@ void DWARFFormValue::Dump(Stream &s) const {
case DW_FORM_udata:
s.PutULEB128(uvalue);
break;
case DW_FORM_strp: {
case DW_FORM_strp:
case DW_FORM_line_strp: {
const char *dbg_str = AsCString();
if (dbg_str) {
s.QuotedCString(dbg_str);
@ -606,6 +608,7 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) {
case DW_FORM_flag:
case DW_FORM_sdata:
case DW_FORM_strp:
case DW_FORM_line_strp:
case DW_FORM_strx:
case DW_FORM_strx1:
case DW_FORM_strx2:

View File

@ -0,0 +1,181 @@
# Test handling of DWARF5 DW_FORM_line_strp from .debug_info as used by GCC.
# UNSUPPORTED: system-darwin, system-windows
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -o %t -triple x86_64-pc-linux %s
# RUN: %lldb %t -o "p main" \
# RUN: -o exit | FileCheck %s
# CHECK: (void (*)()) $0 = 0x0000000000000000
.text
.Ltext0:
.globl main
.type main, @function
main:
.LFB0:
.LM1:
.long 0
.LM2:
.long 0
.LFE0:
.size main, .-main
.Letext0:
.section .debug_info,"",@progbits
.Ldebug_info0:
.long .Ldebug_info0_end - .Ldebug_info0_start # Length of Compilation Unit Info
.Ldebug_info0_start:
.value 0x5 # DWARF version number
.byte 0x1 # DW_UT_compile
.byte 0x8 # Pointer Size (in bytes)
.long .Ldebug_abbrev0 # Offset Into Abbrev. Section
.uleb128 0x1 # (DIE (0xc) DW_TAG_compile_unit)
.long .LASF2 # DW_AT_producer: "GNU C17 11.0.0 20210210 (Red Hat 11.0.0-0) -mtune=generic -march=x86-64 -gdwarf-5 -gno-as-loc-support"
.byte 0x1d # DW_AT_language
.long .LASF0 # DW_AT_name: "main.c"
.long .LASF1 # DW_AT_comp_dir: ""
.quad .Ltext0 # DW_AT_low_pc
.quad .Letext0-.Ltext0 # DW_AT_high_pc
.long .Ldebug_line0 # DW_AT_stmt_list
.uleb128 0x2 # (DIE (0x2e) DW_TAG_subprogram)
# DW_AT_external
.long .LASF3 # DW_AT_name: "main"
.byte 0x1 # DW_AT_decl_file (main.c)
.byte 0x1 # DW_AT_decl_line
.quad .LFB0 # DW_AT_low_pc
.quad .LFE0-.LFB0 # DW_AT_high_pc
.byte 0 # end of children of DIE 0xc
.Ldebug_info0_end:
.section .debug_abbrev,"",@progbits
.Ldebug_abbrev0:
.uleb128 0x1 # (abbrev code)
.uleb128 0x11 # (TAG: DW_TAG_compile_unit)
.byte 0x1 # DW_children_yes
.uleb128 0x25 # (DW_AT_producer)
.uleb128 0xe # (DW_FORM_strp)
.uleb128 0x13 # (DW_AT_language)
.uleb128 0xb # (DW_FORM_data1)
.uleb128 0x3 # (DW_AT_name)
.uleb128 0x1f # (DW_FORM_line_strp)
.uleb128 0x1b # (DW_AT_comp_dir)
.uleb128 0x1f # (DW_FORM_line_strp)
.uleb128 0x11 # (DW_AT_low_pc)
.uleb128 0x1 # (DW_FORM_addr)
.uleb128 0x12 # (DW_AT_high_pc)
.uleb128 0x7 # (DW_FORM_data8)
.uleb128 0x10 # (DW_AT_stmt_list)
.uleb128 0x17 # (DW_FORM_sec_offset)
.byte 0
.byte 0
.uleb128 0x2 # (abbrev code)
.uleb128 0x2e # (TAG: DW_TAG_subprogram)
.byte 0 # DW_children_no
.uleb128 0x3f # (DW_AT_external)
.uleb128 0x19 # (DW_FORM_flag_present)
.uleb128 0x3 # (DW_AT_name)
.uleb128 0xe # (DW_FORM_strp)
.uleb128 0x3a # (DW_AT_decl_file)
.uleb128 0xb # (DW_FORM_data1)
.uleb128 0x3b # (DW_AT_decl_line)
.uleb128 0xb # (DW_FORM_data1)
.uleb128 0x11 # (DW_AT_low_pc)
.uleb128 0x1 # (DW_FORM_addr)
.uleb128 0x12 # (DW_AT_high_pc)
.uleb128 0x7 # (DW_FORM_data8)
.byte 0
.byte 0
.uleb128 0x3 # (abbrev code)
.uleb128 0x24 # (TAG: DW_TAG_base_type)
.byte 0 # DW_children_no
.uleb128 0xb # (DW_AT_byte_size)
.uleb128 0xb # (DW_FORM_data1)
.uleb128 0x3e # (DW_AT_encoding)
.uleb128 0xb # (DW_FORM_data1)
.uleb128 0x3 # (DW_AT_name)
.uleb128 0x8 # (DW_FORM_string)
.byte 0
.byte 0
.byte 0
.section .debug_line,"",@progbits
.Ldebug_line0:
.long .LELT0-.LSLT0 # Length of Source Line Info
.LSLT0:
.value 0x5 # DWARF version number
.byte 0x8 # Address Size
.byte 0 # Segment Size
.long .LELTP0-.LASLTP0 # Prolog Length
.LASLTP0:
.byte 0x1 # Minimum Instruction Length
.byte 0x1 # Maximum Operations Per Instruction
.byte 0x1 # Default is_stmt_start flag
.byte 0xf6 # Line Base Value (Special Opcodes)
.byte 0xf2 # Line Range Value (Special Opcodes)
.byte 0xd # Special Opcode Base
.byte 0 # opcode: 0x1 has 0 args
.byte 0x1 # opcode: 0x2 has 1 args
.byte 0x1 # opcode: 0x3 has 1 args
.byte 0x1 # opcode: 0x4 has 1 args
.byte 0x1 # opcode: 0x5 has 1 args
.byte 0 # opcode: 0x6 has 0 args
.byte 0 # opcode: 0x7 has 0 args
.byte 0 # opcode: 0x8 has 0 args
.byte 0x1 # opcode: 0x9 has 1 args
.byte 0 # opcode: 0xa has 0 args
.byte 0 # opcode: 0xb has 0 args
.byte 0x1 # opcode: 0xc has 1 args
.byte 0x1 # Directory entry format count
.uleb128 0x1 # DW_LNCT_path
.uleb128 0x1f # DW_FORM_line_strp
.uleb128 0x2 # Directories count
.long .LASF1 # Directory Entry: 0: ""
.long .LASF4 # Directory Entry: 0: ""
.byte 0x2 # File name entry format count
.uleb128 0x1 # DW_LNCT_path
.uleb128 0x1f # DW_FORM_line_strp
.uleb128 0x2 # DW_LNCT_directory_index
.uleb128 0xb # DW_FORM_data1
.uleb128 0x2 # File names count
.long .LASF0 # File Entry: 0: "main.c"
.byte 0
.long .LASF5 # File Entry: 0: "main.c"
.byte 0x1
.LELTP0:
.byte 0 # set address *.LM1
.uleb128 0x9
.byte 0x2
.quad .LM1
.byte 0x1 # copy line 1
.byte 0x5 # column 12
.uleb128 0xc # 12
.byte 0 # set address *.LM2
.uleb128 0x9
.byte 0x2
.quad .LM2
.byte 0x1 # copy line 1
.byte 0x5 # column 13
.uleb128 0xd # 13
.byte 0 # set address *.Letext0
.uleb128 0x9
.byte 0x2
.quad .Letext0
.byte 0 # end sequence
.uleb128 0x1
.byte 0x1
.LELT0:
.section .debug_str,"MS",@progbits,1
.LASF2:
.string "GNU C17 11.0.0 20210210 (Red Hat 11.0.0-0) -mtune=generic -march=x86-64 -gdwarf-5 -gno-as-loc-support"
.LASF3:
.string "main"
.section .debug_line_str,"MS",@progbits,1
.LASF1:
.string ""
.LASF4:
.string ""
.LASF0:
.string "main.c"
.LASF5:
.string "main.c"
.ident "GCC: (GNU) 11.0.0 20210210 (Red Hat 11.0.0-0)"
.section .note.GNU-stack,"",@progbits