blob: c7b0e0887566b151d5f02aa289dc58499ae8096c [file] [log] [blame]
Michael J. Spencer84487f12015-07-24 21:03:07 +00001//===- SymbolTable.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
10#include "SymbolTable.h"
11#include "Driver.h"
12#include "Symbols.h"
13
14using namespace llvm;
15
16using namespace lld;
17using namespace lld::elf2;
18
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000019SymbolTable::SymbolTable() { resolve(new (Alloc) Undefined("_start")); }
Michael J. Spencer84487f12015-07-24 21:03:07 +000020
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000021void SymbolTable::addFile(std::unique_ptr<InputFile> File) {
Michael J. Spencer84487f12015-07-24 21:03:07 +000022 File->parse();
23 InputFile *FileP = File.release();
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000024 auto *P = cast<ObjectFileBase>(FileP);
Michael J. Spencer84487f12015-07-24 21:03:07 +000025 addObject(P);
Michael J. Spencer84487f12015-07-24 21:03:07 +000026}
27
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000028void SymbolTable::addObject(ObjectFileBase *File) {
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000029 if (!ObjectFiles.empty()) {
30 ObjectFileBase &Old = *ObjectFiles[0];
31 if (!Old.isCompatibleWith(*File))
32 error(Twine(Old.getName() + " is incompatible with " + File->getName()));
33 }
34
Michael J. Spencer84487f12015-07-24 21:03:07 +000035 ObjectFiles.emplace_back(File);
36 for (SymbolBody *Body : File->getSymbols())
37 if (Body->isExternal())
38 resolve(Body);
39}
40
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000041void SymbolTable::reportRemainingUndefines() {
Michael J. Spencer84487f12015-07-24 21:03:07 +000042 for (auto &I : Symtab) {
43 Symbol *Sym = I.second;
44 if (auto *Undef = dyn_cast<Undefined>(Sym->Body))
45 error(Twine("undefined symbol: ") + Undef->getName());
46 }
47}
48
49// This function resolves conflicts if there's an existing symbol with
50// the same name. Decisions are made based on symbol type.
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000051void SymbolTable::resolve(SymbolBody *New) {
Michael J. Spencer84487f12015-07-24 21:03:07 +000052 // Find an existing Symbol or create and insert a new one.
53 StringRef Name = New->getName();
54 Symbol *&Sym = Symtab[Name];
55 if (!Sym) {
56 Sym = new (Alloc) Symbol(New);
57 New->setBackref(Sym);
58 return;
59 }
60 New->setBackref(Sym);
61
62 // compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
63 // equivalent (conflicting), or more preferable, respectively.
64 SymbolBody *Existing = Sym->Body;
65 int comp = Existing->compare(New);
66 if (comp < 0)
67 Sym->Body = New;
68 if (comp == 0)
69 error(Twine("duplicate symbol: ") + Name);
70}