blob: 8e3b1689884aadc7f3448df7f785cfb70f72a260 [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
16using namespace llvm::ELF;
17
18using namespace lld;
19using namespace lld::elf2;
20
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000021template <class ELFT>
22bool ObjectFile<ELFT>::isCompatibleWith(const ObjectFileBase &Other) const {
23 if (kind() != Other.kind())
24 return false;
25 return getObj()->getHeader()->e_machine ==
26 cast<ObjectFile<ELFT>>(Other).getObj()->getHeader()->e_machine;
27}
28
Michael J. Spencer84487f12015-07-24 21:03:07 +000029template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
30 // Parse a memory buffer as a ELF file.
31 std::error_code EC;
32 ELFObj = llvm::make_unique<ELFFile<ELFT>>(MB.getBuffer(), EC);
33 error(EC);
34
35 // Read section and symbol tables.
36 initializeChunks();
37 initializeSymbols();
38}
39
40template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() {
41 uint64_t Size = ELFObj->getNumSections();
Rafael Espindola832b93f2015-08-24 20:06:32 +000042 Chunks.resize(Size);
43 unsigned I = 0;
Michael J. Spencer84487f12015-07-24 21:03:07 +000044 for (const Elf_Shdr &Sec : ELFObj->sections()) {
Rafael Espindolacde25132015-08-13 14:45:44 +000045 switch (Sec.sh_type) {
46 case SHT_SYMTAB:
Rafael Espindolad8340da2015-08-10 15:12:17 +000047 Symtab = &Sec;
Rafael Espindolacde25132015-08-13 14:45:44 +000048 break;
Rafael Espindola20348222015-08-24 21:43:25 +000049 case SHT_SYMTAB_SHNDX: {
50 ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = ELFObj->getSHNDXTable(Sec);
51 error(ErrorOrTable);
52 SymtabSHNDX = *ErrorOrTable;
53 break;
54 }
Rafael Espindolacde25132015-08-13 14:45:44 +000055 case SHT_STRTAB:
56 case SHT_NULL:
Rafael Espindolacde25132015-08-13 14:45:44 +000057 break;
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000058 case SHT_RELA:
59 case SHT_REL: {
60 uint32_t RelocatedSectionIndex = Sec.sh_info;
61 if (RelocatedSectionIndex >= Size)
62 error("Invalid relocated section index");
63 SectionChunk<ELFT> *RelocatedSection = Chunks[RelocatedSectionIndex];
64 if (!RelocatedSection)
65 error("Unsupported relocation reference");
66 RelocatedSection->RelocSections.push_back(&Sec);
67 break;
68 }
Rafael Espindolacde25132015-08-13 14:45:44 +000069 default:
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000070 Chunks[I] = new (Alloc) SectionChunk<ELFT>(this, &Sec);
Rafael Espindolacde25132015-08-13 14:45:44 +000071 break;
Michael J. Spencer84487f12015-07-24 21:03:07 +000072 }
Rafael Espindola832b93f2015-08-24 20:06:32 +000073 ++I;
Michael J. Spencer84487f12015-07-24 21:03:07 +000074 }
75}
76
77template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
Michael J. Spencer84487f12015-07-24 21:03:07 +000078 ErrorOr<StringRef> StringTableOrErr =
79 ELFObj->getStringTableForSymtab(*Symtab);
80 error(StringTableOrErr.getError());
81 StringRef StringTable = *StringTableOrErr;
82
Rafael Espindola1a9344f2015-08-07 17:16:28 +000083 Elf_Sym_Range Syms = ELFObj->symbols(Symtab);
Reid Klecknerf7b85e02015-08-11 20:06:51 +000084 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
Rafael Espindola7c388182015-08-11 16:30:34 +000085 uint32_t FirstNonLocal = Symtab->sh_info;
86 if (FirstNonLocal > NumSymbols)
87 error("Invalid sh_info in symbol table");
88 Syms = llvm::make_range(Syms.begin() + FirstNonLocal, Syms.end());
Michael J. Spencer84487f12015-07-24 21:03:07 +000089 SymbolBodies.reserve(NumSymbols);
Rafael Espindola30318512015-08-04 14:00:56 +000090 for (const Elf_Sym &Sym : Syms)
91 SymbolBodies.push_back(createSymbolBody(StringTable, &Sym));
Michael J. Spencer84487f12015-07-24 21:03:07 +000092}
93
94template <class ELFT>
95SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
96 const Elf_Sym *Sym) {
97 ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
98 error(NameOrErr.getError());
99 StringRef Name = *NameOrErr;
Rafael Espindola20348222015-08-24 21:43:25 +0000100
101 uint32_t SecIndex = Sym->st_shndx;
Rafael Espindola51d46902015-08-28 21:26:51 +0000102 switch (SecIndex) {
103 case SHN_ABS:
Rafael Espindola0e0c1902015-08-27 12:40:06 +0000104 return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym);
Rafael Espindola51d46902015-08-28 21:26:51 +0000105 case SHN_UNDEF:
106 return new (Alloc) Undefined<ELFT>(Name, *Sym);
107 case SHN_COMMON:
108 return new (Alloc) DefinedCommon<ELFT>(Name, *Sym);
109 case SHN_XINDEX:
Rafael Espindola20348222015-08-24 21:43:25 +0000110 SecIndex = ELFObj->getExtendedSymbolTableIndex(Sym, Symtab, SymtabSHNDX);
Rafael Espindola51d46902015-08-28 21:26:51 +0000111 break;
112 }
Rafael Espindola20348222015-08-24 21:43:25 +0000113
Rafael Espindola5cd113d2015-08-24 22:00:25 +0000114 if (SecIndex >= Chunks.size() ||
115 (SecIndex != 0 && !Chunks[SecIndex]))
116 error("Invalid section index");
117
Rafael Espindolab13df652015-08-11 17:33:02 +0000118 switch (Sym->getBinding()) {
119 default:
120 error("unexpected binding");
121 case STB_GLOBAL:
Rafael Espindola3a63f3f2015-08-28 20:19:34 +0000122 case STB_WEAK:
Rafael Espindola832b93f2015-08-24 20:06:32 +0000123 return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Chunks[SecIndex]);
Rafael Espindolab13df652015-08-11 17:33:02 +0000124 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000125}
126
127namespace lld {
128namespace elf2 {
129template class elf2::ObjectFile<llvm::object::ELF32LE>;
130template class elf2::ObjectFile<llvm::object::ELF32BE>;
131template class elf2::ObjectFile<llvm::object::ELF64LE>;
132template class elf2::ObjectFile<llvm::object::ELF64BE>;
133}
134}