Skip to content

Commit

Permalink
EntryExitInstrumenter: skip naked functions
Browse files Browse the repository at this point in the history
The asm in a naked function may reasonably expect the argument registers and the
return address register (if present) to be live.

When using -pg and -finstrument-functions, functions are instrumented by adding
a function call to `_mcount/__cyg_profile_func_enter/__cyg_profile_func_enter_bare`/etc,
which will clobber these registers. If the return address register is clobbered,
the function will be unable to return to the caller, possibly causing an
infinite loop.

```
__attribute__((naked)) void g() {
#if defined(__arm__)
  __asm__("bx lr");
#else
  __asm__("ret");
#endif
}

int main() { g(); }
```

It seems that the only one reasonable way to handle the combination is to
disable instrumenting for naked functions.

GCC PR: https://gcc.gnu.org/PR109707
Close #62504

Reviewed By: hans

Differential Revision: https://reviews.llvm.org/D149721
  • Loading branch information
MaskRay committed May 4, 2023
1 parent ec2c0e0 commit 3460f72
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 0 deletions.
7 changes: 7 additions & 0 deletions llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ static void insertCall(Function &CurFn, StringRef Func,
}

static bool runOnFunction(Function &F, bool PostInlining) {
// The asm in a naked function may reasonably expect the argument registers
// and the return address register (if present) to be live. An inserted
// function call will clobber these registers. Simply skip naked functions for
// all targets.
if (F.hasFnAttribute(Attribute::Naked))
return false;

StringRef EntryAttr = PostInlining ? "instrument-function-entry-inlined"
: "instrument-function-entry";

Expand Down
7 changes: 7 additions & 0 deletions llvm/test/Transforms/EntryExitInstrumenter/mcount.ll
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ define ptr @tailcaller2() #8 {
; CHECK: ret
}

;; naked functions are not instrumented, otherwise the argument registers
;; and the return address register (if present) would be clobbered.
define void @naked() naked { entry: ret void }
; CHECK-LABEL: define void @naked(
; CHECK-LABEL-NEXT: entry:
; CHECK-LABEL-NEXT: ret void

; The attributes are "consumed" when the instrumentation is inserted.
; CHECK: attributes
; CHECK-NOT: instrument-function
Expand Down

0 comments on commit 3460f72

Please sign in to comment.