207 lines · plain
1# REQUIRES: x862 3# RUN: split-file %s %t4# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %t/input.s -o %t/input.o5# RUN: %lldb %t/input.o -o "command script import %t/script.py" -o exit | FileCheck %s6 7# CHECK: Found 1 function(s).8# CHECK: foo: [input.o[0x0-0xe), input.o[0x14-0x1c)]9# CHECK-NEXT: input.o[0x0]: callq 0xe10# CHECK-NEXT: input.o[0x5]: jmp 0x1b11# CHECK-NEXT: input.o[0x7]: cmpl $0x0, %edi12# CHECK-NEXT: input.o[0xa]: je 0x1413# CHECK-NEXT: input.o[0xc]: jmp 0x014# CHECK-EMPTY:15# CHECK-NEXT: input.o[0x14]: callq 0x1916# CHECK-NEXT: input.o[0x19]: jmp 0x1b17# CHECK-NEXT: input.o[0x1b]: retq18## Testing the GetRangeIndexForBlockAddress API. "ffffffff" indicates that19## the address does not belong to any range.20# CHECK-NEXT: offset 0x00 => index 021# CHECK-NEXT: offset 0x0c => index 022# CHECK-NEXT: offset 0x0e => index ffffffff23# CHECK-NEXT: offset 0x13 => index ffffffff24# CHECK-NEXT: offset 0x14 => index 125# CHECK-NEXT: offset 0x1b => index 126# CHECK-NEXT: offset 0x1c => index ffffffff27 28 29#--- script.py30import lldb31 32def __lldb_init_module(debugger, internal_dict):33 target = debugger.GetSelectedTarget()34 sym_ctxs = target.FindFunctions("foo")35 print(f"Found {len(sym_ctxs)} function(s).")36 for ctx in sym_ctxs:37 fn = ctx.function38 print(f"{fn.name}: {fn.GetRanges()}")39 print(fn.GetInstructions(target))40 text = fn.addr.section41 for offset in [0x00, 0x0c, 0x0e, 0x13, 0x14, 0x1b, 0x1c]:42 idx = fn.block.GetRangeIndexForBlockAddress(lldb.SBAddress(text, offset))43 print(f"offset 0x{offset:02x} => index {idx:x}")44 45#--- input.s46# An example of a function which has been split into two parts. Roughly47# corresponds to this C code.48# int baz();49# int bar() { return 47; }50# int foo(int flag) { return flag ? bar() : baz(); }51# The function bar has been placed "in the middle" of foo.52 53 .text54 55 .type foo,@function56foo.__part.1:57 .cfi_startproc58 callq bar59 jmp foo.__part.360.Lfoo.__part.1_end:61 .size foo.__part.1, .Lfoo.__part.1_end-foo.__part.162 .cfi_endproc63 64foo:65 .cfi_startproc66 cmpl $0, %edi67 je foo.__part.268 jmp foo.__part.169 .cfi_endproc70.Lfoo_end:71 .size foo, .Lfoo_end-foo72 73bar:74 .cfi_startproc75 movl $47, %eax76 retq77 .cfi_endproc78.Lbar_end:79 .size bar, .Lbar_end-bar80 81foo.__part.2:82 .cfi_startproc83 callq baz84 jmp foo.__part.385.Lfoo.__part.2_end:86 .size foo.__part.2, .Lfoo.__part.2_end-foo.__part.287 .cfi_endproc88 89foo.__part.3:90 .cfi_startproc91 retq92.Lfoo.__part.3_end:93 .size foo.__part.3, .Lfoo.__part.3_end-foo.__part.394 .cfi_endproc95 96 97 .section .debug_abbrev,"",@progbits98 .byte 1 # Abbreviation Code99 .byte 17 # DW_TAG_compile_unit100 .byte 1 # DW_CHILDREN_yes101 .byte 37 # DW_AT_producer102 .byte 8 # DW_FORM_string103 .byte 19 # DW_AT_language104 .byte 5 # DW_FORM_data2105 .byte 17 # DW_AT_low_pc106 .byte 1 # DW_FORM_addr107 .byte 85 # DW_AT_ranges108 .byte 35 # DW_FORM_rnglistx109 .byte 116 # DW_AT_rnglists_base110 .byte 23 # DW_FORM_sec_offset111 .byte 0 # EOM(1)112 .byte 0 # EOM(2)113 .byte 2 # Abbreviation Code114 .byte 46 # DW_TAG_subprogram115 .byte 0 # DW_CHILDREN_no116 .byte 17 # DW_AT_low_pc117 .byte 1 # DW_FORM_addr118 .byte 18 # DW_AT_high_pc119 .byte 1 # DW_FORM_addr120 .byte 3 # DW_AT_name121 .byte 8 # DW_FORM_string122 .byte 0 # EOM(1)123 .byte 0 # EOM(2)124 .byte 3 # Abbreviation Code125 .byte 46 # DW_TAG_subprogram126 .byte 0 # DW_CHILDREN_no127 .byte 85 # DW_AT_ranges128 .byte 35 # DW_FORM_rnglistx129 .byte 64 # DW_AT_frame_base130 .byte 24 # DW_FORM_exprloc131 .byte 3 # DW_AT_name132 .byte 8 # DW_FORM_string133 .byte 0 # EOM(1)134 .byte 0 # EOM(2)135 .byte 0 # EOM(3)136 137 .section .debug_info,"",@progbits138.Lcu_begin0:139 .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit140.Ldebug_info_start0:141 .short 5 # DWARF version number142 .byte 1 # DWARF Unit Type143 .byte 8 # Address Size (in bytes)144 .long .debug_abbrev # Offset Into Abbrev. Section145 .byte 1 # Abbrev [1] DW_TAG_compile_unit146 .asciz "Hand-written DWARF" # DW_AT_producer147 .short 29 # DW_AT_language148 .quad 0 # DW_AT_low_pc149 .byte 1 # DW_AT_ranges150 .long .Lrnglists_table_base0 # DW_AT_rnglists_base151 .byte 2 # Abbrev [2] DW_TAG_subprogram152 .quad bar # DW_AT_low_pc153 .quad .Lbar_end # DW_AT_high_pc154 .asciz "bar" # DW_AT_name155 .byte 3 # Abbrev [3] DW_TAG_subprogram156 .byte 0 # DW_AT_ranges157 .byte 1 # DW_AT_frame_base158 .byte 86159 .asciz "foo" # DW_AT_name160 .byte 0 # End Of Children Mark161.Ldebug_info_end0:162 163 .section .debug_rnglists,"",@progbits164 .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length165.Ldebug_list_header_start0:166 .short 5 # Version167 .byte 8 # Address size168 .byte 0 # Segment selector size169 .long 2 # Offset entry count170.Lrnglists_table_base0:171 .long .Ldebug_ranges0-.Lrnglists_table_base0172 .long .Ldebug_ranges1-.Lrnglists_table_base0173.Ldebug_ranges0:174 .byte 6 # DW_RLE_start_end175 .quad foo176 .quad .Lfoo_end177 .byte 6 # DW_RLE_start_end178 .quad foo.__part.1179 .quad .Lfoo.__part.1_end180 .byte 6 # DW_RLE_start_end181 .quad foo.__part.2182 .quad .Lfoo.__part.2_end183 .byte 6 # DW_RLE_start_end184 .quad foo.__part.3185 .quad .Lfoo.__part.3_end186 .byte 0 # DW_RLE_end_of_list187.Ldebug_ranges1:188 .byte 6 # DW_RLE_start_end189 .quad bar190 .quad .Lbar_end191 .byte 6 # DW_RLE_start_end192 .quad foo.__part.1193 .quad .Lfoo.__part.1_end194 .byte 6 # DW_RLE_start_end195 .quad foo.__part.2196 .quad .Lfoo.__part.2_end197 .byte 6 # DW_RLE_start_end198 .quad foo.__part.3199 .quad .Lfoo.__part.3_end200 .byte 6 # DW_RLE_start_end201 .quad foo202 .quad .Lfoo_end203 .byte 0 # DW_RLE_end_of_list204.Ldebug_list_header_end0:205 206 .section ".note.GNU-stack","",@progbits207