-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Branch island with numbers #138781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Branch island with numbers #138781
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -26,6 +26,7 @@ | |||||
#include "lldb/Target/Thread.h" | ||||||
#include "lldb/Target/ThreadPlanCallFunction.h" | ||||||
#include "lldb/Target/ThreadPlanRunToAddress.h" | ||||||
#include "lldb/Target/ThreadPlanStepInstruction.h" | ||||||
#include "lldb/Utility/DataBuffer.h" | ||||||
#include "lldb/Utility/DataBufferHeap.h" | ||||||
#include "lldb/Utility/LLDBLog.h" | ||||||
|
@@ -923,15 +924,15 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread, | |||||
if (current_symbol != nullptr) { | ||||||
std::vector<Address> addresses; | ||||||
|
||||||
ConstString current_name = | ||||||
current_symbol->GetMangled().GetName(Mangled::ePreferMangled); | ||||||
if (current_symbol->IsTrampoline()) { | ||||||
ConstString trampoline_name = | ||||||
current_symbol->GetMangled().GetName(Mangled::ePreferMangled); | ||||||
|
||||||
if (trampoline_name) { | ||||||
if (current_name) { | ||||||
const ModuleList &images = target_sp->GetImages(); | ||||||
|
||||||
SymbolContextList code_symbols; | ||||||
images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, | ||||||
images.FindSymbolsWithNameAndType(current_name, eSymbolTypeCode, | ||||||
code_symbols); | ||||||
for (const SymbolContext &context : code_symbols) { | ||||||
Address addr = context.GetFunctionOrSymbolAddress(); | ||||||
|
@@ -945,8 +946,8 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread, | |||||
} | ||||||
|
||||||
SymbolContextList reexported_symbols; | ||||||
images.FindSymbolsWithNameAndType( | ||||||
trampoline_name, eSymbolTypeReExported, reexported_symbols); | ||||||
images.FindSymbolsWithNameAndType(current_name, eSymbolTypeReExported, | ||||||
reexported_symbols); | ||||||
for (const SymbolContext &context : reexported_symbols) { | ||||||
if (context.symbol) { | ||||||
Symbol *actual_symbol = | ||||||
|
@@ -968,7 +969,7 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread, | |||||
} | ||||||
|
||||||
SymbolContextList indirect_symbols; | ||||||
images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver, | ||||||
images.FindSymbolsWithNameAndType(current_name, eSymbolTypeResolver, | ||||||
indirect_symbols); | ||||||
|
||||||
for (const SymbolContext &context : indirect_symbols) { | ||||||
|
@@ -1028,6 +1029,23 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread, | |||||
thread_plan_sp = std::make_shared<ThreadPlanRunToAddress>( | ||||||
thread, load_addrs, stop_others); | ||||||
} | ||||||
// One more case we have to consider is "branch islands". These are regular | ||||||
// TEXT symbols but their names end in .island plus maybe a .digit suffix. | ||||||
// They are to allow arm64 code to branch further than the size of the | ||||||
// address slot allows. We just need to single-instruction step in that | ||||||
// case. | ||||||
static const char *g_branch_island_pattern = "\\.island\\.?[0-9]*$"; | ||||||
static RegularExpression g_branch_island_regex(g_branch_island_pattern); | ||||||
|
||||||
bool is_branch_island = g_branch_island_regex.Execute(current_name); | ||||||
if (!thread_plan_sp && is_branch_island) { | ||||||
thread_plan_sp = std::make_shared<ThreadPlanStepInstruction>( | ||||||
thread, | ||||||
/* step_over= */ false, /* stop_others */ false, eVoteNoOpinion, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
eVoteNoOpinion); | ||||||
LLDB_LOG(log, "Stepping one instruction over branch island: '{0}'.", | ||||||
current_name); | ||||||
} | ||||||
} else { | ||||||
LLDB_LOGF(log, "Could not find symbol for step through."); | ||||||
} | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
C_SOURCES := main.c foo.c | ||
CFLAGS_EXTRAS := -std=c99 | ||
|
||
include Makefile.rules | ||
|
||
a.out: main.o padding1.o padding2.o padding3.o padding4.o foo.o | ||
${CC} ${LDFLAGS} foo.o padding1.o padding2.o padding3.o padding4.o main.o -o a.out | ||
|
||
%.o: $(SRCDIR)/%.s | ||
${CC} -c $< | ||
|
||
#padding1.o: padding1.s | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. delete this? |
||
# ${CC} -c $(SRCDIR)/padding1.s | ||
|
||
#padding2.o: padding2.s | ||
# ${CC} -c $(SRCDIR)/padding2.s |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
""" | ||
Make sure that we can step in across an arm64 branch island | ||
""" | ||
|
||
|
||
import lldb | ||
import lldbsuite.test.lldbutil as lldbutil | ||
from lldbsuite.test.lldbtest import * | ||
from lldbsuite.test.decorators import * | ||
|
||
|
||
class TestBranchIslandStepping(TestBase): | ||
NO_DEBUG_INFO_TESTCASE = True | ||
|
||
@skipUnlessDarwin | ||
def test_step_in_branch_island(self): | ||
"""Make sure we can step in across a branch island""" | ||
self.build() | ||
self.main_source_file = lldb.SBFileSpec("main.c") | ||
self.do_test() | ||
|
||
def do_test(self): | ||
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( | ||
self, "Set a breakpoint here", self.main_source_file | ||
) | ||
|
||
# Make sure that we did manage to generate a branch island for foo: | ||
syms = target.FindSymbols("foo.island", lldb.eSymbolTypeCode) | ||
self.assertEqual(len(syms), 1, "We did generate an island for foo") | ||
|
||
thread.StepInto() | ||
stop_frame = thread.frames[0] | ||
self.assertIn("foo", stop_frame.name, "Stepped into foo") | ||
var = stop_frame.FindVariable("a_variable_in_foo") | ||
self.assertTrue(var.IsValid(), "Found the variable in foo") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include <stdio.h> | ||
|
||
void foo() { | ||
int a_variable_in_foo = 10; | ||
printf("I am foo: %d.\n", a_variable_in_foo); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extern void foo(); | ||
|
||
int main() { | ||
foo(); // Set a breakpoint here | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.text | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the first cross-architecture assembler source file I've seen :-) |
||
_padding1: | ||
.space 120*1024*1024 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.text | ||
_padding2: | ||
.space 120*1024*1024 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.text | ||
_padding3: | ||
.space 120*1024*1024 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.text | ||
_padding4: | ||
.space 120*1024*1024 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pedantic, but maybe
"\\.island\\(.[0-9]+)?$"
would be more precise, sincefoo.island.
with no number should probably not get matched?