blob: b6ac08e9867930b305cea7a70f487b470d542483 [file] [log] [blame]
Michael J. Spencer84487f12015-07-24 21:03:07 +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
10#include "Symbols.h"
11#include "Chunks.h"
Michael J. Spencercdae0a42015-07-28 22:58:25 +000012#include "InputFiles.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000013
14using namespace llvm::object;
15
16using namespace lld;
17using namespace lld::elf2;
18
Michael J. Spencercdae0a42015-07-28 22:58:25 +000019template <class ELFT>
20StringRef
21getSymbolName(const llvm::object::ELFFile<ELFT> *F,
22 const typename llvm::object::ELFFile<ELFT>::Elf_Sym *S) {
23 ErrorOr<StringRef> StrTab = F->getStringTableForSymtab(*F->getDotSymtabSec());
24 if (!StrTab || S->st_name >= StrTab->size())
25 llvm::report_fatal_error("Invalid string table.");
26 return StrTab->data() + S->st_name;
27}
28
29template <class ELFT>
30DefinedRegular<ELFT>::DefinedRegular(ObjectFile<ELFT> *F, const Elf_Sym *S)
Rafael Espindolae3335d82015-08-05 13:26:54 +000031 : Defined(DefinedRegularKind, getSymbolName<ELFT>(F->getObj(), S)),
32 File(F) {}
Michael J. Spencercdae0a42015-07-28 22:58:25 +000033
Michael J. Spencer84487f12015-07-24 21:03:07 +000034// Returns 1, 0 or -1 if this symbol should take precedence
35// over the Other, tie or lose, respectively.
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000036int SymbolBody::compare(SymbolBody *Other) {
37 Kind LK = kind();
38 Kind RK = Other->kind();
39
40 // Normalize so that the smaller kind is on the left.
41 if (LK > RK)
Michael J. Spencer84487f12015-07-24 21:03:07 +000042 return -Other->compare(this);
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000043
44 // First handle comparisons between two different kinds.
45 if (LK != RK) {
46 assert(LK == DefinedRegularKind);
47 assert(RK == UndefinedKind);
Michael J. Spencer84487f12015-07-24 21:03:07 +000048 return 1;
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000049 }
Michael J. Spencer84487f12015-07-24 21:03:07 +000050
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000051 // Now handle the case where the kinds are the same.
52 switch (LK) {
53 case DefinedRegularKind:
Michael J. Spencer84487f12015-07-24 21:03:07 +000054 return 0;
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000055 case UndefinedKind:
56 return 1;
57 default:
58 llvm_unreachable("unknown symbol kind");
59 }
Michael J. Spencer84487f12015-07-24 21:03:07 +000060}
61
Michael J. Spencer84487f12015-07-24 21:03:07 +000062namespace lld {
63namespace elf2 {
64template class DefinedRegular<llvm::object::ELF32LE>;
65template class DefinedRegular<llvm::object::ELF32BE>;
66template class DefinedRegular<llvm::object::ELF64LE>;
67template class DefinedRegular<llvm::object::ELF64BE>;
68}
69}