Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/bolt
diff options
context:
space:
mode:
Diffstat (limited to 'bolt')
-rw-r--r--bolt/CMakeLists.txt2
-rw-r--r--bolt/include/bolt/Core/BinaryContext.h16
-rw-r--r--bolt/lib/Rewrite/RewriteInstance.cpp4
-rw-r--r--bolt/test/AArch64/Inputs/plt-gnu-ld.yaml459
-rw-r--r--bolt/test/AArch64/lit.local.cfg2
-rw-r--r--bolt/test/AArch64/plt-gnu-ld.test12
-rw-r--r--bolt/test/AArch64/plt-lld.test13
-rw-r--r--bolt/test/Inputs/plt.c20
-rw-r--r--bolt/test/Inputs/stub.c6
-rw-r--r--bolt/test/Inputs/stub.h9
-rw-r--r--bolt/test/lit.cfg.py3
-rw-r--r--bolt/test/lit.site.cfg.py.in1
-rw-r--r--bolt/test/runtime/AArch64/plt.c25
-rw-r--r--bolt/test/runtime/iplt.c (renamed from bolt/test/runtime/AArch64/iplt.c)6
-rw-r--r--bolt/test/runtime/plt-gnu-ld.test12
-rw-r--r--bolt/test/runtime/plt-lld.test9
16 files changed, 569 insertions, 30 deletions
diff --git a/bolt/CMakeLists.txt b/bolt/CMakeLists.txt
index d7290927abe4..bf2e04779513 100644
--- a/bolt/CMakeLists.txt
+++ b/bolt/CMakeLists.txt
@@ -73,6 +73,8 @@ if (git_executable)
endif()
endif()
+find_program(GNU_LD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.bfd ld.bfd DOC "GNU ld")
+
# If we can't find a revision, set it to "<unknown>".
if (NOT BOLT_REVISION)
set(BOLT_REVISION "<unknown>")
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 86b2e45661a0..0257c907f588 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -774,6 +774,22 @@ public:
return Itr != GlobalSymbols.end() ? Itr->second : nullptr;
}
+ /// Return registered PLT entry BinaryData with the given \p Name
+ /// or nullptr if no global PLT symbol with that name exists.
+ const BinaryData *getPLTBinaryDataByName(StringRef Name) const {
+ if (const BinaryData *Data = getBinaryDataByName(Name.str() + "@PLT"))
+ return Data;
+
+ // The symbol name might contain versioning information e.g
+ // memcpy@@GLIBC_2.17. Remove it and try to locate binary data
+ // without it.
+ size_t At = Name.find("@");
+ if (At != std::string::npos)
+ return getBinaryDataByName(Name.str().substr(0, At) + "@PLT");
+
+ return nullptr;
+ }
+
/// Return true if \p SymbolName was generated internally and was not present
/// in the input binary.
bool isInternalSymbolName(const StringRef Name) {
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index b342d2cdbed6..1db7bd92a4a0 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -1884,7 +1884,7 @@ bool RewriteInstance::analyzeRelocation(
IsSectionRelocation = (cantFail(Symbol.getType()) == SymbolRef::ST_Debug);
// Check for PLT entry registered with symbol name
if (!SymbolAddress && IsAArch64) {
- BinaryData *BD = BC->getBinaryDataByName(SymbolName + "@PLT");
+ const BinaryData *BD = BC->getPLTBinaryDataByName(SymbolName);
SymbolAddress = BD ? BD->getAddress() : 0;
}
}
@@ -3035,7 +3035,7 @@ public:
std::string SymName = Symbol.str();
LLVM_DEBUG(dbgs() << "BOLT: looking for " << SymName << "\n");
// Resolve to a PLT entry if possible
- if (BinaryData *I = BC.getBinaryDataByName(SymName + "@PLT")) {
+ if (const BinaryData *I = BC.getPLTBinaryDataByName(SymName)) {
AllResults[Symbol] =
JITEvaluatedSymbol(I->getAddress(), JITSymbolFlags());
continue;
diff --git a/bolt/test/AArch64/Inputs/plt-gnu-ld.yaml b/bolt/test/AArch64/Inputs/plt-gnu-ld.yaml
new file mode 100644
index 000000000000..04e7f85b6722
--- /dev/null
+++ b/bolt/test/AArch64/Inputs/plt-gnu-ld.yaml
@@ -0,0 +1,459 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_AARCH64
+ Entry: 0x400510
+ProgramHeaders:
+ - Type: PT_PHDR
+ Flags: [ PF_R ]
+ VAddr: 0x400040
+ Align: 0x8
+ - Type: PT_INTERP
+ Flags: [ PF_R ]
+ FirstSec: .interp
+ LastSec: .interp
+ VAddr: 0x400238
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ FirstSec: .interp
+ LastSec: .bss
+ VAddr: 0x400000
+ Align: 0x10000
+ - Type: PT_DYNAMIC
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ VAddr: 0x410E08
+ Align: 0x8
+Sections:
+ - Name: .interp
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x400238
+ AddressAlign: 0x1
+ Content: 2F6C69622F6C642D6C696E75782D616172636836342E736F2E3100
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ Flags: [ SHF_ALLOC ]
+ Address: 0x4002A0
+ Link: .dynstr
+ AddressAlign: 0x8
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ Address: 0x400348
+ AddressAlign: 0x1
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ Address: 0x4003C8
+ Link: .dynsym
+ AddressAlign: 0x8
+ Relocations:
+ - Offset: 0x410FE0
+ Symbol: __gmon_start__
+ Type: R_AARCH64_GLOB_DAT
+ - Name: .rela.plt
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC, SHF_INFO_LINK ]
+ Address: 0x4003E0
+ Link: .dynsym
+ AddressAlign: 0x8
+ Info: .got.plt
+ Relocations:
+ - Offset: 0x411000
+ Symbol: memcpy
+ Type: R_AARCH64_JUMP_SLOT
+ - Offset: 0x411008
+ Symbol: __libc_start_main
+ Type: R_AARCH64_JUMP_SLOT
+ - Offset: 0x411010
+ Symbol: memset
+ Type: R_AARCH64_JUMP_SLOT
+ - Offset: 0x411018
+ Symbol: __gmon_start__
+ Type: R_AARCH64_JUMP_SLOT
+ - Offset: 0x411020
+ Symbol: abort
+ Type: R_AARCH64_JUMP_SLOT
+ - Offset: 0x411028
+ Symbol: printf
+ Type: R_AARCH64_JUMP_SLOT
+ - Name: .plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x400490
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F07BBFA99000009011FE47F910E23F9120021FD61F2003D51F2003D51F2003D5900000B0110240F91002009120021FD6900000B0110640F91022009120021FD6900000B0110A40F91042009120021FD6900000B0110E40F91062009120021FD6900000B0111240F91082009120021FD6900000B0111640F910A2009120021FD6
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x400510
+ AddressAlign: 0x8
+ Content: 1D0080D21E0080D2E50300AAE10340F9E2230091E603009100000090002015910300009063201B910400009084201D91E0FFFF97EBFFFF972F0000148000009000F047F9400000B4E2FFFF17C0035FD6800000B000000191810000B0210001913F0000EBC00000540100009021B443F9610000B4F00301AA00021FD6C0035FD6800000B000000191810000B021000191210000CB22FC7FD3410C818BFF0781EB21FC4193C00000540200009042B843F9620000B4F00302AA00021FD6C0035FD6FD7BBEA9FD030091F30B00F9930000B06002413980000035DEFFFF972000805260020139F30B40F9FD7BC2A8C0035FD6E4FFFF17FF8300D1FD7B01A9FD430091BFC31FB8E1230091E8DD9752A8D5BB72E80300B9E80B00B9E0130091FF0700B9880000B00900009029C11291092500F9082540F9820080D200013FD6E90340B9E80740B90801096BA00000540100001428008052A8C31FB814000014880000B00900009029411391092900F9082940F9E0230091E1031F2A820080D200013FD6E80B40B9A80000340100001428008052A8C31FB8050000140000009000E01D9194FFFF9701000014A0C35FB8FD7B41A9FF830091C0035FD6FD7BBCA9FD030091F35301A99400009094023891F55B02A995000090B5E23791940215CBF603002AF76303A9F70301AAF80302AA5DFFFF97FF0F94EB6001005494FE4393130080D2A37A73F8E20318AA73060091E10317AAE003162A60003FD69F0213EB21FFFF54F35341A9F55B42A9F76343A9FD7BC4A8C0035FD61F2003D5C0035FD6
+ - Name: .rodata
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x400760
+ AddressAlign: 0x8
+ Content: 0100020000000000000000000000000000000000000000005465737420636F6D706C657465640A00
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x410E08
+ Link: .dynstr
+ AddressAlign: 0x8
+ Entries:
+ - Tag: DT_NEEDED
+ Value: 0x1
+ - Tag: DT_STRTAB
+ Value: 0x400348
+ - Tag: DT_SYMTAB
+ Value: 0x4002A0
+ - Tag: DT_STRSZ
+ Value: 0x52
+ - Tag: DT_SYMENT
+ Value: 0x18
+ - Tag: DT_DEBUG
+ Value: 0x0
+ - Tag: DT_PLTGOT
+ Value: 0x410FE8
+ - Tag: DT_PLTRELSZ
+ Value: 0x90
+ - Tag: DT_PLTREL
+ Value: 0x7
+ - Tag: DT_JMPREL
+ Value: 0x4003E0
+ - Tag: DT_RELA
+ Value: 0x4003C8
+ - Tag: DT_RELASZ
+ Value: 0x18
+ - Tag: DT_RELAENT
+ Value: 0x18
+ - Tag: DT_NULL
+ Value: 0x0
+ - Name: .got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x410FD8
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '080E4100000000000000000000000000'
+ - Name: .got.plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x410FE8
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '000000000000000000000000000000000000000000000000900440000000000090044000000000009004400000000000900440000000000090044000000000009004400000000000'
+ - Name: .tm_clone_table
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x411040
+ AddressAlign: 0x8
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x411040
+ AddressAlign: 0x8
+ Size: 0x18
+ - Name: .rela.text
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .text
+ Relocations:
+ - Offset: 0x400528
+ Symbol: .text
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ Addend: 56
+ - Offset: 0x40052C
+ Symbol: .text
+ Type: R_AARCH64_ADD_ABS_LO12_NC
+ Addend: 56
+ Symbol: '__libc_start_main@@GLIBC_2.17'
+ Type: R_AARCH64_CALL26
+ - Offset: 0x400544
+ Symbol: 'abort@@GLIBC_2.17'
+ Type: R_AARCH64_CALL26
+ - Offset: 0x400548
+ Symbol: main
+ Type: R_AARCH64_JUMP26
+ - Offset: 0x40054C
+ Symbol: __gmon_start__
+ Type: R_AARCH64_ADR_GOT_PAGE
+ - Offset: 0x400550
+ Symbol: __gmon_start__
+ Type: R_AARCH64_LD64_GOT_LO12_NC
+ - Offset: 0x400558
+ Symbol: __gmon_start__
+ Type: R_AARCH64_JUMP26
+ - Offset: 0x400560
+ Symbol: .tm_clone_table
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ - Offset: 0x400564
+ Symbol: .tm_clone_table
+ Type: R_AARCH64_ADD_ABS_LO12_NC
+ - Offset: 0x400578
+ Symbol: .rodata
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ Addend: 8
+ - Offset: 0x40057C
+ Symbol: .rodata
+ Type: R_AARCH64_LDST64_ABS_LO12_NC
+ Addend: 8
+ - Offset: 0x400590
+ Symbol: .tm_clone_table
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ - Offset: 0x400594
+ Symbol: .tm_clone_table
+ Type: R_AARCH64_ADD_ABS_LO12_NC
+ - Offset: 0x4005B8
+ Symbol: .rodata
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ Addend: 16
+ - Offset: 0x4005BC
+ Symbol: .rodata
+ Type: R_AARCH64_LDST64_ABS_LO12_NC
+ Addend: 16
+ - Offset: 0x4005DC
+ Symbol: .bss
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ - Offset: 0x4005E0
+ Symbol: .bss
+ Type: R_AARCH64_LDST8_ABS_LO12_NC
+ - Offset: 0x4005F0
+ Symbol: .bss
+ Type: R_AARCH64_LDST8_ABS_LO12_NC
+ - Offset: 0x400630
+ Symbol: memcpy_p
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ - Offset: 0x400634
+ Symbol: 'memcpy@@GLIBC_2.17'
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ - Offset: 0x400638
+ Symbol: 'memcpy@@GLIBC_2.17'
+ Type: R_AARCH64_ADD_ABS_LO12_NC
+ - Offset: 0x40063C
+ Symbol: memcpy_p
+ Type: R_AARCH64_LDST64_ABS_LO12_NC
+ - Offset: 0x400640
+ Symbol: memcpy_p
+ Type: R_AARCH64_LDST64_ABS_LO12_NC
+ - Offset: 0x40066C
+ Symbol: memset_p
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ - Offset: 0x400670
+ Symbol: 'memset@@GLIBC_2.17'
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ - Offset: 0x400674
+ Symbol: 'memset@@GLIBC_2.17'
+ Type: R_AARCH64_ADD_ABS_LO12_NC
+ - Offset: 0x400678
+ Symbol: memset_p
+ Type: R_AARCH64_LDST64_ABS_LO12_NC
+ - Offset: 0x40067C
+ Symbol: memset_p
+ Type: R_AARCH64_LDST64_ABS_LO12_NC
+ - Offset: 0x4006A8
+ Symbol: .rodata
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ Addend: 24
+ - Offset: 0x4006AC
+ Symbol: .rodata
+ Type: R_AARCH64_ADD_ABS_LO12_NC
+ Addend: 24
+ - Offset: 0x4006B0
+ Symbol: 'printf@@GLIBC_2.17'
+ Type: R_AARCH64_CALL26
+ - Name: .rela.rodata
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .rodata
+ Relocations:
+ - Type: SectionHeaderTable
+ Sections:
+ - Name: .interp
+ - Name: .dynsym
+ - Name: .dynstr
+ - Name: .rela.dyn
+ - Name: .rela.plt
+ - Name: .plt
+ - Name: .text
+ - Name: .rela.text
+ - Name: .rodata
+ - Name: .rela.rodata
+ - Name: .dynamic
+ - Name: .got
+ - Name: .got.plt
+ - Name: .tm_clone_table
+ - Name: .bss
+ - Name: .symtab
+ - Name: .strtab
+ - Name: .shstrtab
+Symbols:
+ - Name: .interp
+ Type: STT_SECTION
+ Section: .interp
+ Value: 0x400238
+ - Name: .dynsym
+ Type: STT_SECTION
+ Section: .dynsym
+ Value: 0x4002A0
+ - Name: .dynstr
+ Type: STT_SECTION
+ Section: .dynstr
+ Value: 0x400348
+ - Name: .rela.dyn
+ Type: STT_SECTION
+ Section: .rela.dyn
+ Value: 0x4003C8
+ - Name: .rela.plt
+ Type: STT_SECTION
+ Section: .rela.plt
+ Value: 0x4003E0
+ - Name: .plt
+ Type: STT_SECTION
+ Section: .plt
+ Value: 0x400490
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ Value: 0x400510
+ - Name: .rodata
+ Type: STT_SECTION
+ Section: .rodata
+ Value: 0x400760
+ - Name: .dynamic
+ Type: STT_SECTION
+ Section: .dynamic
+ Value: 0x410E08
+ - Name: .got
+ Type: STT_SECTION
+ Section: .got
+ Value: 0x410FD8
+ - Name: .got.plt
+ Type: STT_SECTION
+ Section: .got.plt
+ Value: 0x410FE8
+ - Name: .tm_clone_table
+ Type: STT_SECTION
+ Section: .tm_clone_table
+ Value: 0x411040
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ Value: 0x411040
+ - Name: __wrap_main
+ Section: .text
+ Value: 0x400548
+ - Name: _DYNAMIC
+ Type: STT_OBJECT
+ Section: .dynamic
+ Value: 0x410E08
+ - Name: _GLOBAL_OFFSET_TABLE_
+ Type: STT_OBJECT
+ Section: .got
+ Value: 0x410FD8
+ - Name: 'memcpy@@GLIBC_2.17'
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ Value: 0x4004B0
+ - Name: __bss_start__
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x411040
+ - Name: memcpy_p
+ Type: STT_OBJECT
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x411048
+ Size: 0x8
+ - Name: _bss_end__
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x411058
+ - Name: _edata
+ Section: .tm_clone_table
+ Binding: STB_GLOBAL
+ Value: 0x411040
+ - Name: __bss_end__
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x411058
+ - Name: '__libc_start_main@@GLIBC_2.17'
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: 'memset@@GLIBC_2.17'
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ Value: 0x4004D0
+ - Name: memset_p
+ Type: STT_OBJECT
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x411050
+ Size: 0x8
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: 'abort@@GLIBC_2.17'
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: _IO_stdin_used
+ Type: STT_OBJECT
+ Section: .rodata
+ Binding: STB_GLOBAL
+ Value: 0x400760
+ Size: 0x4
+ - Name: _end
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x411058
+ - Name: _start
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x400510
+ - Name: __end__
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x411058
+ - Name: __bss_start
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x411040
+ - Name: main
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x400604
+ Size: 0xC4
+ - Name: 'printf@@GLIBC_2.17'
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+DynamicSymbols:
+ - Name: __libc_start_main
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: abort
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: printf
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: memcpy
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ Value: 0x4004B0
+ - Name: memset
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ Value: 0x4004D0
diff --git a/bolt/test/AArch64/lit.local.cfg b/bolt/test/AArch64/lit.local.cfg
index 2806b3027d52..a727a7d2eafe 100644
--- a/bolt/test/AArch64/lit.local.cfg
+++ b/bolt/test/AArch64/lit.local.cfg
@@ -4,4 +4,4 @@ if 'AArch64' not in config.root.targets:
config.substitutions.insert(
0, ('%cflags',
'%cflags --target=aarch64-pc-linux -nostartfiles -nostdlib -fuse-ld=lld'
- ' -Wl,--unresolved-symbols=ignore-all'))
+ ' -ffreestanding -Wl,--unresolved-symbols=ignore-all'))
diff --git a/bolt/test/AArch64/plt-gnu-ld.test b/bolt/test/AArch64/plt-gnu-ld.test
new file mode 100644
index 000000000000..9dc37cd9b846
--- /dev/null
+++ b/bolt/test/AArch64/plt-gnu-ld.test
@@ -0,0 +1,12 @@
+// This test checks that the PLT symbols are properly recognized
+// by the BOLT tool.
+// The test is using bfd linker, since it may add versioning string
+// to the symbol name e.g. memcpy@@GLIBC_2.17
+
+// RUN: yaml2obj %p/Inputs/plt-gnu-ld.yaml &> %t.exe
+// RUN: llvm-bolt %t.exe -o %t.bolt.exe -use-old-text=0 -lite=0 \
+// RUN: -print-cfg -print-only=main | FileCheck %s
+
+// CHECK: memcpy@PLT
+// CHECK: memset@PLT
+// CHECK: printf@PLT
diff --git a/bolt/test/AArch64/plt-lld.test b/bolt/test/AArch64/plt-lld.test
new file mode 100644
index 000000000000..0a86a9ef9819
--- /dev/null
+++ b/bolt/test/AArch64/plt-lld.test
@@ -0,0 +1,13 @@
+// This test checks that the PLT symbols are properly recognized
+// by the BOLT tool.
+
+// RUN: %clang %cflags %p/../Inputs/stub.c -fuse-ld=lld -fPIC -pie -shared \
+// RUN: -o %t.so
+// RUN: %clang %cflags %p/../Inputs/plt.c -fuse-ld=lld \
+// RUN: -o %t.lld.exe -Wl,-q %t.so
+// RUN: llvm-bolt %t.lld.exe -o %t.lld.bolt.exe -use-old-text=0 -lite=0 \
+// RUN: -print-cfg -print-only=main | FileCheck %s
+
+// CHECK: memcpy@PLT
+// CHECK: memset@PLT
+// CHECK: printf@PLT
diff --git a/bolt/test/Inputs/plt.c b/bolt/test/Inputs/plt.c
new file mode 100644
index 000000000000..475c15b9cb3c
--- /dev/null
+++ b/bolt/test/Inputs/plt.c
@@ -0,0 +1,20 @@
+#include "stub.h"
+
+void *(*memcpy_p)(void *dest, const void *src, unsigned long n);
+void *(*memset_p)(void *dest, int c, unsigned long n);
+
+int main() {
+ int a = 0xdeadbeef, b = 0;
+
+ memcpy_p = memcpy;
+ memcpy_p(&b, &a, sizeof(b));
+ if (b != 0xdeadbeef)
+ return 1;
+
+ memset_p = memset;
+ memset_p(&a, 0, sizeof(a));
+ if (a != 0)
+ return 1;
+
+ printf("Test completed\n");
+}
diff --git a/bolt/test/Inputs/stub.c b/bolt/test/Inputs/stub.c
new file mode 100644
index 000000000000..1e84e8989490
--- /dev/null
+++ b/bolt/test/Inputs/stub.c
@@ -0,0 +1,6 @@
+// The stub symbols library used for testing purposes
+
+void *memcpy(void *dest, const void *src, unsigned long n) { return 0; }
+void *memset(void *dest, int c, unsigned long n) { return 0; }
+int printf(const char *format, ...) { return 0; }
+void exit(int status) {}
diff --git a/bolt/test/Inputs/stub.h b/bolt/test/Inputs/stub.h
new file mode 100644
index 000000000000..5c5b5d1f876a
--- /dev/null
+++ b/bolt/test/Inputs/stub.h
@@ -0,0 +1,9 @@
+#ifndef BOLT_TEST_STUB_H
+#define BOLT_TEST_STUB_H
+
+void *memcpy(void *dest, const void *src, unsigned long n);
+void *memset(void *dest, int c, unsigned long n);
+int printf(const char *format, ...);
+void exit(int status);
+
+#endif
diff --git a/bolt/test/lit.cfg.py b/bolt/test/lit.cfg.py
index 82e0db362fbc..a6bf3d073b97 100644
--- a/bolt/test/lit.cfg.py
+++ b/bolt/test/lit.cfg.py
@@ -53,6 +53,9 @@ else:
if config.bolt_enable_runtime:
config.available_features.add("bolt-runtime")
+if config.gnu_ld:
+ config.available_features.add("gnu_ld")
+
llvm_config.use_default_substitutions()
llvm_config.config.environment['CLANG'] = config.bolt_clang
diff --git a/bolt/test/lit.site.cfg.py.in b/bolt/test/lit.site.cfg.py.in
index 8c4b7f665361..832c497d8609 100644
--- a/bolt/test/lit.site.cfg.py.in
+++ b/bolt/test/lit.site.cfg.py.in
@@ -22,6 +22,7 @@ config.python_executable = "@PYTHON_EXECUTABLE@"
config.bolt_clang = "@BOLT_CLANG_EXE@"
config.bolt_lld = "@BOLT_LLD_EXE@"
config.targets_to_build = "@TARGETS_TO_BUILD@"
+config.gnu_ld = "@GNU_LD_EXECUTABLE@"
import lit.llvm
lit.llvm.initialize(lit_config, config)
diff --git a/bolt/test/runtime/AArch64/plt.c b/bolt/test/runtime/AArch64/plt.c
deleted file mode 100644
index 296599fff6d7..000000000000
--- a/bolt/test/runtime/AArch64/plt.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// This test checks that the pointers to PLT are properly updated.
-
-// RUN: %clang %cflags %s -fuse-ld=lld \
-// RUN: -o %t.exe -Wl,-q
-// RUN: llvm-bolt %t.exe -o %t.bolt.exe -use-old-text=0 -lite=0
-// RUN: %t.bolt.exe
-
-#include <string.h>
-
-void *(*memcpy_p)(void *dest, const void *src, size_t n);
-void *(*memset_p)(void *dest, int c, size_t n);
-
-int main() {
- int a = 0xdeadbeef, b = 0;
-
- memcpy_p = memcpy;
- memcpy_p(&b, &a, sizeof(b));
- if (b != 0xdeadbeef)
- return 1;
-
- memset_p = memset;
- memset_p(&a, 0, sizeof(a));
- if (a != 0)
- return 1;
-}
diff --git a/bolt/test/runtime/AArch64/iplt.c b/bolt/test/runtime/iplt.c
index 30a169c1265d..518d53dff903 100644
--- a/bolt/test/runtime/AArch64/iplt.c
+++ b/bolt/test/runtime/iplt.c
@@ -23,7 +23,9 @@ imemcpy(void *dest, const void *src, size_t n);
int main() {
int a = 0xdeadbeef, b = 0;
- ifoo();
imemcpy(&b, &a, sizeof(b));
- return a != b;
+ if (a != b)
+ return -1;
+
+ ifoo();
}
diff --git a/bolt/test/runtime/plt-gnu-ld.test b/bolt/test/runtime/plt-gnu-ld.test
new file mode 100644
index 000000000000..c1d945884733
--- /dev/null
+++ b/bolt/test/runtime/plt-gnu-ld.test
@@ -0,0 +1,12 @@
+// This test checks that the pointers to PLT are properly updated.
+// The test is using bfd linker, since it may add versioning string
+// to the symbol name e.g. memcpy@@GLIBC_2.17
+
+// REQUIRES: gnu_ld
+
+// RUN: %clang %cflags %p/../Inputs/plt.c -fuse-ld=bfd \
+// RUN: -o %t.bfd.exe -Wl,-q
+// RUN: llvm-bolt %t.bfd.exe -o %t.bfd.bolt.exe -use-old-text=0 -lite=0
+// RUN: %t.bfd.bolt.exe | FileCheck %s
+
+// CHECK: Test completed
diff --git a/bolt/test/runtime/plt-lld.test b/bolt/test/runtime/plt-lld.test
new file mode 100644
index 000000000000..39cb23115ef2
--- /dev/null
+++ b/bolt/test/runtime/plt-lld.test
@@ -0,0 +1,9 @@
+// This test checks that the pointers to PLT are properly updated.
+// The test is using lld linker.
+
+// RUN: %clang %cflags %p/../Inputs/plt.c -fuse-ld=lld \
+// RUN: -o %t.lld.exe -Wl,-q
+// RUN: llvm-bolt %t.lld.exe -o %t.lld.bolt.exe -use-old-text=0 -lite=0
+// RUN: %t.lld.bolt.exe | FileCheck %s
+
+// CHECK: Test completed