diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-abbrev.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-abbrev.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-abbrev.s @@ -0,0 +1,90 @@ +## Show that llvm-dwarfdump prints a range of different structures in the +## .debug_abbrev section when requested. As well as basic cases, this test also +## shows how llvm-dwarfdump handles unknown tag, attribute and form values. + +# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o %t.o +# RUN: llvm-dwarfdump --debug-abbrev %t.o | FileCheck %s --match-full-lines + +# CHECK: .debug_abbrev contents: +# CHECK-NEXT: Abbrev table for offset: 0x00000000 +# CHECK-NEXT: [66] DW_TAG_compile_unit DW_CHILDREN_yes +# CHECK-NEXT: DW_AT_name DW_FORM_string +# CHECK-NEXT: DW_AT_stmt_list DW_FORM_data2 +# CHECK-EMPTY: +# CHECK-NEXT: [128] DW_TAG_unknown_ffff DW_CHILDREN_no +# CHECK-NEXT: DW_AT_unknown_5 DW_FORM_unknown_2 +# CHECK-EMPTY: +# CHECK-NEXT: [66] DW_TAG_unknown_4080 DW_CHILDREN_no +# CHECK-EMPTY: +# CHECK-NEXT: [1] DW_TAG_unknown_4000 DW_CHILDREN_no +# CHECK-NEXT: DW_AT_unknown_2000 DW_FORM_unknown_ffff +# CHECK-NEXT: DW_AT_unknown_3fff DW_FORM_unknown_7f +# CHECK-NEXT: DW_AT_unknown_1fff DW_FORM_block2 +# CHECK-NEXT: DW_AT_unknown_4000 DW_FORM_block4 +# CHECK-EMPTY: +# CHECK-NEXT: [2] DW_TAG_unknown_407f DW_CHILDREN_no +# CHECK-EMPTY: +# CHECK-NEXT: Abbrev table for offset: 0x00000038 +# CHECK-NEXT: [66] DW_TAG_entry_point DW_CHILDREN_no +# CHECK-NEXT: DW_AT_elemental DW_FORM_flag_present + +## All values in this assembly are intended to be arbitrary, except where +## specified. +.section .debug_abbrev,"",@progbits + .byte 0x42 ## Abbreviation Code + ## Known tag with children and known attributes and forms. + .byte 0x11 ## DW_TAG_compile_unit + .byte 0x01 ## DW_CHILDREN_yes + .byte 0x03 ## DW_AT_name + .byte 0x08 ## DW_FORM_string (valid form for DW_AT_name). + .byte 0x10 ## DW_AT_stmt_list + .byte 0x05 ## DW_FORM_data2 (invalid form for DW_AT_stmt_list). + .byte 0, 0 ## End of attributes + + ## Tag without children and reserved form/attribute values. + .byte 0x80, 0x01 ## Multi-byte Abbreviation Code + .byte 0xFF, 0xFF, 0x03 ## 0xFFFF == DW_TAG_hi_user + .byte 0x00 ## DW_CHILDREN_no + ## Reserved attribute and form. + .byte 0x05 ## Reserved DW_AT_* + .byte 0x02 ## Reserved DW_FORM_* + .byte 0, 0 ## End of attributes. + + ## Tag with no attributes. + .byte 0x42 ## Abbreviation Code (duplicate) + .byte 0x80, 0x81, 0x01 ## 0x4080 == DW_TAG_lo_user + .byte 0x00 ## DW_CHILDREN_no + .byte 0, 0 ## End of attributes. + + ## Tag with attributes/forms with unknown values/values in user-defined ranges. + .byte 0x01 ## Abbreviation Code + ## FIXME: https://bugs.llvm.org/show_bug.cgi?id=44258 means that 0x80, 0x80, 0x04 + ## results in a failure to parse correctly, whilst the following tag value is + ## interpreted incorrectly as 0x4000. + .byte 0x80, 0x80, 0x05 ## 0x10001 == DW_TAG_hi_user + 2 + .byte 0x00 ## DW_CHILDREN_no + .byte 0x80, 0x40 ## 0x2000 == DW_AT_lo_user + .byte 0xFF, 0xFF, 0x03 ## 0xFFFF == Unknown multi-byte form. + .byte 0xFF, 0x7F ## DW_AT_hi_user + .byte 0x7F ## Unknown single-byte form. + .byte 0xFF, 0x3F ## DW_AT_lo_user - 1 + .byte 0x03 ## DW_FORM_block2 + .byte 0x80, 0x80, 0x01 ## DW_AT_hi_user + 1 + .byte 0x04 ## DW_FORM_block4 + .byte 0, 0 ## End of attributes. + + ## Tag with invalid children encoding. + .byte 0x02 ## Abbreviation Code + .byte 0xFF, 0x80, 0x01 ## 0x407F == DW_TAG_lo_user - 1 + .byte 0x02 ## Invalid children encoding (interpreted as DW_CHILDREN_no). + .byte 0, 0 ## End of attributes. + + .byte 0 ## End of abbrevs. + + ## Second .debug_abbrev set. + .byte 0x42 ## Abbreviation Code (duplicate in different unit) + .byte 0x03 ## DW_TAG_entry_point + .byte 0x00 ## DW_CHILDREN_no + .byte 0x66 ## DW_AT_elemental + .byte 0x19 ## DW_FORM_flag_present + .byte 0, 0 ## End of attributes. diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-line.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-line.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-line.s @@ -0,0 +1,144 @@ +## Show that llvm-dwarfdump dumps the whole .debug_line section when +## --debug-line is specified. + +# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o %t.o +# RUN: llvm-dwarfdump --debug-line %t.o | FileCheck %s --match-full-lines + +# CHECK: .debug_line contents: +# CHECK-NEXT: debug_line[0x00000000] +# CHECK-NEXT: Line table prologue: +# CHECK-NEXT: total_length: 0x00000069 +# CHECK-NEXT: version: 5 +# CHECK-NEXT: address_size: 8 +# CHECK-NEXT: seg_select_size: 0 +# CHECK-NEXT: prologue_length: 0x0000004c +# CHECK-NEXT: min_inst_length: 1 +# CHECK-NEXT: max_ops_per_inst: 1 +# CHECK-NEXT: default_is_stmt: 1 +# CHECK-NEXT: line_base: -5 +# CHECK-NEXT: line_range: 7 +# CHECK-NEXT: opcode_base: 14 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_copy] = 0 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_advance_pc] = 1 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_advance_line] = 1 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_file] = 1 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_column] = 1 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_negate_stmt] = 0 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_basic_block] = 0 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_const_add_pc] = 0 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_prologue_end] = 0 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_isa] = 1 +# CHECK-NEXT: standard_opcode_lengths[(null)] = 0 +# CHECK-NEXT: include_directories[ 0] = "dir1/dir2" +# CHECK-NEXT: file_names[ 0]: +# CHECK-NEXT: name: "file1.c" +# CHECK-NEXT: dir_index: 2 +# CHECK-NEXT: mod_time: 0x12345678 +# CHECK-NEXT: length: 0x00000010 +# CHECK-EMPTY: +# CHECK-NEXT: Address Line Column File ISA Discriminator Flags +# CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------------- +# CHECK-NEXT: 0x0000000000000002 1 0 1 0 0 is_stmt +# CHECK-NEXT: 0x0000000000000002 1 4 3 0 0 is_stmt +# CHECK-NEXT: 0x0000000000000024 1 4 3 5 6 basic_block prologue_end epilogue_begin end_sequence +# CHECK-NEXT: debug_line[0x0000006d] +# CHECK-NEXT: Line table prologue: +# CHECK-NEXT: total_length: 0x0000001b +# CHECK-NEXT: version: 4 +# CHECK-NEXT: prologue_length: 0x00000015 +# CHECK-NEXT: min_inst_length: 2 +# CHECK-NEXT: max_ops_per_inst: 4 +# CHECK-NEXT: default_is_stmt: 0 +# CHECK-NEXT: line_base: 42 +# CHECK-NEXT: line_range: 10 +# CHECK-NEXT: opcode_base: 2 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_copy] = 42 +# CHECK-NEXT: include_directories[ 1] = "baz" +# CHECK-NEXT: file_names[ 1]: +# CHECK-NEXT: name: "foo.c" +# CHECK-NEXT: dir_index: 1 +# CHECK-NEXT: mod_time: 0x00000011 +# CHECK-NEXT: length: 0x00000022 +# CHECK-NOT: {{.}} + +.section .debug_line,"",@progbits + .long .Lunit0_end - .Lunit0_begin ## unit_length +.Lunit0_begin: + .short 5 ## version + .byte 8 ## address_size + .byte 0 ## segment_selector_size + .long .Lheader0_end - .Lheader0_begin ## header_length +.Lheader0_begin: + .byte 1 ## minimum_instruction_length + .byte 1 ## maximum_operations_per_instruction + .byte 1 ## default_is_stmt + .byte -5 ## line_base + .byte 7 ## line_range + ## Use an opcode_base > than the last standard opcode to show that unknown + ## standard opcodes can be handled. + .byte 14 ## opcode_base + .byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0 ## standard_opcode_lengths + .byte 2 ## directory_entry_format_count + ## Use two formats to show that only the path is included in the output. + .byte 0x1, 0x8 ## DW_LNCT_path, DW_FORM_string + .byte 0x4, 0x5 ## DW_LNCT_size, DW_FORM_data2 + .byte 1 ## directories_count + .asciz "dir1/dir2" ## directory entry 0 + .short 0x1234 + .byte 4 ## file_name_entry_format_count + .byte 0x4, 0x1E ## DW_LNCT_MD5, DW_FORM_data16 + .byte 0x3, 0x6 ## DW_LNCT_timestamp, DW_FORM_data4 + .byte 0x2, 0xB ## DW_LNCT_directory_index, DW_FORM_data1 + .byte 0x1, 0x8 ## DW_LNCT_path, DW_FORM_string + .byte 1 ## file_names_count + .quad 0x1111222233334444, 0x5555666677778888 ## file name entry 0 + .long 0x12345678 + .byte 2 + .asciz "file1.c" +.Lheader0_end: + .byte 0x21 ## Special opcode - shows line printed after special opcode. + .byte 0x4 ## DW_LNS_set_file - shows file can be changed to an arbitrary value. + .byte 3 + .byte 0x5 ## DW_LNS_set_column - shows column can be changed. + .byte 4 + .byte 0x1 ## DW_LNS_copy - shows line printed after copy opcode. + .byte 0x8 ## DW_LNS_const_add_pc - shows address can be changed. + .byte 0xC ## DW_LNS_set_isa - shows isa register value can be changed. + .byte 5 + .byte 0, 0x2, 0x4 ## DW_LNE_set_discriminator - shows discriminator can be changed. + .byte 6 + ## These lines all show that the printed boolean register values can be changed. + .byte 0x6 ## DW_LNS_negate_stmt + .byte 0x7 ## DW_LNS_set_basic_block + .byte 0xA ## DW_LNS_set_prologue_end + .byte 0xB ## DW_LNS_set_epilogue_begin + + .byte 0xD ## DW_LNS_unknown - shows that unknown opcodes do not affect state. + .byte 0, 0x1, 0x1 ## DW_LNE_end_sequence +.Lunit0_end: + +## Second line table program with version 4. + .long .Lunit1_end - .Lunit1_begin ## unit_length +.Lunit1_begin: + .short 4 ## version + .long .Lheader1_end - .Lheader1_begin ## header_length +.Lheader1_begin: + .byte 2 ## minimum_instruction_length + .byte 4 ## maximum_operations_per_instruction + .byte 0 ## default_is_stmt + .byte 42 ## line_base + .byte 10 ## line_range + .byte 2 ## opcode_base - lower than normal to show this can be handled. + .byte 42 ## standard_opcode_lengths - different to normal. + ## include_directories + .asciz "baz" + .byte 0 + ## file_names + .asciz "foo.c" + .byte 1 ## Directory index + .byte 0x11 ## Timestamp + .byte 0x22 ## Length +.Lheader1_end: +.Lunit1_end: diff --git a/llvm/test/tools/llvm-dwarfdump/debug-frame-dumps-eh-frame-and-debug-frame.yaml b/llvm/test/tools/llvm-dwarfdump/debug-frame-dumps-eh-frame-and-debug-frame.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/debug-frame-dumps-eh-frame-and-debug-frame.yaml @@ -0,0 +1,15 @@ +## Show that the --debug-frame switch dumps both .debug_frame and .eh_frame if +## present. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-dwarfdump --debug-frame %t | FileCheck %s + +# CHECK: .debug_frame contents: +# CHECK: .eh_frame contents: + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 diff --git a/llvm/test/tools/llvm-dwarfdump/debug-str.yaml b/llvm/test/tools/llvm-dwarfdump/debug-str.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/debug-str.yaml @@ -0,0 +1,22 @@ +## Show that llvm-dwarfdump dumps the .debug_str section when --debug-str is +## specified. + +# RUN: yaml2obj %s -o %t.o +# RUN: llvm-dwarfdump %t.o --debug-str | FileCheck %s + +# CHECK: .debug_str contents: +# CHECK-NEXT: 0x00000000: "some string" +# CHECK-NEXT: 0x0000000c: "foo" +# CHECK-NEXT: 0x00000010: "" +# CHECK-NOT: {{.}} + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .debug_str + Type: SHT_PROGBITS + Content: '736f6d6520737472696e6700666f6f0000' ## "some string\0foo\0\0"