Skip to content

Commit b88dc63

Browse files
authored
Merge pull request #6565 from augusto2112/cherry-pick-trampoline-support
Cherry pick trampoline support
2 parents f72221d + 2af4818 commit b88dc63

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+737
-50
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,12 @@ def Artificial : InheritableAttr {
771771
let SimpleHandler = 1;
772772
}
773773

774+
def TransparentStepping: InheritableAttr {
775+
let Spellings = [Clang<"transparent_stepping">];
776+
let Subjects = SubjectList<[Function]>;
777+
let Documentation = [TransparentSteppingDocs];
778+
}
779+
774780
def XRayInstrument : InheritableAttr {
775781
let Spellings = [Clang<"xray_always_instrument">,
776782
Clang<"xray_never_instrument">];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6924,6 +6924,66 @@ As such, this function attribute is currently only supported on X86 targets.
69246924
}];
69256925
}
69266926

6927+
def TransparentSteppingDocs : Documentation {
6928+
let Category = DocCatFunction;
6929+
let Content = [{
6930+
The ``transparent_stepping`` attribute is intended as a hint for debuggers that this
6931+
function itself is not interesting, but it calls a function that might be. So, when
6932+
stepping in arrives at a function with this attribute, debuggers should transparently
6933+
step-in through it into the functions called by the annotated function (but not by
6934+
subsequent calls made by those functions), stopping at the first one its normal rules
6935+
for whether to stop says to stop at - or stepping out again if none qualify. Also, when
6936+
stepping out arrives at a function with this attribute, the debugger should continue
6937+
stepping out to its caller.
6938+
6939+
For example:
6940+
6941+
.. code-block:: c
6942+
6943+
int bar(void) {
6944+
return 42;
6945+
}
6946+
6947+
__attribute__((transparent_stepping))
6948+
int foo(void) {
6949+
return bar();
6950+
}
6951+
6952+
int caller(void) {
6953+
return foo();
6954+
}
6955+
6956+
Stepping into ``foo`` should step directly into ``bar`` instead, and stepping out of ``bar``
6957+
should stop in ``caller``.
6958+
6959+
Functions with the ``transparent_stepping`` attribute can be chained together:
6960+
6961+
.. code-block:: c
6962+
6963+
int baz(void) {
6964+
return 42;
6965+
}
6966+
6967+
__attribute__((transparent_stepping))
6968+
int bar(void) {
6969+
return baz();
6970+
}
6971+
6972+
__attribute__((transparent_stepping))
6973+
int foo(void) {
6974+
return bar();
6975+
}
6976+
6977+
int caller(void) {
6978+
return foo();
6979+
}
6980+
6981+
In this example, stepping into ``foo`` should step directly into ``baz``, and stepping out of
6982+
``baz`` should stop in ``caller``.
6983+
}];
6984+
}
6985+
6986+
69276987
def ReadOnlyPlacementDocs : Documentation {
69286988
let Category = DocCatType;
69296989
let Content = [{This attribute is attached to a structure, class or union declaration.

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx) {
6767
return D->hasAttr<AlignedAttr>() ? D->getMaxAlignment() : 0;
6868
}
6969

70+
static bool getIsTransparentStepping(const Decl *D) {
71+
if (!D)
72+
return false;
73+
return D->hasAttr<TransparentSteppingAttr>();
74+
}
75+
7076
CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
7177
: CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
7278
DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
@@ -1882,6 +1888,8 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
18821888
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
18831889
if (CGM.getLangOpts().Optimize)
18841890
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
1891+
if (getIsTransparentStepping(Method))
1892+
SPFlags |= llvm::DISubprogram::SPFlagIsTransparentStepping;
18851893

18861894
// In this debug mode, emit type info for a class when its constructor type
18871895
// info is emitted.
@@ -3809,6 +3817,8 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
38093817
if (Stub) {
38103818
Flags |= getCallSiteRelatedAttrs();
38113819
SPFlags |= llvm::DISubprogram::SPFlagDefinition;
3820+
if (getIsTransparentStepping(FD))
3821+
SPFlags |= llvm::DISubprogram::SPFlagIsTransparentStepping;
38123822
return DBuilder.createFunction(
38133823
DContext, Name, LinkageName, Unit, Line,
38143824
getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags,
@@ -3958,6 +3968,8 @@ llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
39583968
if (It == TypeCache.end())
39593969
return nullptr;
39603970
auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
3971+
if (getIsTransparentStepping(D))
3972+
SPFlags |= llvm::DISubprogram::SPFlagIsTransparentStepping;
39613973
llvm::DISubprogram *FD = DBuilder.createFunction(
39623974
InterfaceType, getObjCMethodName(OMD), StringRef(),
39633975
InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
@@ -4124,6 +4136,8 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
41244136
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
41254137
if (CGM.getLangOpts().Optimize)
41264138
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
4139+
if (getIsTransparentStepping(D))
4140+
SPFlags |= llvm::DISubprogram::SPFlagIsTransparentStepping;
41274141

41284142
llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
41294143
llvm::DISubprogram::DISPFlags SPFlagsForDef =
@@ -4210,6 +4224,9 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
42104224

42114225
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
42124226
llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
4227+
if (getIsTransparentStepping(D))
4228+
SPFlags |= llvm::DISubprogram::SPFlagIsTransparentStepping;
4229+
42134230
llvm::DISubprogram *SP = DBuilder.createFunction(
42144231
FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
42154232
SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations);

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6687,6 +6687,12 @@ static void handleSwiftAsyncName(Sema &S, Decl *D, const ParsedAttr &AL) {
66876687
D->addAttr(::new (S.Context) SwiftAsyncNameAttr(S.Context, AL, Name));
66886688
}
66896689

6690+
static void handleTransparentStepping(Sema &S, Decl *D,
6691+
const ParsedAttr &AL) {
6692+
D->addAttr(::new (S.Context)
6693+
TransparentSteppingAttr(S.Context, AL));
6694+
}
6695+
66906696
static void handleSwiftNewType(Sema &S, Decl *D, const ParsedAttr &AL) {
66916697
// Make sure that there is an identifier as the annotation's single argument.
66926698
if (!AL.checkExactlyNumArgs(S, 1))
@@ -8948,6 +8954,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
89488954
case ParsedAttr::AT_NoDebug:
89498955
handleNoDebugAttr(S, D, AL);
89508956
break;
8957+
case ParsedAttr::AT_TransparentStepping:
8958+
handleTransparentStepping(S, D, AL);
8959+
break;
89518960
case ParsedAttr::AT_CmseNSEntry:
89528961
handleCmseNSEntryAttr(S, D, AL);
89538962
break;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
2+
3+
void bar(void) {}
4+
5+
struct A {
6+
[[clang::transparent_stepping()]]
7+
void foo(void) {
8+
bar();
9+
}
10+
};
11+
12+
int main() {
13+
A().foo();
14+
}
15+
16+
// CHECK: DISubprogram(name: "foo"{{.*}} DISPFlagIsTransparentStepping
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
2+
3+
void bar(void) {}
4+
5+
__attribute__((transparent_stepping))
6+
void foo(void) {
7+
bar();
8+
}
9+
10+
// CHECK: DISubprogram(name: "foo"{{.*}} DISPFlagIsTransparentStepping

clang/test/Misc/pragma-attribute-supported-attributes-list.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@
185185
// CHECK-NEXT: Target (SubjectMatchRule_function)
186186
// CHECK-NEXT: TargetClones (SubjectMatchRule_function)
187187
// CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
188+
// CHECK-NEXT: TransparentStepping (SubjectMatchRule_function)
188189
// CHECK-NEXT: TrivialABI (SubjectMatchRule_record)
189190
// CHECK-NEXT: Uninitialized (SubjectMatchRule_variable_is_local)
190191
// CHECK-NEXT: UseHandle (SubjectMatchRule_variable_is_parameter)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %clang_cc1 %s -verify -fsyntax-only
2+
3+
__attribute__((transparent_stepping))
4+
void correct(void) {}
5+
6+
__attribute__((transparent_stepping(1))) // expected-error {{'transparent_stepping' attribute takes no arguments}}
7+
void wrong_arg(void) {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 %s -verify -fsyntax-only
2+
3+
4+
struct S {
5+
[[clang::transparent_stepping]]
6+
void correct(void) {}
7+
8+
[[clang::transparent_stepping(1)]] // expected-error {{'transparent_stepping' attribute takes no arguments}}
9+
void one_arg(void) {}
10+
};
11+

lldb/include/lldb/Symbol/Function.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ class Function : public UserID, public SymbolContextScope {
442442
Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
443443
lldb::user_id_t func_type_uid, const Mangled &mangled,
444444
Type *func_type, const AddressRange &range,
445-
bool can_throw = false);
445+
bool can_throw = false, bool generic_trampoline = false);
446446

447447
/// Destructor.
448448
~Function() override;
@@ -554,6 +554,10 @@ class Function : public UserID, public SymbolContextScope {
554554
/// A type object pointer.
555555
Type *GetType();
556556

557+
bool IsGenericTrampoline() const {
558+
return m_is_generic_trampoline;
559+
}
560+
557561
/// Get const accessor for the type that describes the function return value
558562
/// type, and parameter types.
559563
///
@@ -659,6 +663,8 @@ class Function : public UserID, public SymbolContextScope {
659663
/// information.
660664
Mangled m_mangled;
661665

666+
bool m_is_generic_trampoline;
667+
662668
/// All lexical blocks contained in this function.
663669
Block m_block;
664670

0 commit comments

Comments
 (0)