Skip to content

Commit 11f33ab

Browse files
authored
Branch island with numbers (#138781)
Reapply the support for stepping through branch islands, add support for a branch that takes multiple hops to get to the target.
1 parent 32fb8c5 commit 11f33ab

File tree

9 files changed

+100
-7
lines changed

9 files changed

+100
-7
lines changed

lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "lldb/Target/Thread.h"
2727
#include "lldb/Target/ThreadPlanCallFunction.h"
2828
#include "lldb/Target/ThreadPlanRunToAddress.h"
29+
#include "lldb/Target/ThreadPlanStepInstruction.h"
2930
#include "lldb/Utility/DataBuffer.h"
3031
#include "lldb/Utility/DataBufferHeap.h"
3132
#include "lldb/Utility/LLDBLog.h"
@@ -923,15 +924,15 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread,
923924
if (current_symbol != nullptr) {
924925
std::vector<Address> addresses;
925926

927+
ConstString current_name =
928+
current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
926929
if (current_symbol->IsTrampoline()) {
927-
ConstString trampoline_name =
928-
current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
929930

930-
if (trampoline_name) {
931+
if (current_name) {
931932
const ModuleList &images = target_sp->GetImages();
932933

933934
SymbolContextList code_symbols;
934-
images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode,
935+
images.FindSymbolsWithNameAndType(current_name, eSymbolTypeCode,
935936
code_symbols);
936937
for (const SymbolContext &context : code_symbols) {
937938
Address addr = context.GetFunctionOrSymbolAddress();
@@ -945,8 +946,8 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread,
945946
}
946947

947948
SymbolContextList reexported_symbols;
948-
images.FindSymbolsWithNameAndType(
949-
trampoline_name, eSymbolTypeReExported, reexported_symbols);
949+
images.FindSymbolsWithNameAndType(current_name, eSymbolTypeReExported,
950+
reexported_symbols);
950951
for (const SymbolContext &context : reexported_symbols) {
951952
if (context.symbol) {
952953
Symbol *actual_symbol =
@@ -968,7 +969,7 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread,
968969
}
969970

970971
SymbolContextList indirect_symbols;
971-
images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver,
972+
images.FindSymbolsWithNameAndType(current_name, eSymbolTypeResolver,
972973
indirect_symbols);
973974

974975
for (const SymbolContext &context : indirect_symbols) {
@@ -1028,6 +1029,23 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread,
10281029
thread_plan_sp = std::make_shared<ThreadPlanRunToAddress>(
10291030
thread, load_addrs, stop_others);
10301031
}
1032+
// One more case we have to consider is "branch islands". These are regular
1033+
// TEXT symbols but their names end in .island plus maybe a .digit suffix.
1034+
// They are to allow arm64 code to branch further than the size of the
1035+
// address slot allows. We just need to single-instruction step in that
1036+
// case.
1037+
static const char *g_branch_island_pattern = "\\.island\\.?[0-9]*$";
1038+
static RegularExpression g_branch_island_regex(g_branch_island_pattern);
1039+
1040+
bool is_branch_island = g_branch_island_regex.Execute(current_name);
1041+
if (!thread_plan_sp && is_branch_island) {
1042+
thread_plan_sp = std::make_shared<ThreadPlanStepInstruction>(
1043+
thread,
1044+
/* step_over= */ false, /* stop_others */ false, eVoteNoOpinion,
1045+
eVoteNoOpinion);
1046+
LLDB_LOG(log, "Stepping one instruction over branch island: '{0}'.",
1047+
current_name);
1048+
}
10311049
} else {
10321050
LLDB_LOGF(log, "Could not find symbol for step through.");
10331051
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
C_SOURCES := main.c foo.c
2+
CFLAGS_EXTRAS := -std=c99
3+
4+
include Makefile.rules
5+
6+
a.out: main.o padding1.o padding2.o padding3.o padding4.o foo.o
7+
${CC} ${LDFLAGS} foo.o padding1.o padding2.o padding3.o padding4.o main.o -o a.out
8+
9+
%.o: $(SRCDIR)/%.s
10+
${CC} -c $<
11+
12+
#padding1.o: padding1.s
13+
# ${CC} -c $(SRCDIR)/padding1.s
14+
15+
#padding2.o: padding2.s
16+
# ${CC} -c $(SRCDIR)/padding2.s
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
Make sure that we can step in across an arm64 branch island
3+
"""
4+
5+
6+
import lldb
7+
import lldbsuite.test.lldbutil as lldbutil
8+
from lldbsuite.test.lldbtest import *
9+
from lldbsuite.test.decorators import *
10+
11+
12+
class TestBranchIslandStepping(TestBase):
13+
NO_DEBUG_INFO_TESTCASE = True
14+
15+
@skipUnlessDarwin
16+
def test_step_in_branch_island(self):
17+
"""Make sure we can step in across a branch island"""
18+
self.build()
19+
self.main_source_file = lldb.SBFileSpec("main.c")
20+
self.do_test()
21+
22+
def do_test(self):
23+
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
24+
self, "Set a breakpoint here", self.main_source_file
25+
)
26+
27+
# Make sure that we did manage to generate a branch island for foo:
28+
syms = target.FindSymbols("foo.island", lldb.eSymbolTypeCode)
29+
self.assertEqual(len(syms), 1, "We did generate an island for foo")
30+
31+
thread.StepInto()
32+
stop_frame = thread.frames[0]
33+
self.assertIn("foo", stop_frame.name, "Stepped into foo")
34+
var = stop_frame.FindVariable("a_variable_in_foo")
35+
self.assertTrue(var.IsValid(), "Found the variable in foo")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <stdio.h>
2+
3+
void foo() {
4+
int a_variable_in_foo = 10;
5+
printf("I am foo: %d.\n", a_variable_in_foo);
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
extern void foo();
2+
3+
int main() {
4+
foo(); // Set a breakpoint here
5+
return 0;
6+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.text
2+
_padding1:
3+
.space 120*1024*1024
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.text
2+
_padding2:
3+
.space 120*1024*1024
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.text
2+
_padding3:
3+
.space 120*1024*1024
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.text
2+
_padding4:
3+
.space 120*1024*1024

0 commit comments

Comments
 (0)