parent
fb490a0bcc
commit
9c8f853ca9
|
@ -330,8 +330,8 @@ Symbol *SymbolTable::addUndefined(StringRef Name, bool IsLocal, uint8_t Binding,
|
|||
SS->getFile<ELFT>()->IsUsed = true;
|
||||
}
|
||||
if (auto *L = dyn_cast<Lazy>(S->body())) {
|
||||
// An undefined weak will not fetch archive members, but we have to remember
|
||||
// its type. See also comment in addLazyArchive.
|
||||
// An undefined weak will not fetch archive members. See comment on Lazy in
|
||||
// Symbols.h for the details.
|
||||
if (S->isWeak())
|
||||
L->Type = Type;
|
||||
else if (InputFile *F = L->fetch())
|
||||
|
@ -574,13 +574,8 @@ Symbol *SymbolTable::addLazyArchive(StringRef Name, ArchiveFile *F,
|
|||
if (!S->body()->isUndefined())
|
||||
return S;
|
||||
|
||||
// Weak undefined symbols should not fetch members from archives. If we were
|
||||
// to keep old symbol we would not know that an archive member was available
|
||||
// if a strong undefined symbol shows up afterwards in the link. If a strong
|
||||
// undefined symbol never shows up, this lazy symbol will get to the end of
|
||||
// the link and must be treated as the weak undefined one. We already marked
|
||||
// this symbol as used when we added it to the symbol table, but we also need
|
||||
// to preserve its type. FIXME: Move the Type field to Symbol.
|
||||
// An undefined weak will not fetch archive members. See comment on Lazy in
|
||||
// Symbols.h for the details.
|
||||
if (S->isWeak()) {
|
||||
replaceBody<LazyArchive>(S, F, Sym, S->body()->Type);
|
||||
return S;
|
||||
|
|
|
@ -128,15 +128,7 @@ SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
|
|||
|
||||
// Returns true if this is a weak undefined symbol.
|
||||
bool SymbolBody::isUndefWeak() const {
|
||||
// A note on isLazy() in the following expression: If you add a weak
|
||||
// undefined symbol and then a lazy symbol to the symbol table, the
|
||||
// combined result is a lazy weak symbol. isLazy is for that situation.
|
||||
//
|
||||
// Weak undefined symbols shouldn't fetch archive members (for
|
||||
// compatibility with other linkers), but we still want to memorize
|
||||
// that there are lazy symbols, because strong undefined symbols
|
||||
// could be added later which triggers archive member fetching.
|
||||
// Thus, the weak lazy symbol is a valid concept in lld.
|
||||
// See comment on Lazy in Symbols.h for the details.
|
||||
return !isLocal() && symbol()->isWeak() && (isUndefined() || isLazy());
|
||||
}
|
||||
|
||||
|
|
|
@ -267,11 +267,15 @@ private:
|
|||
const void *ElfSym;
|
||||
};
|
||||
|
||||
// This class represents a symbol defined in an archive file. It is
|
||||
// created from an archive file header, and it knows how to load an
|
||||
// object file from an archive to replace itself with a defined
|
||||
// symbol. If the resolver finds both Undefined and Lazy for
|
||||
// the same name, it will ask the Lazy to load a file.
|
||||
// This represents a symbol that is not yet in the link, but we know where to
|
||||
// find it if needed. If the resolver finds both Undefined and Lazy for the same
|
||||
// name, it will ask the Lazy to load a file.
|
||||
//
|
||||
// A special complication is the handling of weak undefined symbols. They should
|
||||
// not load a file, but we have to remember we have seen both the weak undefined
|
||||
// and the lazy. We represent that with a lazy symbol with a weak binding. This
|
||||
// means that code looking for undefined symbols normally also has to take lazy
|
||||
// symbols into consideration.
|
||||
class Lazy : public SymbolBody {
|
||||
public:
|
||||
static bool classof(const SymbolBody *S) { return S->isLazy(); }
|
||||
|
@ -285,7 +289,10 @@ protected:
|
|||
: SymbolBody(K, Name, /*IsLocal=*/false, llvm::ELF::STV_DEFAULT, Type) {}
|
||||
};
|
||||
|
||||
// LazyArchive symbols represents symbols in archive files.
|
||||
// This class represents a symbol defined in an archive file. It is
|
||||
// created from an archive file header, and it knows how to load an
|
||||
// object file from an archive to replace itself with a defined
|
||||
// symbol.
|
||||
class LazyArchive : public Lazy {
|
||||
public:
|
||||
LazyArchive(const llvm::object::Archive::Symbol S, uint8_t Type);
|
||||
|
|
Loading…
Reference in New Issue