Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3771,6 +3771,8 @@ MCSymbol *BinaryFunction::addEntryPointAtOffset(uint64_t Offset) {
assert(Offset && "cannot add primary entry point");

const uint64_t EntryPointAddress = getAddress() + Offset;
assert(!isInConstantIsland(EntryPointAddress) &&
"cannot add entry point that points to constant data");
MCSymbol *LocalSymbol = getOrCreateLocalLabel(EntryPointAddress);

MCSymbol *EntrySymbol = getSecondaryEntryPointSymbol(LocalSymbol);
Expand Down
3 changes: 2 additions & 1 deletion bolt/lib/Rewrite/RewriteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2935,7 +2935,8 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
ReferencedSymbol = nullptr;
ExtractedValue = Address;
} else if (RefFunctionOffset) {
if (ContainingBF && ContainingBF != ReferencedBF) {
if (ContainingBF && ContainingBF != ReferencedBF &&
!ReferencedBF->isInConstantIsland(Address)) {
ReferencedSymbol =
ReferencedBF->addEntryPointAtOffset(RefFunctionOffset);
} else {
Expand Down
44 changes: 41 additions & 3 deletions bolt/test/AArch64/validate-secondary-entry-point.s
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
# This test is to verify that BOLT won't take a label pointing to constant
# island as a secondary entry point (function `_start` doesn't have ELF size
# set originally) and the function won't otherwise be mistaken as non-simple.
# island as a secondary entry point. This could happen when function doesn't
# have ELF size set if it is from assembly code, or a constant island is
# referenced by another function discovered during relocation processing.

# RUN: %clang %cflags -pie %s -o %t.so -Wl,-q -Wl,--init=_foo -Wl,--fini=_foo
# RUN: split-file %s %t

# RUN: %clang %cflags -pie %t/tt.asm -o %t.so \
# RUN: -Wl,-q -Wl,--init=_foo -Wl,--fini=_foo
# RUN: llvm-bolt %t.so -o %t.bolt.so --print-cfg 2>&1 | FileCheck %s
# CHECK-NOT: BOLT-WARNING: reference in the middle of instruction detected \
# CHECK-NOT: function _start at offset 0x{{[0-9a-f]+}}
# CHECK: Binary Function "_start" after building cfg

# RUN: %clang %cflags -ffunction-sections -shared %t/tt.c %t/ss.c -o %tt.so \
# RUN: -Wl,-q -Wl,--init=_start -Wl,--fini=_start \
# RUN: -Wl,--version-script=%t/linker_script
# RUN: llvm-bolt %tt.so -o %tt.bolted.so

;--- tt.asm
.text

.global _foo
Expand All @@ -32,3 +42,31 @@ _bar:

# Dummy relocation to force relocation mode
.reloc 0, R_AARCH64_NONE

;--- tt.c
void _start() {}

__attribute__((naked)) void foo() {
asm("ldr x16, .L_fnptr\n"
"blr x16\n"
"ret\n"

"_rodatx:"
".global _rodatx;"
".quad 0;"
".L_fnptr:"
".quad 0;");
}

;--- ss.c
__attribute__((visibility("hidden"))) extern void* _rodatx;
void* bar() { return &_rodatx; }

;--- linker_script
{
global:
_start;
foo;
bar;
local: *;
};
Loading