mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-01 13:20:25 +00:00
[lld] Keep full library path in DT_NEEDED.
Fixes PR32572. When (a) a library has no soname and (b) library is given on the command line with path (and not through -L/-l flags) DT_NEEDED entry for such library keeps the path as given. This behavior is consistent with gold and bfd, and is used in compiler-rt test suite. llvm-svn: 300007
This commit is contained in:
parent
4ecc848ebd
commit
2c2dcae13c
@ -153,7 +153,7 @@ LinkerDriver::getArchiveMembers(MemoryBufferRef MB) {
|
||||
|
||||
// Opens and parses a file. Path has to be resolved already.
|
||||
// Newly created memory buffers are owned by this driver.
|
||||
void LinkerDriver::addFile(StringRef Path) {
|
||||
void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
|
||||
using namespace sys::fs;
|
||||
|
||||
Optional<MemoryBufferRef> Buffer = readFile(Path);
|
||||
@ -184,6 +184,11 @@ void LinkerDriver::addFile(StringRef Path) {
|
||||
return;
|
||||
}
|
||||
Files.push_back(createSharedFile(MBRef));
|
||||
// If the library is found at an explicitly given path use the entire path
|
||||
// as he default soname. Such libraries should not require RPATH or
|
||||
// LD_LIBRARY_PATH to run.
|
||||
Files.back()->DefaultSoName =
|
||||
WithLOption ? sys::path::filename(Path) : Path;
|
||||
return;
|
||||
default:
|
||||
if (InLib)
|
||||
@ -196,7 +201,7 @@ void LinkerDriver::addFile(StringRef Path) {
|
||||
// Add a given library by searching it from input search paths.
|
||||
void LinkerDriver::addLibrary(StringRef Name) {
|
||||
if (Optional<std::string> Path = searchLibrary(Name))
|
||||
addFile(*Path);
|
||||
addFile(*Path, /*WithLOption=*/true);
|
||||
else
|
||||
error("unable to find library -l" + Name);
|
||||
}
|
||||
@ -762,7 +767,7 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
|
||||
addLibrary(Arg->getValue());
|
||||
break;
|
||||
case OPT_INPUT:
|
||||
addFile(Arg->getValue());
|
||||
addFile(Arg->getValue(), /*WithLOption=*/false);
|
||||
break;
|
||||
case OPT_alias_script_T:
|
||||
case OPT_script:
|
||||
|
@ -27,7 +27,7 @@ extern class LinkerDriver *Driver;
|
||||
class LinkerDriver {
|
||||
public:
|
||||
void main(ArrayRef<const char *> Args, bool CanExitEarly);
|
||||
void addFile(StringRef Path);
|
||||
void addFile(StringRef Path, bool WithLOption);
|
||||
void addLibrary(StringRef Name);
|
||||
|
||||
private:
|
||||
|
@ -661,7 +661,7 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() {
|
||||
// DSOs are identified by soname, and they usually contain
|
||||
// DT_SONAME tag in their header. But if they are missing,
|
||||
// filenames are used as default sonames.
|
||||
SoName = sys::path::filename(this->getName());
|
||||
SoName = this->DefaultSoName;
|
||||
|
||||
if (!DynamicSec)
|
||||
return;
|
||||
|
@ -93,6 +93,10 @@ public:
|
||||
uint16_t EMachine = llvm::ELF::EM_NONE;
|
||||
uint8_t OSABI = 0;
|
||||
|
||||
// For SharedKind inputs, the string to use in DT_NEEDED when the library
|
||||
// has no soname.
|
||||
std::string DefaultSoName;
|
||||
|
||||
// Cache for toString(). Only toString() should use this member.
|
||||
mutable std::string ToStringCache;
|
||||
|
||||
|
@ -243,25 +243,26 @@ void ScriptParser::addFile(StringRef S) {
|
||||
SmallString<128> PathData;
|
||||
StringRef Path = (Config->Sysroot + S).toStringRef(PathData);
|
||||
if (sys::fs::exists(Path)) {
|
||||
Driver->addFile(Saver.save(Path));
|
||||
Driver->addFile(Saver.save(Path), /*WithLOption=*/false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sys::path::is_absolute(S)) {
|
||||
Driver->addFile(S);
|
||||
Driver->addFile(S, /*WithLOption=*/false);
|
||||
} else if (S.startswith("=")) {
|
||||
if (Config->Sysroot.empty())
|
||||
Driver->addFile(S.substr(1));
|
||||
Driver->addFile(S.substr(1), /*WithLOption=*/false);
|
||||
else
|
||||
Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
|
||||
Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)),
|
||||
/*WithLOption=*/false);
|
||||
} else if (S.startswith("-l")) {
|
||||
Driver->addLibrary(S.substr(2));
|
||||
} else if (sys::fs::exists(S)) {
|
||||
Driver->addFile(S);
|
||||
Driver->addFile(S, /*WithLOption=*/false);
|
||||
} else {
|
||||
if (Optional<std::string> Path = findFromSearchPaths(S))
|
||||
Driver->addFile(Saver.save(*Path));
|
||||
Driver->addFile(Saver.save(*Path), /*WithLOption=*/true);
|
||||
else
|
||||
setError("unable to find " + S);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
# CHECK-NEXT: Other: 0
|
||||
# CHECK-NEXT: Section: Undefined
|
||||
|
||||
# CHECK: NEEDED SharedLibrary (as-needed-no-reloc{{.*}}2.so)
|
||||
# CHECK: NEEDED SharedLibrary ({{.*}}as-needed-no-reloc{{.*}}2.so)
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
|
31
lld/test/ELF/no-soname.s
Normal file
31
lld/test/ELF/no-soname.s
Normal file
@ -0,0 +1,31 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
// RUN: mkdir -p %T/no-soname
|
||||
// RUN: ld.lld %t.o -shared -o %T/no-soname/libfoo.so
|
||||
|
||||
// RUN: ld.lld %t.o %T/no-soname/libfoo.so -o %t
|
||||
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
|
||||
|
||||
// CHECK: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}/no-soname/libfoo.so)
|
||||
// CHECK-NOT: NEEDED
|
||||
|
||||
// RUN: ld.lld %t.o %T/no-soname/../no-soname/libfoo.so -o %t
|
||||
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK2
|
||||
|
||||
// CHECK2: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}/no-soname/../no-soname/libfoo.so)
|
||||
// CHECK2-NOT: NEEDED
|
||||
|
||||
// RUN: ld.lld %t.o -L%T/no-soname/../no-soname -lfoo -o %t
|
||||
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK3
|
||||
|
||||
// CHECK3: 0x0000000000000001 NEEDED SharedLibrary (libfoo.so)
|
||||
// CHECK3-NOT: NEEDED
|
||||
|
||||
// RUN: ld.lld %t.o -shared -soname libbar.so -o %T/no-soname/libbar.so
|
||||
// RUN: ld.lld %t.o %T/no-soname/libbar.so -o %t
|
||||
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK4
|
||||
|
||||
// CHECK4: 0x0000000000000001 NEEDED SharedLibrary (libbar.so)
|
||||
// CHECK4-NOT: NEEDED
|
||||
|
||||
.global _start
|
||||
_start:
|
@ -10,16 +10,20 @@
|
||||
# NORELRO-NEXT: 0 00000000 0000000000000000
|
||||
# NORELRO-NEXT: 1 .dynsym 00000048 0000000000200120
|
||||
# NORELRO-NEXT: 2 .hash 00000020 0000000000200168
|
||||
# NORELRO-NEXT: 3 .dynstr 00000021 0000000000200188
|
||||
# NORELRO-NEXT: 4 .rela.dyn 00000018 00000000002001b0
|
||||
# NORELRO-NEXT: 5 .rela.plt 00000018 00000000002001c8
|
||||
# NORELRO-NEXT: 6 .text 0000000a 00000000002001e0 TEXT DATA
|
||||
# NORELRO-NEXT: 7 .plt 00000020 00000000002001f0 TEXT DATA
|
||||
# NORELRO-NEXT: 8 .data 00000008 0000000000200210 DATA
|
||||
# NORELRO-NEXT: 9 .foo 00000004 0000000000200218 DATA
|
||||
# NORELRO-NEXT: 10 .dynamic 000000f0 0000000000200220
|
||||
# NORELRO-NEXT: 11 .got 00000008 0000000000200310 DATA
|
||||
# NORELRO-NEXT: 12 .got.plt 00000020 0000000000200318 DATA
|
||||
# NORELRO-NEXT: 3 .dynstr 0000004c 0000000000200188
|
||||
# NORELRO-NEXT: 4 .rela.dyn 00000018 00000000002001d8
|
||||
# NORELRO-NEXT: 5 .rela.plt 00000018 00000000002001f0
|
||||
# NORELRO-NEXT: 6 .text 0000000a 0000000000200208 TEXT DATA
|
||||
# NORELRO-NEXT: 7 .plt 00000020 0000000000200220 TEXT DATA
|
||||
# NORELRO-NEXT: 8 .data 00000008 0000000000200240 DATA
|
||||
# NORELRO-NEXT: 9 .foo 00000004 0000000000200248 DATA
|
||||
# NORELRO-NEXT: 10 .dynamic 000000f0 0000000000200250
|
||||
# NORELRO-NEXT: 11 .got 00000008 0000000000200340 DATA
|
||||
# NORELRO-NEXT: 12 .got.plt 00000020 0000000000200348 DATA
|
||||
# NORELRO-NEXT: 13 .comment 00000008 0000000000000000
|
||||
# NORELRO-NEXT: 14 .symtab 00000060 0000000000000000
|
||||
# NORELRO-NEXT: 15 .shstrtab 0000007b 0000000000000000
|
||||
# NORELRO-NEXT: 16 .strtab 00000013 0000000000000000
|
||||
|
||||
# NOPHDRS: ProgramHeaders [
|
||||
# NOPHDRS-NOT: PT_GNU_RELRO
|
||||
|
Loading…
Reference in New Issue
Block a user