blob: eedacfa22780cdad1f72c2f09330652024572ccb [file] [log] [blame]
Michael J. Spencer84487f12015-07-24 21:03:07 +00001//===- InputFiles.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 "InputFiles.h"
11#include "Chunks.h"
Rafael Espindola192e1fa2015-08-06 15:08:23 +000012#include "Error.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000013#include "Symbols.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000014#include "llvm/ADT/STLExtras.h"
15
Michael J. Spencer1b348a62015-09-04 22:28:10 +000016using namespace llvm;
Michael J. Spencer84487f12015-07-24 21:03:07 +000017using namespace llvm::ELF;
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000018using namespace llvm::object;
Michael J. Spencer84487f12015-07-24 21:03:07 +000019
20using namespace lld;
21using namespace lld::elf2;
22
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000023template <class ELFT> static uint16_t getEMachine(const ELFFileBase &B) {
24 bool IsShared = isa<SharedFileBase>(B);
25 if (IsShared)
26 return cast<SharedFile<ELFT>>(B).getEMachine();
27 return cast<ObjectFile<ELFT>>(B).getEMachine();
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000028}
29
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000030static uint16_t getEMachine(const ELFFileBase &B) {
31 ELFKind K = B.getELFKind();
32 switch (K) {
33 case ELF32BEKind:
34 return getEMachine<ELF32BE>(B);
35 case ELF32LEKind:
36 return getEMachine<ELF32LE>(B);
37 case ELF64BEKind:
38 return getEMachine<ELF64BE>(B);
39 case ELF64LEKind:
40 return getEMachine<ELF64LE>(B);
41 }
Rafael Espindola55eed7ef2015-09-03 22:25:11 +000042 llvm_unreachable("Invalid kind");
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000043}
44
45bool ELFFileBase::isCompatibleWith(const ELFFileBase &Other) const {
46 return getELFKind() == Other.getELFKind() &&
47 getEMachine(*this) == getEMachine(Other);
48}
49
50template <class ELFT> void ELFData<ELFT>::openELF(MemoryBufferRef MB) {
Michael J. Spencer84487f12015-07-24 21:03:07 +000051 // Parse a memory buffer as a ELF file.
52 std::error_code EC;
53 ELFObj = llvm::make_unique<ELFFile<ELFT>>(MB.getBuffer(), EC);
54 error(EC);
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000055}
56
57template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
58 this->openELF(MB);
Michael J. Spencer84487f12015-07-24 21:03:07 +000059
60 // Read section and symbol tables.
61 initializeChunks();
62 initializeSymbols();
63}
64
65template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() {
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000066 uint64_t Size = this->ELFObj->getNumSections();
Rafael Espindola832b93f2015-08-24 20:06:32 +000067 Chunks.resize(Size);
68 unsigned I = 0;
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000069 for (const Elf_Shdr &Sec : this->ELFObj->sections()) {
Rafael Espindolacde25132015-08-13 14:45:44 +000070 switch (Sec.sh_type) {
71 case SHT_SYMTAB:
Rafael Espindolad8340da2015-08-10 15:12:17 +000072 Symtab = &Sec;
Rafael Espindolacde25132015-08-13 14:45:44 +000073 break;
Rafael Espindola20348222015-08-24 21:43:25 +000074 case SHT_SYMTAB_SHNDX: {
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000075 ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable =
76 this->ELFObj->getSHNDXTable(Sec);
Rafael Espindola20348222015-08-24 21:43:25 +000077 error(ErrorOrTable);
78 SymtabSHNDX = *ErrorOrTable;
79 break;
80 }
Rafael Espindolacde25132015-08-13 14:45:44 +000081 case SHT_STRTAB:
82 case SHT_NULL:
Rafael Espindolacde25132015-08-13 14:45:44 +000083 break;
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000084 case SHT_RELA:
85 case SHT_REL: {
86 uint32_t RelocatedSectionIndex = Sec.sh_info;
87 if (RelocatedSectionIndex >= Size)
88 error("Invalid relocated section index");
89 SectionChunk<ELFT> *RelocatedSection = Chunks[RelocatedSectionIndex];
90 if (!RelocatedSection)
91 error("Unsupported relocation reference");
92 RelocatedSection->RelocSections.push_back(&Sec);
93 break;
94 }
Rafael Espindolacde25132015-08-13 14:45:44 +000095 default:
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000096 Chunks[I] = new (Alloc) SectionChunk<ELFT>(this, &Sec);
Rafael Espindolacde25132015-08-13 14:45:44 +000097 break;
Michael J. Spencer84487f12015-07-24 21:03:07 +000098 }
Rafael Espindola832b93f2015-08-24 20:06:32 +000099 ++I;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000100 }
101}
102
103template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
Michael J. Spencer84487f12015-07-24 21:03:07 +0000104 ErrorOr<StringRef> StringTableOrErr =
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000105 this->ELFObj->getStringTableForSymtab(*Symtab);
Michael J. Spencer84487f12015-07-24 21:03:07 +0000106 error(StringTableOrErr.getError());
107 StringRef StringTable = *StringTableOrErr;
108
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000109 Elf_Sym_Range Syms = this->ELFObj->symbols(Symtab);
Reid Klecknerf7b85e02015-08-11 20:06:51 +0000110 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
Rafael Espindola7c388182015-08-11 16:30:34 +0000111 uint32_t FirstNonLocal = Symtab->sh_info;
112 if (FirstNonLocal > NumSymbols)
113 error("Invalid sh_info in symbol table");
114 Syms = llvm::make_range(Syms.begin() + FirstNonLocal, Syms.end());
Davide Italiano34812ba2015-09-03 20:25:54 +0000115 SymbolBodies.reserve(NumSymbols - FirstNonLocal);
Rafael Espindola30318512015-08-04 14:00:56 +0000116 for (const Elf_Sym &Sym : Syms)
117 SymbolBodies.push_back(createSymbolBody(StringTable, &Sym));
Michael J. Spencer84487f12015-07-24 21:03:07 +0000118}
119
120template <class ELFT>
121SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
122 const Elf_Sym *Sym) {
123 ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
124 error(NameOrErr.getError());
125 StringRef Name = *NameOrErr;
Rafael Espindola20348222015-08-24 21:43:25 +0000126
127 uint32_t SecIndex = Sym->st_shndx;
Rafael Espindola51d46902015-08-28 21:26:51 +0000128 switch (SecIndex) {
129 case SHN_ABS:
Rafael Espindola0e0c1902015-08-27 12:40:06 +0000130 return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym);
Rafael Espindola51d46902015-08-28 21:26:51 +0000131 case SHN_UNDEF:
132 return new (Alloc) Undefined<ELFT>(Name, *Sym);
133 case SHN_COMMON:
134 return new (Alloc) DefinedCommon<ELFT>(Name, *Sym);
135 case SHN_XINDEX:
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000136 SecIndex =
137 this->ELFObj->getExtendedSymbolTableIndex(Sym, Symtab, SymtabSHNDX);
Rafael Espindola51d46902015-08-28 21:26:51 +0000138 break;
139 }
Rafael Espindola20348222015-08-24 21:43:25 +0000140
Rafael Espindola5cd113d2015-08-24 22:00:25 +0000141 if (SecIndex >= Chunks.size() ||
142 (SecIndex != 0 && !Chunks[SecIndex]))
143 error("Invalid section index");
144
Rafael Espindolab13df652015-08-11 17:33:02 +0000145 switch (Sym->getBinding()) {
146 default:
147 error("unexpected binding");
148 case STB_GLOBAL:
Rafael Espindola3a63f3f2015-08-28 20:19:34 +0000149 case STB_WEAK:
Rafael Espindola832b93f2015-08-24 20:06:32 +0000150 return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Chunks[SecIndex]);
Rafael Espindolab13df652015-08-11 17:33:02 +0000151 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000152}
153
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000154void ArchiveFile::parse() {
155 auto ArchiveOrErr = Archive::create(MB);
156 error(ArchiveOrErr, "Failed to parse archive");
157 File = std::move(*ArchiveOrErr);
158
159 // Allocate a buffer for Lazy objects.
160 size_t NumSyms = File->getNumberOfSymbols();
161 LazySymbols.reserve(NumSyms);
162
163 // Read the symbol table to construct Lazy objects.
164 for (const Archive::Symbol &Sym : File->symbols())
165 LazySymbols.emplace_back(this, Sym);
166}
167
168// Returns a buffer pointing to a member file containing a given symbol.
169MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
170 ErrorOr<Archive::child_iterator> ItOrErr = Sym->getMember();
171 error(ItOrErr,
172 Twine("Could not get the member for symbol ") + Sym->getName());
173 Archive::child_iterator It = *ItOrErr;
174
175 if (!Seen.insert(It->getChildOffset()).second) {
176 return MemoryBufferRef();
177 }
178 ErrorOr<MemoryBufferRef> Ret = It->getMemoryBufferRef();
179 error(Ret, Twine("Could not get the buffer for the member defining symbol ") +
180 Sym->getName());
181 return *Ret;
182}
183
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000184template <class ELFT> void SharedFile<ELFT>::parse() { this->openELF(MB); }
185
Michael J. Spencer84487f12015-07-24 21:03:07 +0000186namespace lld {
187namespace elf2 {
188template class elf2::ObjectFile<llvm::object::ELF32LE>;
189template class elf2::ObjectFile<llvm::object::ELF32BE>;
190template class elf2::ObjectFile<llvm::object::ELF64LE>;
191template class elf2::ObjectFile<llvm::object::ELF64BE>;
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000192
193template class elf2::SharedFile<llvm::object::ELF32LE>;
194template class elf2::SharedFile<llvm::object::ELF32BE>;
195template class elf2::SharedFile<llvm::object::ELF64LE>;
196template class elf2::SharedFile<llvm::object::ELF64BE>;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000197}
198}