diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h index 16a82d5687de9..e5b7ad63007ca 100644 --- a/bolt/include/bolt/Rewrite/RewriteInstance.h +++ b/bolt/include/bolt/Rewrite/RewriteInstance.h @@ -510,12 +510,11 @@ class RewriteInstance { }; /// Different types of X86-64 PLT sections. - const PLTSectionInfo X86_64_PLTSections[4] = { - { ".plt", 16 }, - { ".plt.got", 8 }, - { ".plt.sec", 8 }, - { nullptr, 0 } - }; + const PLTSectionInfo X86_64_PLTSections[5] = {{".plt", 16}, + {".plt.got", 8}, + {".plt.sec", 8}, + {".iplt", 16}, + {nullptr, 0}}; /// AArch64 PLT sections. const PLTSectionInfo AArch64_PLTSections[4] = { diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index adacb50dc167c..2f0fa6038bde0 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -1533,7 +1533,7 @@ void RewriteInstance::createPLTBinaryFunction(uint64_t TargetAddress, MCSymbol *Symbol = Rel->Symbol; if (!Symbol) { - if (!BC->isAArch64() || !Rel->Addend || !Rel->isIRelative()) + if (BC->isRISCV() || !Rel->Addend || !Rel->isIRelative()) return; // IFUNC trampoline without symbol diff --git a/bolt/test/AArch64/ifunc.c b/bolt/test/AArch64/ifunc.test similarity index 76% rename from bolt/test/AArch64/ifunc.c rename to bolt/test/AArch64/ifunc.test index 1744976f05b22..3da42c67c5a0a 100644 --- a/bolt/test/AArch64/ifunc.c +++ b/bolt/test/AArch64/ifunc.test @@ -1,8 +1,6 @@ -// This test checks that IFUNC trampoline is properly recognised by BOLT - // With -O0 indirect call is performed on IPLT trampoline. IPLT trampoline // has IFUNC symbol. -// RUN: %clang %cflags -nostdlib -O0 -no-pie %s -fuse-ld=lld \ +// RUN: %clang %cflags -nostdlib -O0 -no-pie %p/../Inputs/ifunc.c -fuse-ld=lld \ // RUN: -o %t.O0.exe -Wl,-q // RUN: llvm-bolt %t.O0.exe -o %t.O0.bolt.exe \ // RUN: --print-disasm --print-only=_start | \ @@ -12,7 +10,7 @@ // Non-pie static executable doesn't generate PT_DYNAMIC, check relocation // is readed successfully and IPLT trampoline has been identified by bolt. -// RUN: %clang %cflags -nostdlib -O3 %s -fuse-ld=lld -no-pie \ +// RUN: %clang %cflags -nostdlib -O3 %p/../Inputs/ifunc.c -fuse-ld=lld -no-pie \ // RUN: -o %t.O3_nopie.exe -Wl,-q // RUN: llvm-readelf -l %t.O3_nopie.exe | \ // RUN: FileCheck --check-prefix=NON_DYN_CHECK %s @@ -25,7 +23,7 @@ // With -O3 direct call is performed on IPLT trampoline. IPLT trampoline // doesn't have associated symbol. The ifunc symbol has the same address as // IFUNC resolver function. -// RUN: %clang %cflags -nostdlib -O3 %s -fuse-ld=lld -fPIC -pie \ +// RUN: %clang %cflags -nostdlib -O3 %p/../Inputs/ifunc.c -fuse-ld=lld -fPIC -pie \ // RUN: -o %t.O3_pie.exe -Wl,-q // RUN: llvm-bolt %t.O3_pie.exe -o %t.O3_pie.bolt.exe \ // RUN: --print-disasm --print-only=_start | \ @@ -35,8 +33,8 @@ // Check that IPLT trampoline located in .plt section are normally handled by // BOLT. The gnu-ld linker doesn't use separate .iplt section. -// RUN: %clang %cflags -nostdlib -O3 %s -fuse-ld=lld -fPIC -pie \ -// RUN: -T %p/Inputs/iplt.ld -o %t.iplt_O3_pie.exe -Wl,-q +// RUN: %clang %cflags -nostdlib -O3 %p/../Inputs/ifunc.c -fuse-ld=lld -fPIC -pie \ +// RUN: -T %p/../Inputs/iplt.ld -o %t.iplt_O3_pie.exe -Wl,-q // RUN: llvm-bolt %t.iplt_O3_pie.exe -o %t.iplt_O3_pie.bolt.exe \ // RUN: --print-disasm --print-only=_start | \ // RUN: FileCheck --check-prefix=CHECK %s @@ -49,14 +47,3 @@ // REL_CHECK: R_AARCH64_IRELATIVE [[#%x,REL_SYMB_ADDR:]] // REL_CHECK: [[#REL_SYMB_ADDR]] {{.*}} FUNC {{.*}} resolver_foo - -static void foo() {} -static void bar() {} - -extern int use_foo; - -static void *resolver_foo(void) { return use_foo ? foo : bar; } - -__attribute__((ifunc("resolver_foo"))) void ifoo(); - -void _start() { ifoo(); } diff --git a/bolt/test/Inputs/ifunc.c b/bolt/test/Inputs/ifunc.c new file mode 100644 index 0000000000000..3fa62bef30930 --- /dev/null +++ b/bolt/test/Inputs/ifunc.c @@ -0,0 +1,12 @@ +// This test checks that IFUNC trampoline is properly recognised by BOLT + +static void foo() {} +static void bar() {} + +extern int use_foo; + +static void *resolver_foo(void) { return use_foo ? foo : bar; } + +__attribute__((ifunc("resolver_foo"))) void ifoo(); + +void _start() { ifoo(); } diff --git a/bolt/test/AArch64/Inputs/iplt.ld b/bolt/test/Inputs/iplt.ld similarity index 100% rename from bolt/test/AArch64/Inputs/iplt.ld rename to bolt/test/Inputs/iplt.ld diff --git a/bolt/test/X86/ifunc.test b/bolt/test/X86/ifunc.test new file mode 100644 index 0000000000000..befefbe5b2ac0 --- /dev/null +++ b/bolt/test/X86/ifunc.test @@ -0,0 +1,47 @@ +// Check if BOLT can process ifunc symbols from .plt section +// RUN: %clang %cflags -nostdlib -no-pie %p/../Inputs/ifunc.c -fuse-ld=lld \ +// RUN: -o %t.exe -Wl,-q +// RUN: llvm-bolt %t.exe -o %t.bolt.exe \ +// RUN: --print-disasm --print-only=_start | \ +// RUN: FileCheck --check-prefix=CHECK %s +// RUN: llvm-readelf -aW %t.bolt.exe | \ +// RUN: FileCheck --check-prefix=REL_CHECK %s + +// Check if BOLT can process ifunc symbols from .plt section in non-pie static +// executable case. +// RUN: %clang %cflags -nostdlib %p/../Inputs/ifunc.c -fuse-ld=lld -no-pie \ +// RUN: -o %t.nopie.exe -Wl,-q +// RUN: llvm-readelf -l %t.nopie.exe | \ +// RUN: FileCheck --check-prefix=NON_DYN_CHECK %s +// RUN: llvm-bolt %t.nopie.exe -o %t.nopie.bolt.exe \ +// RUN: --print-disasm --print-only=_start | \ +// RUN: FileCheck --check-prefix=CHECK %s +// RUN: llvm-readelf -aW %t.nopie.bolt.exe | \ +// RUN: FileCheck --check-prefix=REL_CHECK %s + +// Check if BOLT can process ifunc symbols from .plt section in pie executable +// case. +// RUN: %clang %cflags -nostdlib %p/../Inputs/ifunc.c -fuse-ld=lld -fPIC -pie \ +// RUN: -o %t.pie.exe -Wl,-q +// RUN: llvm-bolt %t.pie.exe -o %t.pie.bolt.exe \ +// RUN: --print-disasm --print-only=_start | \ +// RUN: FileCheck --check-prefix=CHECK %s +// RUN: llvm-readelf -aW %t.pie.bolt.exe | \ +// RUN: FileCheck --check-prefix=REL_CHECK %s + +// Check that IPLT trampoline located in .plt section are normally handled by +// BOLT. The gnu-ld linker doesn't use separate .iplt section. +// RUN: %clang %cflags -nostdlib %p/../Inputs/ifunc.c -fuse-ld=lld -fPIC -pie \ +// RUN: -T %p/../Inputs/iplt.ld -o %t.iplt_pie.exe -Wl,-q +// RUN: llvm-bolt %t.iplt_pie.exe -o %t.iplt_pie.bolt.exe \ +// RUN: --print-disasm --print-only=_start | \ +// RUN: FileCheck --check-prefix=CHECK %s +// RUN: llvm-readelf -aW %t.iplt_pie.bolt.exe | \ +// RUN: FileCheck --check-prefix=REL_CHECK %s + +// NON_DYN_CHECK-NOT: DYNAMIC + +// CHECK: callq "resolver_foo/1@PLT" + +// REL_CHECK: R_X86_64_IRELATIVE [[#%x,REL_SYMB_ADDR:]] +// REL_CHECK: [[#REL_SYMB_ADDR]] {{.*}} FUNC {{.*}} resolver_foo