Skip to content

Commit fdd0d53

Browse files
authored
cmse: emit __acle_se_ symbol for aliases to entry functions (llvm#162109)
Emitting the symbol in `emitGlobalAlias` seemed most efficient, otherwise I think you'd have to traverse all aliases. I have verified that the additional symbol is picked up by `arm-none-eabi-ld` and correctly generates an entry in `veneers.o`. Fixes llvm#162084
1 parent c3579f0 commit fdd0d53

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

llvm/lib/Target/ARM/ARMAsmPrinter.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,35 @@ void ARMAsmPrinter::emitXXStructor(const DataLayout &DL, const Constant *CV) {
103103
OutStreamer->emitValue(E, Size);
104104
}
105105

106+
// An alias to a cmse entry function should also emit a `__acle_se_` symbol.
107+
void ARMAsmPrinter::emitCMSEVeneerAlias(const GlobalAlias &GA) {
108+
const Function *BaseFn = dyn_cast_or_null<Function>(GA.getAliaseeObject());
109+
if (!BaseFn || !BaseFn->hasFnAttribute("cmse_nonsecure_entry"))
110+
return;
111+
112+
MCSymbol *AliasSym = getSymbol(&GA);
113+
MCSymbol *FnSym = getSymbol(BaseFn);
114+
115+
MCSymbol *SEAliasSym =
116+
OutContext.getOrCreateSymbol(Twine("__acle_se_") + AliasSym->getName());
117+
MCSymbol *SEBaseSym =
118+
OutContext.getOrCreateSymbol(Twine("__acle_se_") + FnSym->getName());
119+
120+
// Mirror alias linkage/visibility onto the veneer-alias symbol.
121+
emitLinkage(&GA, SEAliasSym);
122+
OutStreamer->emitSymbolAttribute(SEAliasSym, MCSA_ELF_TypeFunction);
123+
emitVisibility(SEAliasSym, GA.getVisibility());
124+
125+
// emit "__acle_se_<alias> = __acle_se_<aliasee>"
126+
const MCExpr *SEExpr = MCSymbolRefExpr::create(SEBaseSym, OutContext);
127+
OutStreamer->emitAssignment(SEAliasSym, SEExpr);
128+
}
129+
130+
void ARMAsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) {
131+
AsmPrinter::emitGlobalAlias(M, GA);
132+
emitCMSEVeneerAlias(GA);
133+
}
134+
106135
void ARMAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
107136
if (PromotedGlobals.count(GV))
108137
// The global was promoted into a constant pool. It should not be emitted.

llvm/lib/Target/ARM/ARMAsmPrinter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter {
104104
void emitEndOfAsmFile(Module &M) override;
105105
void emitXXStructor(const DataLayout &DL, const Constant *CV) override;
106106
void emitGlobalVariable(const GlobalVariable *GV) override;
107+
void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override;
107108

108109
MCSymbol *GetCPISymbol(unsigned CPID) const override;
109110

@@ -159,6 +160,8 @@ class LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter {
159160

160161
MCSymbol *GetARMGVSymbol(const GlobalValue *GV, unsigned char TargetFlags);
161162

163+
void emitCMSEVeneerAlias(const GlobalAlias &GA);
164+
162165
public:
163166
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
164167
/// the .s file.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
; RUN: llc -mtriple=thumbv8.1m.main %s -o - | FileCheck %s
2+
3+
@foo = unnamed_addr alias void (), ptr @bar
4+
5+
; CHECK: .globl bar
6+
; CHECK: .globl __acle_se_bar @ @bar
7+
; CHECK: .globl foo
8+
; CHECK: foo = bar
9+
; CHECK: __acle_se_foo = __acle_se_bar
10+
11+
define dso_local void @bar() unnamed_addr #0 {
12+
start:
13+
ret void
14+
}
15+
16+
attributes #0 = { nounwind "cmse_nonsecure_entry" }
17+

0 commit comments

Comments
 (0)