mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-01 13:20:25 +00:00
Don't include --start-lib/--end-lib files twice.
This should never happen with correct programs, but it is trivial write a testcase where lld would crash or report duplicated symbols. We now behave like when an archive is used and include the file only once. llvm-svn: 272724
This commit is contained in:
parent
a0dd66423d
commit
65c65ce897
@ -691,10 +691,17 @@ std::unique_ptr<InputFile> elf::createSharedFile(MemoryBufferRef MB) {
|
||||
return createELFFile<SharedFile>(MB);
|
||||
}
|
||||
|
||||
MemoryBufferRef LazyObjectFile::getBuffer() {
|
||||
if (Seen)
|
||||
return MemoryBufferRef();
|
||||
Seen = true;
|
||||
return MB;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LazyObjectFile::parse() {
|
||||
for (StringRef Sym : getSymbols())
|
||||
Symtab<ELFT>::X->addLazyObject(Sym, this->MB);
|
||||
Symtab<ELFT>::X->addLazyObject(Sym, *this);
|
||||
}
|
||||
|
||||
template <class ELFT> std::vector<StringRef> LazyObjectFile::getElfSymbols() {
|
||||
|
@ -190,6 +190,7 @@ public:
|
||||
}
|
||||
|
||||
template <class ELFT> void parse();
|
||||
MemoryBufferRef getBuffer();
|
||||
|
||||
private:
|
||||
std::vector<StringRef> getSymbols();
|
||||
@ -198,6 +199,7 @@ private:
|
||||
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
llvm::StringSaver Saver{Alloc};
|
||||
bool Seen = false;
|
||||
};
|
||||
|
||||
// An ArchiveFile object represents a .a file.
|
||||
|
@ -457,22 +457,25 @@ void SymbolTable<ELFT>::addLazyArchive(
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void SymbolTable<ELFT>::addLazyObject(StringRef Name, MemoryBufferRef MBRef) {
|
||||
void SymbolTable<ELFT>::addLazyObject(StringRef Name, LazyObjectFile &Obj) {
|
||||
Symbol *S;
|
||||
bool WasInserted;
|
||||
std::tie(S, WasInserted) = insert(Name);
|
||||
if (WasInserted) {
|
||||
replaceBody<LazyObject>(S, Name, MBRef, SymbolBody::UnknownType);
|
||||
replaceBody<LazyObject>(S, Name, Obj, SymbolBody::UnknownType);
|
||||
return;
|
||||
}
|
||||
if (!S->body()->isUndefined())
|
||||
return;
|
||||
|
||||
// See comment for addLazyArchive above.
|
||||
if (S->isWeak())
|
||||
replaceBody<LazyObject>(S, Name, MBRef, S->body()->Type);
|
||||
else
|
||||
addFile(createObjectFile(MBRef));
|
||||
if (S->isWeak()) {
|
||||
replaceBody<LazyObject>(S, Name, Obj, S->body()->Type);
|
||||
} else {
|
||||
MemoryBufferRef MBRef = Obj.getBuffer();
|
||||
if (!MBRef.getBuffer().empty())
|
||||
addFile(createObjectFile(MBRef));
|
||||
}
|
||||
}
|
||||
|
||||
// Process undefined (-u) flags by loading lazy symbols named by those flags.
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
const typename ELFT::Verdef *Verdef);
|
||||
|
||||
void addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S);
|
||||
void addLazyObject(StringRef Name, MemoryBufferRef MBRef);
|
||||
void addLazyObject(StringRef Name, LazyObjectFile &Obj);
|
||||
Symbol *addBitcode(StringRef Name, bool IsWeak, uint8_t StOther, uint8_t Type,
|
||||
bool CanOmitFromDynSym, BitcodeFile *File);
|
||||
|
||||
|
@ -231,6 +231,9 @@ std::unique_ptr<InputFile> LazyArchive::getFile() {
|
||||
}
|
||||
|
||||
std::unique_ptr<InputFile> LazyObject::getFile() {
|
||||
MemoryBufferRef MBRef = File.getBuffer();
|
||||
if (MBRef.getBuffer().empty())
|
||||
return std::unique_ptr<InputFile>(nullptr);
|
||||
return createObjectFile(MBRef);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ namespace elf {
|
||||
class ArchiveFile;
|
||||
class BitcodeFile;
|
||||
class InputFile;
|
||||
class LazyObjectFile;
|
||||
class SymbolBody;
|
||||
template <class ELFT> class ObjectFile;
|
||||
template <class ELFT> class OutputSection;
|
||||
@ -351,8 +352,8 @@ private:
|
||||
// --start-lib and --end-lib options.
|
||||
class LazyObject : public Lazy {
|
||||
public:
|
||||
LazyObject(StringRef Name, MemoryBufferRef M, uint8_t Type)
|
||||
: Lazy(LazyObjectKind, Name, Type), MBRef(M) {}
|
||||
LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type)
|
||||
: Lazy(LazyObjectKind, Name, Type), File(File) {}
|
||||
|
||||
static bool classof(const SymbolBody *S) {
|
||||
return S->kind() == LazyObjectKind;
|
||||
@ -361,7 +362,7 @@ public:
|
||||
std::unique_ptr<InputFile> getFile();
|
||||
|
||||
private:
|
||||
MemoryBufferRef MBRef;
|
||||
LazyObjectFile &File;
|
||||
};
|
||||
|
||||
// Some linker-generated symbols need to be created as
|
||||
|
5
lld/test/ELF/Inputs/start-lib-comdat.s
Normal file
5
lld/test/ELF/Inputs/start-lib-comdat.s
Normal file
@ -0,0 +1,5 @@
|
||||
.global bar
|
||||
bar:
|
||||
.section .sec,"aG",@progbits,zed,comdat
|
||||
.global zed
|
||||
zed:
|
23
lld/test/ELF/start-lib-comdat.s
Normal file
23
lld/test/ELF/start-lib-comdat.s
Normal file
@ -0,0 +1,23 @@
|
||||
// REQUIRES: x86
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
|
||||
// RUN: %p/Inputs/start-lib-comdat.s -o %t2.o
|
||||
// RUN: ld.lld -shared -o %t3 %t1.o --start-lib %t2.o --end-lib
|
||||
// RUN: llvm-readobj -t %t3 | FileCheck %s
|
||||
// RUN: ld.lld -shared -o %t3 --start-lib %t2.o --end-lib %t1.o
|
||||
// RUN: llvm-readobj -t %t3 | FileCheck %s
|
||||
|
||||
// CHECK: Name: zed
|
||||
// CHECK-NEXT: Value:
|
||||
// CHECK-NEXT: Size:
|
||||
// CHECK-NEXT: Binding: Global
|
||||
// CHECK-NEXT: Type:
|
||||
// CHECK-NEXT: Other:
|
||||
// CHECK-NEXT: Section: Undefined
|
||||
|
||||
call bar@plt
|
||||
// The other file also has a section in the zed comdat, but it defines the
|
||||
// symbol zed. That means that we will have a lazy symbol zed, but when adding
|
||||
// the actual file zed will be undefined.
|
||||
.section .sec,"aG",@progbits,zed,comdat
|
Loading…
Reference in New Issue
Block a user