blob: 30e219bf11ac7bd947d0c1e9d8a6278bfa0815b0 [file] [log] [blame]
Rui Ueyama411c63602015-05-28 19:09:30 +00001//===- Symbols.cpp --------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Rui Ueyama8fd9fb92015-06-01 02:58:15 +000010#include "Error.h"
Rui Ueyama411c63602015-05-28 19:09:30 +000011#include "InputFiles.h"
12#include "Symbols.h"
Rui Ueyama411c63602015-05-28 19:09:30 +000013#include "llvm/ADT/STLExtras.h"
14#include "llvm/Support/Debug.h"
15#include "llvm/Support/raw_ostream.h"
16
17using namespace llvm::object;
18using llvm::sys::fs::identify_magic;
19using llvm::sys::fs::file_magic;
20
21namespace lld {
22namespace coff {
23
24// Returns 1, 0 or -1 if this symbol should take precedence over the
25// Other in the symbol table, tie or lose, respectively.
26int Defined::compare(SymbolBody *Other) {
27 if (!isa<Defined>(Other))
28 return 1;
29 auto *X = dyn_cast<DefinedRegular>(this);
30 auto *Y = dyn_cast<DefinedRegular>(Other);
31 if (!X || !Y)
32 return 0;
33
34 // Common symbols are weaker than other types of defined symbols.
35 if (X->isCommon() && Y->isCommon())
36 return (X->getCommonSize() < Y->getCommonSize()) ? -1 : 1;
37 // TODO: we are not sure if regular defined symbol and common
38 // symbols are allowed to have the same name.
39 if (X->isCommon())
40 return -1;
41 if (Y->isCommon())
42 return 1;
43
44 if (X->isCOMDAT() && Y->isCOMDAT())
45 return 1;
46 return 0;
47}
48
49int Lazy::compare(SymbolBody *Other) {
50 if (isa<Defined>(Other))
51 return -1;
52
53 // Undefined symbols with weak aliases will turn into defined
54 // symbols if they remain undefined, so we don't need to resolve
55 // such symbols.
56 if (auto *U = dyn_cast<Undefined>(Other))
57 if (U->getWeakAlias())
58 return -1;
59 return 1;
60}
61
62int Undefined::compare(SymbolBody *Other) {
63 if (isa<Defined>(Other))
64 return -1;
65 if (isa<Lazy>(Other))
66 return getWeakAlias() ? 1 : -1;
67 if (cast<Undefined>(Other)->getWeakAlias())
68 return -1;
69 return 1;
70}
71
72ErrorOr<std::unique_ptr<InputFile>> Lazy::getMember() {
73 auto MBRefOrErr = File->getMember(&Sym);
74 if (auto EC = MBRefOrErr.getError())
75 return EC;
76 MemoryBufferRef MBRef = MBRefOrErr.get();
77
78 // getMember returns an empty buffer if the member was already
79 // read from the library.
80 if (MBRef.getBuffer().empty())
81 return std::unique_ptr<InputFile>(nullptr);
82
83 file_magic Magic = identify_magic(MBRef.getBuffer());
Peter Collingbourne60c16162015-06-01 20:10:10 +000084 if (Magic == file_magic::bitcode)
85 return std::unique_ptr<InputFile>(new BitcodeFile(MBRef));
Rui Ueyama411c63602015-05-28 19:09:30 +000086 if (Magic == file_magic::coff_import_library)
87 return std::unique_ptr<InputFile>(new ImportFile(MBRef));
88
Rui Ueyama8fd9fb92015-06-01 02:58:15 +000089 if (Magic != file_magic::coff_object) {
90 llvm::errs() << File->getName() << ": unknown file type\n";
91 return make_error_code(LLDError::InvalidFile);
92 }
Rui Ueyama411c63602015-05-28 19:09:30 +000093
Rui Ueyamad7c2f582015-05-31 21:04:56 +000094 std::unique_ptr<InputFile> Obj(new ObjectFile(MBRef));
Rui Ueyama411c63602015-05-28 19:09:30 +000095 Obj->setParentName(File->getName());
96 return std::move(Obj);
97}
98
99} // namespace coff
100} // namespace lld