Skip to content

Commit 4a8e545

Browse files
committed
[lldb] Add support for the DW_AT_trampoline attribute with a boolean
This patch adds support for the DW_AT_trampoline attribute whose value is a boolean. Which is a "generic trampoline". Stepping into a generic trampoline by default will step through the function, checking at every branch, until we stop in a function which makes sense to stop at (a function with debug info, which isn't a trampoline, for example). Differential Revision: https://reviews.llvm.org/D147292
1 parent b24e290 commit 4a8e545

27 files changed

+492
-68
lines changed

lldb/include/lldb/Symbol/Function.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,14 @@ class Function : public UserID, public SymbolContextScope {
436436
///
437437
/// \param[in] range
438438
/// The section offset based address for this function.
439+
/// \param[in] generic_trampoline
440+
/// If this function is a generic trampoline. A generic trampoline
441+
/// is a function without any annotations on what the trampoline
442+
/// target is.
439443
Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
440444
lldb::user_id_t func_type_uid, const Mangled &mangled,
441-
Type *func_type, const AddressRange &range);
445+
Type *func_type, const AddressRange &range,
446+
bool generic_trampoline = false);
442447

443448
/// Destructor.
444449
~Function() override;
@@ -550,6 +555,10 @@ class Function : public UserID, public SymbolContextScope {
550555
/// A type object pointer.
551556
Type *GetType();
552557

558+
bool IsGenericTrampoline() const {
559+
return m_is_generic_trampoline;
560+
}
561+
553562
/// Get const accessor for the type that describes the function return value
554563
/// type, and parameter types.
555564
///
@@ -650,6 +659,8 @@ class Function : public UserID, public SymbolContextScope {
650659
/// information.
651660
Mangled m_mangled;
652661

662+
bool m_is_generic_trampoline;
663+
653664
/// All lexical blocks contained in this function.
654665
Block m_block;
655666

lldb/include/lldb/Target/Target.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ class TargetProperties : public Properties {
250250

251251
bool GetDebugUtilityExpression() const;
252252

253+
/// Trampoline support includes stepping through trampolines directly to their
254+
/// targets, stepping out of trampolines directly to their callers, and
255+
/// automatically filtering out trampolines as possible breakpoint locations
256+
/// when set by name.
257+
bool GetEnableTrampolineSupport() const;
258+
253259
private:
254260
// Callbacks for m_launch_info.
255261
void Arg0ValueChangedCallback();

lldb/include/lldb/Target/Thread.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,27 @@ class Thread : public std::enable_shared_from_this<Thread>,
897897
bool abort_other_plans, bool stop_other_threads,
898898
Status &status);
899899

900+
/// Gets the plan used to step through a function with a generic trampoline. A
901+
/// generic trampoline is one without a function target, which the thread plan
902+
/// will attempt to step through until it finds a place where it makes sense
903+
/// to stop at.
904+
/// \param[in] abort_other_plans
905+
/// \b true if we discard the currently queued plans and replace them with
906+
/// this one.
907+
/// Otherwise this plan will go on the end of the plan stack.
908+
///
909+
/// \param[in] stop_other_threads
910+
/// \b true if we will stop other threads while we single step this one.
911+
///
912+
/// \param[out] status
913+
/// A status with an error if queuing failed.
914+
///
915+
/// \return
916+
/// A shared pointer to the newly queued thread plan, or nullptr if the
917+
/// plan could not be queued.
918+
virtual lldb::ThreadPlanSP QueueThreadPlanForStepThroughGenericTrampoline(
919+
bool abort_other_plans, lldb::RunMode stop_other_threads, Status &status);
920+
900921
/// Gets the plan used to continue from the current PC.
901922
/// This is a simple plan, mostly useful as a backstop when you are continuing
902923
/// for some particular purpose.

lldb/include/lldb/Target/ThreadPlan.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ class ThreadPlan : public std::enable_shared_from_this<ThreadPlan>,
302302
eKindStepInRange,
303303
eKindRunToAddress,
304304
eKindStepThrough,
305+
eKindStepThroughGenericTrampoline,
305306
eKindStepUntil
306307
};
307308

lldb/include/lldb/Target/ThreadPlanStepOverRange.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class ThreadPlanStepOverRange : public ThreadPlanStepRange,
3030
bool ShouldStop(Event *event_ptr) override;
3131

3232
protected:
33-
bool DoPlanExplainsStop(Event *event_ptr) override;
3433
bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
3534

3635
void SetFlagsToDefault() override {

lldb/include/lldb/Target/ThreadPlanStepRange.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class ThreadPlanStepRange : public ThreadPlan {
4141
void AddRange(const AddressRange &new_range);
4242

4343
protected:
44+
bool DoPlanExplainsStop(Event *event_ptr) override;
4445
bool InRange();
4546
lldb::FrameComparison CompareCurrentFrameToStartFrame();
4647
bool InSymbol();
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===-- ThreadPlanStepInRange.h ---------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_TARGET_THREADPLANSTEPTHROUGHGENERICTRAMPOLINE_H
10+
#define LLDB_TARGET_THREADPLANSTEPTHROUGHGENERICTRAMPOLINE_H
11+
12+
#include "lldb/Target/Thread.h"
13+
#include "lldb/Target/ThreadPlanShouldStopHere.h"
14+
#include "lldb/Target/ThreadPlanStepRange.h"
15+
16+
namespace lldb_private {
17+
18+
class ThreadPlanStepThroughGenericTrampoline : public ThreadPlanStepRange,
19+
public ThreadPlanShouldStopHere {
20+
public:
21+
ThreadPlanStepThroughGenericTrampoline(Thread &thread,
22+
lldb::RunMode stop_others);
23+
24+
~ThreadPlanStepThroughGenericTrampoline() override;
25+
26+
void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
27+
28+
bool ShouldStop(Event *event_ptr) override;
29+
bool ValidatePlan(Stream *error) override;
30+
31+
protected:
32+
void SetFlagsToDefault() override {
33+
GetFlags().Set(
34+
ThreadPlanStepThroughGenericTrampoline::s_default_flag_values);
35+
}
36+
37+
private:
38+
// Need an appropriate marker for the current stack so we can tell step out
39+
// from step in.
40+
41+
static uint32_t
42+
s_default_flag_values; // These are the default flag values
43+
// for the ThreadPlanStepThroughGenericTrampoline.
44+
ThreadPlanStepThroughGenericTrampoline(
45+
const ThreadPlanStepThroughGenericTrampoline &) = delete;
46+
const ThreadPlanStepThroughGenericTrampoline &
47+
operator=(const ThreadPlanStepThroughGenericTrampoline &) = delete;
48+
};
49+
50+
} // namespace lldb_private
51+
52+
#endif // LLDB_TARGET_THREADPLANSTEPTHROUGHGENERICTRAMPOLINE_H

lldb/source/Core/Module.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,12 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
776776
if (!sc_list.GetContextAtIndex(i, sc))
777777
break;
778778

779+
bool is_trampoline =
780+
Target::GetGlobalProperties().GetEnableTrampolineSupport() &&
781+
sc.function && sc.function->IsGenericTrampoline();
782+
779783
bool keep_it =
784+
!is_trampoline &&
780785
NameMatchesLookupInfo(sc.GetFunctionName(), sc.GetLanguage());
781786
if (keep_it)
782787
++i;

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2440,12 +2440,15 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
24402440

24412441
assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);
24422442

2443+
bool is_generic_trampoline = die.IsGenericTrampoline();
2444+
24432445
const user_id_t func_user_id = die.GetID();
24442446
func_sp =
24452447
std::make_shared<Function>(&comp_unit,
24462448
func_user_id, // UserID is the DIE offset
24472449
func_user_id, func_name, func_type,
2448-
func_range); // first address range
2450+
func_range, // first address range
2451+
is_generic_trampoline);
24492452

24502453
if (func_sp.get() != nullptr) {
24512454
if (frame_base.IsValid())

lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,13 @@ const char *DWARFDIE::GetMangledName() const {
203203
return nullptr;
204204
}
205205

206+
bool DWARFDIE::IsGenericTrampoline() const {
207+
if (IsValid())
208+
return m_die->GetIsGenericTrampoline(m_cu);
209+
else
210+
return false;
211+
}
212+
206213
const char *DWARFDIE::GetPubname() const {
207214
if (IsValid())
208215
return m_die->GetPubname(m_cu);

0 commit comments

Comments
 (0)