Index: include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -58,12 +58,13 @@ public: /// Print the location lists found within the debug_loc section. - void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo) const; + void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, + Optional Offset) const; /// Parse the debug_loc section accessible via the 'data' parameter using the /// address size also given in 'data' to interpret the address ranges. void parse(const DWARFDataExtractor &data); - + Optional parseOneLocationList(DWARFDataExtractor Data, uint32_t *Offset); }; @@ -94,7 +95,8 @@ public: void parse(DataExtractor data); - void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo) const; + void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, + Optional Offset) const; static Optional parseOneLocationList(DataExtractor Data, uint32_t *Offset); Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -291,11 +291,11 @@ if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc, DObj->getLocSection().Data)) { - getDebugLoc()->dump(OS, getRegisterInfo()); + getDebugLoc()->dump(OS, getRegisterInfo(), DumpOffset); } if (shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc, DObj->getLocDWOSection().Data)) { - getDebugLocDWO()->dump(OS, getRegisterInfo()); + getDebugLocDWO()->dump(OS, getRegisterInfo(), DumpOffset); } if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, Index: lib/DebugInfo/DWARF/DWARFDebugLoc.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -50,8 +50,11 @@ } } -void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI) const { +void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, + Optional Offset) const { for (const LocationList &L : Locations) { + if (Offset && L.Offset != *Offset) + continue; OS << format("0x%8.8x: ", L.Offset); L.dump(OS, IsLittleEndian, AddressSize, MRI, 12); OS << "\n\n"; @@ -173,8 +176,11 @@ } } -void DWARFDebugLocDWO::dump(raw_ostream &OS, const MCRegisterInfo *MRI) const { +void DWARFDebugLocDWO::dump(raw_ostream &OS, const MCRegisterInfo *MRI, + Optional Offset) const { for (const LocationList &L : Locations) { + if (Offset && L.Offset != *Offset) + continue; OS << format("0x%8.8x: ", L.Offset); L.dump(OS, IsLittleEndian, AddressSize, MRI, /*Indent=*/12); OS << "\n\n"; Index: test/tools/llvm-dwarfdump/X86/debug_loc_offset.test =================================================================== --- /dev/null +++ test/tools/llvm-dwarfdump/X86/debug_loc_offset.test @@ -0,0 +1,17 @@ +RUN: llvm-mc %S/debugloc.s -filetype obj -triple x86_64-linux-elf -o - \ +RUN: | llvm-dwarfdump --debug-loc=0 - \ +RUN: | FileCheck %s --check-prefix=CHECK-A + +# CHECK-A: 0x00000000: +# CHECK-A-NEXT: 0x0000000000000011 - 0x0000000000000025: DW_OP_consts +0, DW_OP_stack_value +# CHECK-A-NEXT: 0x0000000000000025 - 0x000000000000002e: DW_OP_breg5 RDI+0 +# CHECK-A-NEXT: 0x0000000000000037 - 0x000000000000003a: DW_OP_reg0 RAX, DW_OP_piece 0x4 + +RUN: llvm-mc %S/debugloc.s -filetype obj -triple x86_64-linux-elf -o - \ +RUN: | llvm-dwarfdump --debug-loc=0x4e - \ +RUN: | FileCheck %s --check-prefix=CHECK-B + +# CHECK-B: 0x0000004e: +# CHECK-B-NEXT: 0x0000000000000019 - 0x000000000000002e: DW_OP_consts +0, DW_OP_stack_value +# CHECK-B-NEXT: 0x000000000000002e - 0x000000000000003c: DW_OP_breg5 RDI+0 + Index: test/tools/llvm-dwarfdump/X86/debugloc.s =================================================================== --- /dev/null +++ test/tools/llvm-dwarfdump/X86/debugloc.s @@ -0,0 +1,353 @@ +# RUN: llvm-mc %s -filetype obj -triple x86_64-linux-elf -o - \ +# RUN: | llvm-dwarfdump --debug-loc - \ +# RUN: | FileCheck %s + +# CHECK: .debug_loc contents: + +# CHECK: 0x00000000: +# CHECK-NEXT: 0x0000000000000011 - 0x0000000000000025: DW_OP_consts +0, DW_OP_stack_value +# CHECK-NEXT: 0x0000000000000025 - 0x000000000000002e: DW_OP_breg5 RDI+0 +# CHECK-NEXT: 0x0000000000000037 - 0x000000000000003a: DW_OP_reg0 RAX, DW_OP_piece 0x4 + +# CHECK: 0x0000004e: +# CHECK-NEXT: 0x0000000000000019 - 0x000000000000002e: DW_OP_consts +0, DW_OP_stack_value +# CHECK-NEXT: 0x000000000000002e - 0x000000000000003c: DW_OP_breg5 RDI+0 + + .text + .file "debugloc.c" + .globl foo + .align 16, 0x90 + .type foo,@function +foo: # @foo +.Lfunc_begin0: + .file 1 "debugloc.c" + .loc 1 1 0 # debugloc.c:1:0 + .cfi_startproc +# BB#0: + #DEBUG_VALUE: foo:i <- %RDI + .loc 1 2 6 prologue_end # debugloc.c:2:6 + incl (%rdi) + .loc 1 3 1 # debugloc.c:3:1 + retq +.Ltmp0: +.Lfunc_end0: + .size foo, .Lfunc_end0-foo + .cfi_endproc + + .globl main + .align 16, 0x90 + .type main,@function +main: # @main +.Lfunc_begin1: + .loc 1 5 0 # debugloc.c:5:0 + .cfi_startproc +# BB#0: + .loc 1 6 7 prologue_end # debugloc.c:6:7 + pushq %rax +.Ltmp1: + .cfi_def_cfa_offset 16 +.Ltmp2: + #DEBUG_VALUE: main:i <- 0 + movl $0, 4(%rsp) +.Ltmp3: + #DEBUG_VALUE: main:j <- 0 + .loc 1 7 7 # debugloc.c:7:7 + movl $0, (%rsp) + leaq 4(%rsp), %rdi +.Ltmp4: + #DEBUG_VALUE: main:i <- [%RDI+0] + .loc 1 8 3 # debugloc.c:8:3 + callq foo + leaq (%rsp), %rdi +.Ltmp5: + #DEBUG_VALUE: main:j <- [%RDI+0] + .loc 1 9 3 # debugloc.c:9:3 + callq foo + .loc 1 10 10 # debugloc.c:10:10 + movl 4(%rsp), %eax +.Ltmp6: + #DEBUG_VALUE: main:i <- %EAX + .loc 1 10 12 is_stmt 0 # debugloc.c:10:12 + subl (%rsp), %eax +.Ltmp7: + .loc 1 10 3 # debugloc.c:10:3 + popq %rcx + retq +.Ltmp8: +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)" # string offset=0 +.Linfo_string1: + .asciz "debugloc.c" # string offset=54 +.Linfo_string2: + .asciz "/tmp" # string offset=65 +.Linfo_string3: + .asciz "foo" # string offset=70 +.Linfo_string4: + .asciz "main" # string offset=74 +.Linfo_string5: + .asciz "int" # string offset=79 +.Linfo_string6: + .asciz "i" # string offset=83 +.Linfo_string7: + .asciz "j" # string offset=85 + .section .debug_loc,"",@progbits +.Ldebug_loc0: + .quad .Ltmp2-.Lfunc_begin0 + .quad .Ltmp4-.Lfunc_begin0 + .short 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 0 # 0 + .byte 159 # DW_OP_stack_value + .quad .Ltmp4-.Lfunc_begin0 + .quad .Ltmp5-.Lfunc_begin0 + .short 2 # Loc expr size + .byte 117 # DW_OP_breg5 + .byte 0 # 0 + .quad .Ltmp6-.Lfunc_begin0 + .quad .Ltmp7-.Lfunc_begin0 + .short 3 # Loc expr size + .byte 80 # super-register DW_OP_reg0 + .byte 147 # DW_OP_piece + .byte 4 # 4 + .quad 0 + .quad 0 +.Ldebug_loc1: + .quad .Ltmp3-.Lfunc_begin0 + .quad .Ltmp5-.Lfunc_begin0 + .short 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 0 # 0 + .byte 159 # DW_OP_stack_value + .quad .Ltmp5-.Lfunc_begin0 + .quad .Lfunc_end1-.Lfunc_begin0 + .short 2 # Loc expr size + .byte 117 # DW_OP_breg5 + .byte 0 # 0 + .quad 0 + .quad 0 + .section .debug_abbrev,"",@progbits +.Lsection_abbrev: + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .ascii "\341\177" # DW_AT_APPLE_optimized + .byte 25 # DW_FORM_flag_present + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .ascii "\347\177" # DW_AT_APPLE_omit_frame_ptr + .byte 25 # DW_FORM_flag_present + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .ascii "\341\177" # DW_AT_APPLE_optimized + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .ascii "\347\177" # DW_AT_APPLE_omit_frame_ptr + .byte 25 # DW_FORM_flag_present + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .ascii "\341\177" # DW_AT_APPLE_optimized + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 23 # DW_FORM_sec_offset + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lsection_info: +.Lcu_begin0: + .long 142 # Length of Unit + .short 4 # DWARF version number + .long .Lsection_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x87 DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 12 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir + # DW_AT_APPLE_optimized + .quad .Lfunc_begin0 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc + .byte 2 # Abbrev [2] 0x2a:0x23 DW_TAG_subprogram + .quad .Lfunc_begin0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + # DW_AT_APPLE_omit_frame_ptr + .byte 1 # DW_AT_frame_base + .byte 87 + .long .Linfo_string3 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + # DW_AT_prototyped + # DW_AT_external + # DW_AT_APPLE_optimized + .byte 3 # Abbrev [3] 0x3f:0xd DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 85 + .long .Linfo_string6 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 140 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x4d:0x38 DW_TAG_subprogram + .quad .Lfunc_begin1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + # DW_AT_APPLE_omit_frame_ptr + .byte 1 # DW_AT_frame_base + .byte 87 + .long .Linfo_string4 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .long 133 # DW_AT_type + # DW_AT_external + # DW_AT_APPLE_optimized + .byte 5 # Abbrev [5] 0x66:0xf DW_TAG_variable + .long .Ldebug_loc0 # DW_AT_location + .long .Linfo_string6 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + .long 133 # DW_AT_type + .byte 5 # Abbrev [5] 0x75:0xf DW_TAG_variable + .long .Ldebug_loc1 # DW_AT_location + .long .Linfo_string7 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 133 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0x85:0x7 DW_TAG_base_type + .long .Linfo_string5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 7 # Abbrev [7] 0x8c:0x5 DW_TAG_pointer_type + .long 133 # DW_AT_type + .byte 0 # End Of Children Mark + .section .debug_ranges,"",@progbits +.Ldebug_range: + .section .debug_macinfo,"",@progbits + .byte 0 # End Of Macro List Mark + .section .debug_pubnames,"",@progbits + .long .LpubNames_end0-.LpubNames_begin0 # Length of Public Names Info +.LpubNames_begin0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 146 # Compilation Unit Length + .long 42 # DIE offset + .asciz "foo" # External Name + .long 77 # DIE offset + .asciz "main" # External Name + .long 0 # End Mark +.LpubNames_end0: + .section .debug_pubtypes,"",@progbits + .long .LpubTypes_end0-.LpubTypes_begin0 # Length of Public Types Info +.LpubTypes_begin0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 146 # Compilation Unit Length + .long 133 # DIE offset + .asciz "int" # External Name + .long 0 # End Mark +.LpubTypes_end0: + + .ident "clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)" + .section ".note.GNU-stack","",@progbits + .section .debug_line,"",@progbits +.Lline_table_start0: