| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 1 | //===- 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" |
| Rafael Espindola | 9d06ab6 | 2015-09-22 00:01:39 +0000 | [diff] [blame] | 11 | #include "InputSection.h" |
| Rafael Espindola | 192e1fa | 2015-08-06 15:08:23 +0000 | [diff] [blame] | 12 | #include "Error.h" |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 13 | #include "Symbols.h" |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 14 | #include "llvm/ADT/STLExtras.h" |
| 15 | |
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 16 | using namespace llvm; |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 17 | using namespace llvm::ELF; |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 18 | using namespace llvm::object; |
| Rui Ueyama | f5c4aca | 2015-09-30 17:06:09 +0000 | [diff] [blame] | 19 | using namespace llvm::sys::fs; |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 20 | |
| 21 | using namespace lld; |
| 22 | using namespace lld::elf2; |
| 23 | |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 24 | template <class ELFT> static uint16_t getEMachine(const ELFFileBase &B) { |
| 25 | bool IsShared = isa<SharedFileBase>(B); |
| 26 | if (IsShared) |
| 27 | return cast<SharedFile<ELFT>>(B).getEMachine(); |
| 28 | return cast<ObjectFile<ELFT>>(B).getEMachine(); |
| Rafael Espindola | 3c9cb4b | 2015-08-05 12:03:34 +0000 | [diff] [blame] | 29 | } |
| 30 | |
| Rafael Espindola | 503fe94 | 2015-09-22 16:53:55 +0000 | [diff] [blame] | 31 | uint16_t ELFFileBase::getEMachine() const { |
| 32 | switch (EKind) { |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 33 | case ELF32BEKind: |
| Rafael Espindola | 503fe94 | 2015-09-22 16:53:55 +0000 | [diff] [blame] | 34 | return ::getEMachine<ELF32BE>(*this); |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 35 | case ELF32LEKind: |
| Rafael Espindola | 503fe94 | 2015-09-22 16:53:55 +0000 | [diff] [blame] | 36 | return ::getEMachine<ELF32LE>(*this); |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 37 | case ELF64BEKind: |
| Rafael Espindola | 503fe94 | 2015-09-22 16:53:55 +0000 | [diff] [blame] | 38 | return ::getEMachine<ELF64BE>(*this); |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 39 | case ELF64LEKind: |
| Rafael Espindola | 503fe94 | 2015-09-22 16:53:55 +0000 | [diff] [blame] | 40 | return ::getEMachine<ELF64LE>(*this); |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 41 | } |
| Rafael Espindola | 55eed7ef | 2015-09-03 22:25:11 +0000 | [diff] [blame] | 42 | llvm_unreachable("Invalid kind"); |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 43 | } |
| 44 | |
| 45 | bool ELFFileBase::isCompatibleWith(const ELFFileBase &Other) const { |
| 46 | return getELFKind() == Other.getELFKind() && |
| Rafael Espindola | 503fe94 | 2015-09-22 16:53:55 +0000 | [diff] [blame] | 47 | getEMachine() == Other.getEMachine(); |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 48 | } |
| 49 | |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 50 | namespace { |
| 51 | class ECRAII { |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 52 | std::error_code EC; |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 53 | |
| 54 | public: |
| 55 | std::error_code &getEC() { return EC; } |
| 56 | ~ECRAII() { error(EC); } |
| 57 | }; |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 58 | } |
| 59 | |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 60 | template <class ELFT> |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 61 | ELFData<ELFT>::ELFData(MemoryBufferRef MB) |
| 62 | : ELFObj(MB.getBuffer(), ECRAII().getEC()) {} |
| 63 | |
| 64 | template <class ELFT> |
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 65 | typename ELFData<ELFT>::Elf_Sym_Range |
| 66 | ELFData<ELFT>::getSymbolsHelper(bool Local) { |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 67 | if (!Symtab) |
| 68 | return Elf_Sym_Range(nullptr, nullptr); |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 69 | Elf_Sym_Range Syms = ELFObj.symbols(Symtab); |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 70 | uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); |
| 71 | uint32_t FirstNonLocal = Symtab->sh_info; |
| 72 | if (FirstNonLocal > NumSymbols) |
| 73 | error("Invalid sh_info in symbol table"); |
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 74 | if (!Local) |
| Rui Ueyama | 90b3daa | 2015-09-30 02:37:51 +0000 | [diff] [blame] | 75 | return make_range(Syms.begin() + FirstNonLocal, Syms.end()); |
| 76 | // +1 to skip over dummy symbol. |
| 77 | return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal); |
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 78 | } |
| 79 | |
| 80 | template <class ELFT> |
| 81 | typename ELFData<ELFT>::Elf_Sym_Range ELFData<ELFT>::getNonLocalSymbols() { |
| 82 | if (!Symtab) |
| 83 | return Elf_Sym_Range(nullptr, nullptr); |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 84 | ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab); |
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 85 | error(StringTableOrErr.getError()); |
| 86 | StringTable = *StringTableOrErr; |
| 87 | return getSymbolsHelper(false); |
| 88 | } |
| 89 | |
| 90 | template <class ELFT> |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 91 | ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M) |
| 92 | : ObjectFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {} |
| 93 | |
| 94 | template <class ELFT> |
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 95 | typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() { |
| 96 | return this->getSymbolsHelper(true); |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 97 | } |
| 98 | |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 99 | template <class ELFT> void elf2::ObjectFile<ELFT>::parse() { |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 100 | // Read section and symbol tables. |
| Rafael Espindola | 7167585 | 2015-09-22 00:16:19 +0000 | [diff] [blame] | 101 | initializeSections(); |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 102 | initializeSymbols(); |
| 103 | } |
| 104 | |
| Rafael Espindola | 7167585 | 2015-09-22 00:16:19 +0000 | [diff] [blame] | 105 | template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSections() { |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 106 | uint64_t Size = this->ELFObj.getNumSections(); |
| Rafael Espindola | 7167585 | 2015-09-22 00:16:19 +0000 | [diff] [blame] | 107 | Sections.resize(Size); |
| Rafael Espindola | 832b93f | 2015-08-24 20:06:32 +0000 | [diff] [blame] | 108 | unsigned I = 0; |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 109 | for (const Elf_Shdr &Sec : this->ELFObj.sections()) { |
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 110 | switch (Sec.sh_type) { |
| 111 | case SHT_SYMTAB: |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 112 | this->Symtab = &Sec; |
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 113 | break; |
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 114 | case SHT_SYMTAB_SHNDX: { |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 115 | ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 116 | this->ELFObj.getSHNDXTable(Sec); |
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 117 | error(ErrorOrTable); |
| 118 | SymtabSHNDX = *ErrorOrTable; |
| 119 | break; |
| 120 | } |
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 121 | case SHT_STRTAB: |
| 122 | case SHT_NULL: |
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 123 | break; |
| Michael J. Spencer | 67bc8d6 | 2015-08-27 23:15:56 +0000 | [diff] [blame] | 124 | case SHT_RELA: |
| 125 | case SHT_REL: { |
| 126 | uint32_t RelocatedSectionIndex = Sec.sh_info; |
| 127 | if (RelocatedSectionIndex >= Size) |
| 128 | error("Invalid relocated section index"); |
| Rafael Espindola | 7167585 | 2015-09-22 00:16:19 +0000 | [diff] [blame] | 129 | InputSection<ELFT> *RelocatedSection = Sections[RelocatedSectionIndex]; |
| Michael J. Spencer | 67bc8d6 | 2015-08-27 23:15:56 +0000 | [diff] [blame] | 130 | if (!RelocatedSection) |
| 131 | error("Unsupported relocation reference"); |
| 132 | RelocatedSection->RelocSections.push_back(&Sec); |
| 133 | break; |
| 134 | } |
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 135 | default: |
| Rafael Espindola | 7167585 | 2015-09-22 00:16:19 +0000 | [diff] [blame] | 136 | Sections[I] = new (Alloc) InputSection<ELFT>(this, &Sec); |
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 137 | break; |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 138 | } |
| Rafael Espindola | 832b93f | 2015-08-24 20:06:32 +0000 | [diff] [blame] | 139 | ++I; |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 140 | } |
| 141 | } |
| 142 | |
| 143 | template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() { |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 144 | Elf_Sym_Range Syms = this->getNonLocalSymbols(); |
| Reid Kleckner | f7b85e0 | 2015-08-11 20:06:51 +0000 | [diff] [blame] | 145 | uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 146 | SymbolBodies.reserve(NumSymbols); |
| Rafael Espindola | 3031851 | 2015-08-04 14:00:56 +0000 | [diff] [blame] | 147 | for (const Elf_Sym &Sym : Syms) |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 148 | SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 149 | } |
| 150 | |
| 151 | template <class ELFT> |
| 152 | SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, |
| 153 | const Elf_Sym *Sym) { |
| 154 | ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable); |
| 155 | error(NameOrErr.getError()); |
| 156 | StringRef Name = *NameOrErr; |
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 157 | |
| 158 | uint32_t SecIndex = Sym->st_shndx; |
| Rafael Espindola | 51d4690 | 2015-08-28 21:26:51 +0000 | [diff] [blame] | 159 | switch (SecIndex) { |
| 160 | case SHN_ABS: |
| Rafael Espindola | 0e0c190 | 2015-08-27 12:40:06 +0000 | [diff] [blame] | 161 | return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym); |
| Rafael Espindola | 51d4690 | 2015-08-28 21:26:51 +0000 | [diff] [blame] | 162 | case SHN_UNDEF: |
| 163 | return new (Alloc) Undefined<ELFT>(Name, *Sym); |
| 164 | case SHN_COMMON: |
| 165 | return new (Alloc) DefinedCommon<ELFT>(Name, *Sym); |
| 166 | case SHN_XINDEX: |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 167 | SecIndex = this->ELFObj.getExtendedSymbolTableIndex(Sym, this->Symtab, |
| 168 | SymtabSHNDX); |
| Rafael Espindola | 51d4690 | 2015-08-28 21:26:51 +0000 | [diff] [blame] | 169 | break; |
| 170 | } |
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 171 | |
| Rafael Espindola | 7167585 | 2015-09-22 00:16:19 +0000 | [diff] [blame] | 172 | if (SecIndex >= Sections.size() || (SecIndex != 0 && !Sections[SecIndex])) |
| Rafael Espindola | 5cd113d | 2015-08-24 22:00:25 +0000 | [diff] [blame] | 173 | error("Invalid section index"); |
| 174 | |
| Rafael Espindola | b13df65 | 2015-08-11 17:33:02 +0000 | [diff] [blame] | 175 | switch (Sym->getBinding()) { |
| 176 | default: |
| 177 | error("unexpected binding"); |
| 178 | case STB_GLOBAL: |
| Rafael Espindola | 3a63f3f | 2015-08-28 20:19:34 +0000 | [diff] [blame] | 179 | case STB_WEAK: |
| Rafael Espindola | 7167585 | 2015-09-22 00:16:19 +0000 | [diff] [blame] | 180 | return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sections[SecIndex]); |
| Rafael Espindola | b13df65 | 2015-08-11 17:33:02 +0000 | [diff] [blame] | 181 | } |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 182 | } |
| 183 | |
| Igor Kudrin | 2696bbe | 2015-10-01 18:02:21 +0000 | [diff] [blame] | 184 | static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) { |
| Rui Ueyama | d0e5aeb | 2015-09-30 02:42:27 +0000 | [diff] [blame] | 185 | ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB); |
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 186 | error(ArchiveOrErr, "Failed to parse archive"); |
| Igor Kudrin | 2696bbe | 2015-10-01 18:02:21 +0000 | [diff] [blame] | 187 | return std::move(*ArchiveOrErr); |
| 188 | } |
| 189 | |
| 190 | void ArchiveFile::parse() { |
| 191 | File = openArchive(MB); |
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 192 | |
| 193 | // Allocate a buffer for Lazy objects. |
| 194 | size_t NumSyms = File->getNumberOfSymbols(); |
| 195 | LazySymbols.reserve(NumSyms); |
| 196 | |
| 197 | // Read the symbol table to construct Lazy objects. |
| 198 | for (const Archive::Symbol &Sym : File->symbols()) |
| 199 | LazySymbols.emplace_back(this, Sym); |
| 200 | } |
| 201 | |
| 202 | // Returns a buffer pointing to a member file containing a given symbol. |
| 203 | MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) { |
| 204 | ErrorOr<Archive::child_iterator> ItOrErr = Sym->getMember(); |
| 205 | error(ItOrErr, |
| 206 | Twine("Could not get the member for symbol ") + Sym->getName()); |
| 207 | Archive::child_iterator It = *ItOrErr; |
| 208 | |
| Michael J. Spencer | 88f0d63 | 2015-09-08 20:36:20 +0000 | [diff] [blame] | 209 | if (!Seen.insert(It->getChildOffset()).second) |
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 210 | return MemoryBufferRef(); |
| Michael J. Spencer | 88f0d63 | 2015-09-08 20:36:20 +0000 | [diff] [blame] | 211 | |
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 212 | ErrorOr<MemoryBufferRef> Ret = It->getMemoryBufferRef(); |
| 213 | error(Ret, Twine("Could not get the buffer for the member defining symbol ") + |
| 214 | Sym->getName()); |
| 215 | return *Ret; |
| 216 | } |
| 217 | |
| Igor Kudrin | 2696bbe | 2015-10-01 18:02:21 +0000 | [diff] [blame] | 218 | std::vector<MemoryBufferRef> ArchiveFile::getMembers() { |
| 219 | File = openArchive(MB); |
| 220 | |
| 221 | std::vector<MemoryBufferRef> Result; |
| 222 | for (const Archive::Child &Child : File->children()) { |
| 223 | ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef(); |
| 224 | error(MbOrErr, |
| 225 | Twine("Could not get the buffer for a child of the archive ") + |
| 226 | File->getFileName()); |
| 227 | Result.push_back(MbOrErr.get()); |
| 228 | } |
| 229 | return Result; |
| 230 | } |
| 231 | |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 232 | template <class ELFT> |
| 233 | SharedFile<ELFT>::SharedFile(MemoryBufferRef M) |
| 234 | : SharedFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {} |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 235 | |
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 236 | template <class ELFT> void SharedFile<ELFT>::parse() { |
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 237 | typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; |
| 238 | typedef typename ELFFile<ELFT>::uintX_t uintX_t; |
| 239 | const Elf_Shdr *DynamicSec = nullptr; |
| 240 | |
| 241 | const ELFFile<ELFT> Obj = this->ELFObj; |
| 242 | for (const Elf_Shdr &Sec : Obj.sections()) { |
| 243 | uint32_t Type = Sec.sh_type; |
| 244 | if (Type == SHT_DYNSYM) |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 245 | this->Symtab = &Sec; |
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 246 | else if (Type == SHT_DYNAMIC) |
| 247 | DynamicSec = &Sec; |
| 248 | } |
| 249 | |
| 250 | // Also sets StringTable |
| 251 | Elf_Sym_Range Syms = this->getNonLocalSymbols(); |
| 252 | SoName = getName(); |
| 253 | |
| 254 | if (DynamicSec) { |
| 255 | auto *Begin = |
| 256 | reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset); |
| 257 | const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn); |
| 258 | |
| 259 | for (const Elf_Dyn &Dyn : make_range(Begin, End)) { |
| 260 | if (Dyn.d_tag == DT_SONAME) { |
| 261 | uintX_t Val = Dyn.getVal(); |
| 262 | if (Val >= this->StringTable.size()) |
| 263 | error("Invalid DT_SONAME entry"); |
| 264 | SoName = StringRef(this->StringTable.data() + Val); |
| 265 | break; |
| 266 | } |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 267 | } |
| 268 | } |
| 269 | |
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 270 | uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); |
| 271 | SymbolBodies.reserve(NumSymbols); |
| 272 | for (const Elf_Sym &Sym : Syms) { |
| 273 | if (Sym.isUndefined()) |
| 274 | continue; |
| 275 | |
| 276 | ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable); |
| 277 | error(NameOrErr.getError()); |
| 278 | StringRef Name = *NameOrErr; |
| 279 | |
| 280 | SymbolBodies.emplace_back(Name, Sym); |
| 281 | } |
| 282 | } |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 283 | |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 284 | namespace lld { |
| 285 | namespace elf2 { |
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 286 | |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 287 | template class elf2::ObjectFile<llvm::object::ELF32LE>; |
| 288 | template class elf2::ObjectFile<llvm::object::ELF32BE>; |
| 289 | template class elf2::ObjectFile<llvm::object::ELF64LE>; |
| 290 | template class elf2::ObjectFile<llvm::object::ELF64BE>; |
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 291 | |
| 292 | template class elf2::SharedFile<llvm::object::ELF32LE>; |
| 293 | template class elf2::SharedFile<llvm::object::ELF32BE>; |
| 294 | template class elf2::SharedFile<llvm::object::ELF64LE>; |
| 295 | template class elf2::SharedFile<llvm::object::ELF64BE>; |
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 296 | } |
| 297 | } |