summaryrefslogtreecommitdiff
path: root/COFF/Symbols.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'COFF/Symbols.cpp')
-rw-r--r--COFF/Symbols.cpp178
1 files changed, 23 insertions, 155 deletions
diff --git a/COFF/Symbols.cpp b/COFF/Symbols.cpp
index 6e2db6631ce7..6de85d581f49 100644
--- a/COFF/Symbols.cpp
+++ b/COFF/Symbols.cpp
@@ -7,16 +7,17 @@
//
//===----------------------------------------------------------------------===//
+#include "Symbols.h"
#include "Error.h"
#include "InputFiles.h"
-#include "Symbols.h"
+#include "Memory.h"
+#include "Strings.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
using namespace llvm::object;
-using llvm::sys::fs::identify_magic;
-using llvm::sys::fs::file_magic;
namespace lld {
namespace coff {
@@ -36,130 +37,14 @@ StringRef SymbolBody::getName() {
return Name;
}
-// Returns 1, 0 or -1 if this symbol should take precedence
-// over the Other, tie or lose, respectively.
-int SymbolBody::compare(SymbolBody *Other) {
- Kind LK = kind(), RK = Other->kind();
-
- // Normalize so that the smaller kind is on the left.
- if (LK > RK)
- return -Other->compare(this);
-
- // First handle comparisons between two different kinds.
- if (LK != RK) {
- if (RK > LastDefinedKind) {
- if (LK == LazyKind && cast<Undefined>(Other)->WeakAlias)
- return -1;
-
- // The LHS is either defined or lazy and so it wins.
- assert((LK <= LastDefinedKind || LK == LazyKind) && "Bad kind!");
- return 1;
- }
-
- // Bitcode has special complexities.
- if (RK == DefinedBitcodeKind) {
- auto *RHS = cast<DefinedBitcode>(Other);
-
- switch (LK) {
- case DefinedCommonKind:
- return 1;
-
- case DefinedRegularKind:
- // As an approximation, regular symbols win over bitcode symbols,
- // but we definitely have a conflict if the regular symbol is not
- // replaceable and neither is the bitcode symbol. We do not
- // replicate the rest of the symbol resolution logic here; symbol
- // resolution will be done accurately after lowering bitcode symbols
- // to regular symbols in addCombinedLTOObject().
- if (cast<DefinedRegular>(this)->isCOMDAT() || RHS->IsReplaceable)
- return 1;
-
- // Fallthrough to the default of a tie otherwise.
- default:
- return 0;
- }
- }
-
- // Either of the object file kind will trump a higher kind.
- if (LK <= LastDefinedCOFFKind)
- return 1;
-
- // The remaining kind pairs are ties amongst defined symbols.
- return 0;
- }
-
- // Now handle the case where the kinds are the same.
- switch (LK) {
- case DefinedRegularKind: {
- auto *LHS = cast<DefinedRegular>(this);
- auto *RHS = cast<DefinedRegular>(Other);
- if (LHS->isCOMDAT() && RHS->isCOMDAT())
- return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1;
- return 0;
- }
-
- case DefinedCommonKind: {
- auto *LHS = cast<DefinedCommon>(this);
- auto *RHS = cast<DefinedCommon>(Other);
- if (LHS->getSize() == RHS->getSize())
- return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1;
- return LHS->getSize() > RHS->getSize() ? 1 : -1;
- }
-
- case DefinedBitcodeKind: {
- auto *LHS = cast<DefinedBitcode>(this);
- auto *RHS = cast<DefinedBitcode>(Other);
- // If both are non-replaceable, we have a tie.
- if (!LHS->IsReplaceable && !RHS->IsReplaceable)
- return 0;
-
- // Non-replaceable symbols win, but even two replaceable symboles don't
- // tie. If both symbols are replaceable, choice is arbitrary.
- if (RHS->IsReplaceable && LHS->IsReplaceable)
- return uintptr_t(LHS) < uintptr_t(RHS) ? 1 : -1;
- return LHS->IsReplaceable ? -1 : 1;
- }
-
- case LazyKind: {
- // Don't tie, pick the earliest.
- auto *LHS = cast<Lazy>(this);
- auto *RHS = cast<Lazy>(Other);
- return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1;
- }
-
- case UndefinedKind: {
- auto *LHS = cast<Undefined>(this);
- auto *RHS = cast<Undefined>(Other);
- // Tie if both undefined symbols have different weak aliases.
- if (LHS->WeakAlias && RHS->WeakAlias) {
- if (LHS->WeakAlias->getName() != RHS->WeakAlias->getName())
- return 0;
- return uintptr_t(LHS) < uintptr_t(RHS) ? 1 : -1;
- }
- return LHS->WeakAlias ? 1 : -1;
- }
-
- case DefinedLocalImportKind:
- case DefinedImportThunkKind:
- case DefinedImportDataKind:
- case DefinedAbsoluteKind:
- case DefinedRelativeKind:
- // These all simply tie.
- return 0;
- }
- llvm_unreachable("unknown symbol kind");
-}
-
-std::string SymbolBody::getDebugName() {
- std::string N = getName().str();
- if (auto *D = dyn_cast<DefinedCOFF>(this)) {
- N += " ";
- N += D->File->getShortName();
- } else if (auto *D = dyn_cast<DefinedBitcode>(this)) {
- N += " ";
- N += D->File->getShortName();
- }
- return N;
+InputFile *SymbolBody::getFile() {
+ if (auto *Sym = dyn_cast<DefinedCOFF>(this))
+ return Sym->File;
+ if (auto *Sym = dyn_cast<DefinedBitcode>(this))
+ return Sym->File;
+ if (auto *Sym = dyn_cast<Lazy>(this))
+ return Sym->File;
+ return nullptr;
}
COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
@@ -174,44 +59,27 @@ DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
uint16_t Machine)
: Defined(DefinedImportThunkKind, Name) {
switch (Machine) {
- case AMD64: Data.reset(new ImportThunkChunkX64(S)); return;
- case I386: Data.reset(new ImportThunkChunkX86(S)); return;
- case ARMNT: Data.reset(new ImportThunkChunkARM(S)); return;
+ case AMD64: Data = make<ImportThunkChunkX64>(S); return;
+ case I386: Data = make<ImportThunkChunkX86>(S); return;
+ case ARMNT: Data = make<ImportThunkChunkARM>(S); return;
default: llvm_unreachable("unknown machine type");
}
}
-std::unique_ptr<InputFile> Lazy::getMember() {
- MemoryBufferRef MBRef = File->getMember(&Sym);
-
- // getMember returns an empty buffer if the member was already
- // read from the library.
- if (MBRef.getBuffer().empty())
- return std::unique_ptr<InputFile>(nullptr);
-
- file_magic Magic = identify_magic(MBRef.getBuffer());
- if (Magic == file_magic::coff_import_library)
- return std::unique_ptr<InputFile>(new ImportFile(MBRef));
-
- std::unique_ptr<InputFile> Obj;
- if (Magic == file_magic::coff_object)
- Obj.reset(new ObjectFile(MBRef));
- else if (Magic == file_magic::bitcode)
- Obj.reset(new BitcodeFile(MBRef));
- else
- fatal("unknown file type: " + File->getName());
-
- Obj->setParentName(File->getName());
- return Obj;
-}
-
Defined *Undefined::getWeakAlias() {
// A weak alias may be a weak alias to another symbol, so check recursively.
for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias)
- if (auto *D = dyn_cast<Defined>(A->repl()))
+ if (auto *D = dyn_cast<Defined>(A))
return D;
return nullptr;
}
+// Returns a symbol name for an error message.
+std::string toString(SymbolBody &B) {
+ if (Optional<std::string> S = demangle(B.getName()))
+ return ("\"" + *S + "\" (" + B.getName() + ")").str();
+ return B.getName();
+}
+
} // namespace coff
} // namespace lld