blob: 3e8cb7072cb5c94a08c4af974bfddd6b58fe97de [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"
Rafael Espindola49a2ca62015-08-06 15:33:19 +000012#include "Error.h"
Michael J. Spencercdae0a42015-07-28 22:58:25 +000013#include "InputFiles.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000014
15using namespace llvm::object;
16
17using namespace lld;
18using namespace lld::elf2;
19
Michael J. Spencercdae0a42015-07-28 22:58:25 +000020template <class ELFT>
Rafael Espindola49a2ca62015-08-06 15:33:19 +000021static StringRef
Michael J. Spencercdae0a42015-07-28 22:58:25 +000022getSymbolName(const llvm::object::ELFFile<ELFT> *F,
23 const typename llvm::object::ELFFile<ELFT>::Elf_Sym *S) {
Rafael Espindola49a2ca62015-08-06 15:33:19 +000024 ErrorOr<StringRef> StrTabOrErr =
25 F->getStringTableForSymtab(*F->getDotSymtabSec());
26 error(StrTabOrErr, "Invalid string table.");
27 StringRef StrTab = *StrTabOrErr;
28 if (S->st_name >= StrTab.size())
29 error("Invalid string table offset");
30 return StrTab.data() + S->st_name;
Michael J. Spencercdae0a42015-07-28 22:58:25 +000031}
32
33template <class ELFT>
34DefinedRegular<ELFT>::DefinedRegular(ObjectFile<ELFT> *F, const Elf_Sym *S)
Rafael Espindolae3335d82015-08-05 13:26:54 +000035 : Defined(DefinedRegularKind, getSymbolName<ELFT>(F->getObj(), S)),
36 File(F) {}
Michael J. Spencercdae0a42015-07-28 22:58:25 +000037
Michael J. Spencer84487f12015-07-24 21:03:07 +000038// Returns 1, 0 or -1 if this symbol should take precedence
39// over the Other, tie or lose, respectively.
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000040int SymbolBody::compare(SymbolBody *Other) {
41 Kind LK = kind();
42 Kind RK = Other->kind();
43
44 // Normalize so that the smaller kind is on the left.
45 if (LK > RK)
Michael J. Spencer84487f12015-07-24 21:03:07 +000046 return -Other->compare(this);
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000047
48 // First handle comparisons between two different kinds.
49 if (LK != RK) {
50 assert(LK == DefinedRegularKind);
51 assert(RK == UndefinedKind);
Michael J. Spencer84487f12015-07-24 21:03:07 +000052 return 1;
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000053 }
Michael J. Spencer84487f12015-07-24 21:03:07 +000054
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000055 // Now handle the case where the kinds are the same.
56 switch (LK) {
57 case DefinedRegularKind:
Michael J. Spencer84487f12015-07-24 21:03:07 +000058 return 0;
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000059 case UndefinedKind:
60 return 1;
61 default:
62 llvm_unreachable("unknown symbol kind");
63 }
Michael J. Spencer84487f12015-07-24 21:03:07 +000064}
65
Michael J. Spencer84487f12015-07-24 21:03:07 +000066namespace lld {
67namespace elf2 {
68template class DefinedRegular<llvm::object::ELF32LE>;
69template class DefinedRegular<llvm::object::ELF32BE>;
70template class DefinedRegular<llvm::object::ELF64LE>;
71template class DefinedRegular<llvm::object::ELF64BE>;
72}
73}