-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
This code
https://godbolt.org/z/nxnK4PWj9
@foo = unnamed_addr alias void (), ptr @bar
define dso_local void @bar() unnamed_addr #0 {
start:
ret void
}
attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "cmse_nonsecure_entry" "frame-pointer"="all" "target-cpu"="generic" }
generates this assembly
__acle_se_bar:
bar:
push {r7, lr}
mov r7, sp
pop.w {r7, lr}
mov r0, lr
mov r1, lr
mov r2, lr
mov r3, lr
mov r12, lr
msr apsr_nzcvq, lr
bxns lr
foo = bar
The bodies are merged (fine) but no __acle_se_
symbol is generated for foo
(bad!).
It looks like clang specifically marks cmse-nonsecure-entry
functions as local_unnamed_addr
to circumvent this problem, see https://godbolt.org/z/qh55KPzzs. In rustc
we don't really want to do that, and don't see a technical reason why merging the definitions would not work.
My suggestion is to also generate the symbol for any aliases to a function marked as cmse. I'm not sure yet if there is a convenient way to do that currently.
The linker is able to handle such input. For instance, when we modify the input
@foo = unnamed_addr alias void (), ptr @bar
@"__acle_se_foo" = unnamed_addr alias void (), ptr @bar
define dso_local void @bar() unnamed_addr #0 {
start:
ret void
}
Then compile to .o
and then .elf
llc -mtriple=thumbv8m.main-none-eabi -mattr=+8msecext,+thumb-mode -filetype=obj foo.ll -o foo.o
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -mcmse -nostartfiles -nostdlib foo.o -Wl,--cmse-implib -Wl,--out-implib,veneers.o
The linker invocation fails because we really need a linker script here, but the veneer file does contain both symbols
> llvm-objdump -td veneers.o
veneers.o: file format elf32-littlearm
SYMBOL TABLE:
00008001 g F *ABS* 00000010 foo
00008001 g F *ABS* 00000010 bar