Skip to content

Commit 72bc18c

Browse files
author
git apple-llvm automerger
committed
Merge commit '59bb9b915ef9' from llvm.org/main into next
2 parents 4fde836 + 59bb9b9 commit 72bc18c

File tree

7 files changed

+198
-20
lines changed

7 files changed

+198
-20
lines changed

lldb/include/lldb/API/SBAddressRangeList.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class LLDB_API SBAddressRangeList {
4545
private:
4646
friend class SBBlock;
4747
friend class SBProcess;
48+
friend class SBFunction;
4849

4950
lldb_private::AddressRangeListImpl &ref() const;
5051

lldb/include/lldb/API/SBFunction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class LLDB_API SBFunction {
4343

4444
lldb::SBAddress GetStartAddress();
4545

46+
LLDB_DEPRECATED_FIXME("Not compatible with discontinuous functions.",
47+
"GetRanges()")
4648
lldb::SBAddress GetEndAddress();
4749

4850
lldb::SBAddressRangeList GetRanges();

lldb/include/lldb/Core/AddressRangeListImpl.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ class AddressRangeListImpl {
2424
public:
2525
AddressRangeListImpl();
2626

27-
AddressRangeListImpl(const AddressRangeListImpl &rhs) = default;
28-
29-
AddressRangeListImpl &operator=(const AddressRangeListImpl &rhs);
27+
explicit AddressRangeListImpl(AddressRanges ranges)
28+
: m_ranges(std::move(ranges)) {}
3029

3130
size_t GetSize() const;
3231

lldb/include/lldb/Symbol/Function.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,11 @@ class Function : public UserID, public SymbolContextScope {
448448

449449
Function *CalculateSymbolContextFunction() override;
450450

451+
/// DEPRECATED: Use GetAddressRanges instead.
451452
const AddressRange &GetAddressRange() { return m_range; }
452453

454+
const AddressRanges &GetAddressRanges() const { return m_ranges; }
455+
453456
lldb::LanguageType GetLanguage() const;
454457
/// Find the file and line number of the source location of the start of the
455458
/// function. This will use the declaration if present and fall back on the

lldb/source/API/SBFunction.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "lldb/API/SBAddressRange.h"
1111
#include "lldb/API/SBProcess.h"
1212
#include "lldb/API/SBStream.h"
13+
#include "lldb/Core/AddressRangeListImpl.h"
1314
#include "lldb/Core/Disassembler.h"
1415
#include "lldb/Core/Module.h"
1516
#include "lldb/Symbol/CompileUnit.h"
@@ -153,10 +154,11 @@ SBAddress SBFunction::GetEndAddress() {
153154

154155
SBAddress addr;
155156
if (m_opaque_ptr) {
156-
addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
157-
if (byte_size > 0) {
158-
addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress());
159-
addr->Slide(byte_size);
157+
llvm::ArrayRef<AddressRange> ranges = m_opaque_ptr->GetAddressRanges();
158+
if (!ranges.empty()) {
159+
// Return the end of the first range, use GetRanges to get all ranges.
160+
addr.SetAddress(ranges.front().GetBaseAddress());
161+
addr->Slide(ranges.front().GetByteSize());
160162
}
161163
}
162164
return addr;
@@ -166,11 +168,8 @@ lldb::SBAddressRangeList SBFunction::GetRanges() {
166168
LLDB_INSTRUMENT_VA(this);
167169

168170
lldb::SBAddressRangeList ranges;
169-
if (m_opaque_ptr) {
170-
lldb::SBAddressRange range;
171-
(*range.m_opaque_up) = m_opaque_ptr->GetAddressRange();
172-
ranges.Append(std::move(range));
173-
}
171+
if (m_opaque_ptr)
172+
ranges.ref() = AddressRangeListImpl(m_opaque_ptr->GetAddressRanges());
174173

175174
return ranges;
176175
}

lldb/source/Core/AddressRangeListImpl.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@ using namespace lldb_private;
1313

1414
AddressRangeListImpl::AddressRangeListImpl() : m_ranges() {}
1515

16-
AddressRangeListImpl &
17-
AddressRangeListImpl::operator=(const AddressRangeListImpl &rhs) {
18-
if (this == &rhs)
19-
return *this;
20-
m_ranges = rhs.m_ranges;
21-
return *this;
22-
}
23-
2416
size_t AddressRangeListImpl::GetSize() const { return m_ranges.size(); }
2517

2618
void AddressRangeListImpl::Reserve(size_t capacity) {
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# REQUIRES: x86
2+
3+
# RUN: split-file %s %t
4+
# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %t/input.s -o %t/input.o
5+
# RUN: %lldb %t/input.o -o "command script import %t/script.py" -o exit | FileCheck %s
6+
7+
# CHECK: Found 1 function(s).
8+
# CHECK: foo: [input.o[0x0-0x7), input.o[0x7-0xe), input.o[0x14-0x1b), input.o[0x1b-0x1c)]
9+
10+
#--- script.py
11+
import lldb
12+
13+
def __lldb_init_module(debugger, internal_dict):
14+
target = debugger.GetSelectedTarget()
15+
sym_ctxs = target.FindFunctions("foo")
16+
print(f"Found {len(sym_ctxs)} function(s).")
17+
for ctx in sym_ctxs:
18+
fn = ctx.function
19+
print(f"{fn.name}: {fn.GetRanges()}")
20+
21+
#--- input.s
22+
# An example of a function which has been split into two parts. Roughly
23+
# corresponds to this C code.
24+
# int baz();
25+
# int bar() { return 47; }
26+
# int foo(int flag) { return flag ? bar() : baz(); }
27+
# The function bar has been placed "in the middle" of foo.
28+
29+
.text
30+
31+
.type foo,@function
32+
foo:
33+
.cfi_startproc
34+
cmpl $0, %edi
35+
je foo.__part.2
36+
jmp foo.__part.1
37+
.cfi_endproc
38+
.Lfoo_end:
39+
.size foo, .Lfoo_end-foo
40+
41+
foo.__part.1:
42+
.cfi_startproc
43+
callq bar
44+
jmp foo.__part.3
45+
.Lfoo.__part.1_end:
46+
.size foo.__part.1, .Lfoo.__part.1_end-foo.__part.1
47+
.cfi_endproc
48+
49+
bar:
50+
.cfi_startproc
51+
movl $47, %eax
52+
retq
53+
.cfi_endproc
54+
.Lbar_end:
55+
.size bar, .Lbar_end-bar
56+
57+
foo.__part.2:
58+
.cfi_startproc
59+
callq baz
60+
jmp foo.__part.3
61+
.Lfoo.__part.2_end:
62+
.size foo.__part.2, .Lfoo.__part.2_end-foo.__part.2
63+
.cfi_endproc
64+
65+
foo.__part.3:
66+
.cfi_startproc
67+
retq
68+
.Lfoo.__part.3_end:
69+
.size foo.__part.3, .Lfoo.__part.3_end-foo.__part.3
70+
.cfi_endproc
71+
72+
73+
.section .debug_abbrev,"",@progbits
74+
.byte 1 # Abbreviation Code
75+
.byte 17 # DW_TAG_compile_unit
76+
.byte 1 # DW_CHILDREN_yes
77+
.byte 37 # DW_AT_producer
78+
.byte 8 # DW_FORM_string
79+
.byte 19 # DW_AT_language
80+
.byte 5 # DW_FORM_data2
81+
.byte 17 # DW_AT_low_pc
82+
.byte 1 # DW_FORM_addr
83+
.byte 85 # DW_AT_ranges
84+
.byte 35 # DW_FORM_rnglistx
85+
.byte 116 # DW_AT_rnglists_base
86+
.byte 23 # DW_FORM_sec_offset
87+
.byte 0 # EOM(1)
88+
.byte 0 # EOM(2)
89+
.byte 2 # Abbreviation Code
90+
.byte 46 # DW_TAG_subprogram
91+
.byte 0 # DW_CHILDREN_no
92+
.byte 17 # DW_AT_low_pc
93+
.byte 1 # DW_FORM_addr
94+
.byte 18 # DW_AT_high_pc
95+
.byte 1 # DW_FORM_addr
96+
.byte 3 # DW_AT_name
97+
.byte 8 # DW_FORM_string
98+
.byte 0 # EOM(1)
99+
.byte 0 # EOM(2)
100+
.byte 3 # Abbreviation Code
101+
.byte 46 # DW_TAG_subprogram
102+
.byte 0 # DW_CHILDREN_no
103+
.byte 85 # DW_AT_ranges
104+
.byte 35 # DW_FORM_rnglistx
105+
.byte 64 # DW_AT_frame_base
106+
.byte 24 # DW_FORM_exprloc
107+
.byte 3 # DW_AT_name
108+
.byte 8 # DW_FORM_string
109+
.byte 0 # EOM(1)
110+
.byte 0 # EOM(2)
111+
.byte 0 # EOM(3)
112+
113+
.section .debug_info,"",@progbits
114+
.Lcu_begin0:
115+
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
116+
.Ldebug_info_start0:
117+
.short 5 # DWARF version number
118+
.byte 1 # DWARF Unit Type
119+
.byte 8 # Address Size (in bytes)
120+
.long .debug_abbrev # Offset Into Abbrev. Section
121+
.byte 1 # Abbrev [1] DW_TAG_compile_unit
122+
.asciz "Hand-written DWARF" # DW_AT_producer
123+
.short 29 # DW_AT_language
124+
.quad 0 # DW_AT_low_pc
125+
.byte 1 # DW_AT_ranges
126+
.long .Lrnglists_table_base0 # DW_AT_rnglists_base
127+
.byte 2 # Abbrev [2] DW_TAG_subprogram
128+
.quad bar # DW_AT_low_pc
129+
.quad .Lbar_end # DW_AT_high_pc
130+
.asciz "bar" # DW_AT_name
131+
.byte 3 # Abbrev [3] DW_TAG_subprogram
132+
.byte 0 # DW_AT_ranges
133+
.byte 1 # DW_AT_frame_base
134+
.byte 86
135+
.asciz "foo" # DW_AT_name
136+
.byte 0 # End Of Children Mark
137+
.Ldebug_info_end0:
138+
139+
.section .debug_rnglists,"",@progbits
140+
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
141+
.Ldebug_list_header_start0:
142+
.short 5 # Version
143+
.byte 8 # Address size
144+
.byte 0 # Segment selector size
145+
.long 2 # Offset entry count
146+
.Lrnglists_table_base0:
147+
.long .Ldebug_ranges0-.Lrnglists_table_base0
148+
.long .Ldebug_ranges1-.Lrnglists_table_base0
149+
.Ldebug_ranges0:
150+
.byte 6 # DW_RLE_start_end
151+
.quad foo
152+
.quad .Lfoo_end
153+
.byte 6 # DW_RLE_start_end
154+
.quad foo.__part.1
155+
.quad .Lfoo.__part.1_end
156+
.byte 6 # DW_RLE_start_end
157+
.quad foo.__part.2
158+
.quad .Lfoo.__part.2_end
159+
.byte 6 # DW_RLE_start_end
160+
.quad foo.__part.3
161+
.quad .Lfoo.__part.3_end
162+
.byte 0 # DW_RLE_end_of_list
163+
.Ldebug_ranges1:
164+
.byte 6 # DW_RLE_start_end
165+
.quad bar
166+
.quad .Lbar_end
167+
.byte 6 # DW_RLE_start_end
168+
.quad foo.__part.1
169+
.quad .Lfoo.__part.1_end
170+
.byte 6 # DW_RLE_start_end
171+
.quad foo.__part.2
172+
.quad .Lfoo.__part.2_end
173+
.byte 6 # DW_RLE_start_end
174+
.quad foo.__part.3
175+
.quad .Lfoo.__part.3_end
176+
.byte 6 # DW_RLE_start_end
177+
.quad foo
178+
.quad .Lfoo_end
179+
.byte 0 # DW_RLE_end_of_list
180+
.Ldebug_list_header_end0:
181+
182+
.section ".note.GNU-stack","",@progbits

0 commit comments

Comments
 (0)