| 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 | 192e1fa | 2015-08-06 15:08:23 +0000 | [diff] [blame] | 11 | #include "Error.h" | 
| Rafael Espindola | 9d13d04 | 2016-02-11 15:24:48 +0000 | [diff] [blame] | 12 | #include "InputSection.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" | 
| Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 15 | #include "llvm/IR/LLVMContext.h" | 
| Rafael Espindola | 4de44b7 | 2016-03-02 15:43:50 +0000 | [diff] [blame] | 16 | #include "llvm/IR/Module.h" | 
| Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 17 | #include "llvm/Object/IRObjectFile.h" | 
|  | 18 | #include "llvm/Support/raw_ostream.h" | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 19 |  | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 20 | using namespace llvm; | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 21 | using namespace llvm::ELF; | 
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 22 | using namespace llvm::object; | 
| Rui Ueyama | f5c4aca | 2015-09-30 17:06:09 +0000 | [diff] [blame] | 23 | using namespace llvm::sys::fs; | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 24 |  | 
|  | 25 | using namespace lld; | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 26 | using namespace lld::elf; | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 27 |  | 
| Rui Ueyama | eb3413e | 2016-03-03 06:22:29 +0000 | [diff] [blame] | 28 | template <class ELFT> | 
|  | 29 | static ELFFile<ELFT> createELFObj(MemoryBufferRef MB) { | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 30 | std::error_code EC; | 
| Rui Ueyama | eb3413e | 2016-03-03 06:22:29 +0000 | [diff] [blame] | 31 | ELFFile<ELFT> F(MB.getBuffer(), EC); | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 32 | check(EC); | 
| Rui Ueyama | eb3413e | 2016-03-03 06:22:29 +0000 | [diff] [blame] | 33 | return F; | 
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 34 | } | 
|  | 35 |  | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 36 | template <class ELFT> | 
| Rui Ueyama | eb3413e | 2016-03-03 06:22:29 +0000 | [diff] [blame] | 37 | ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) | 
|  | 38 | : InputFile(K, MB), ELFObj(createELFObj<ELFT>(MB)) {} | 
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 39 |  | 
|  | 40 | template <class ELFT> | 
| Rui Ueyama | 2022e81 | 2015-11-20 02:10:52 +0000 | [diff] [blame] | 41 | ELFKind ELFFileBase<ELFT>::getELFKind() { | 
| Rui Ueyama | f588ac4 | 2016-01-06 00:09:41 +0000 | [diff] [blame] | 42 | if (ELFT::TargetEndianness == support::little) | 
|  | 43 | return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind; | 
|  | 44 | return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind; | 
| Rui Ueyama | 2022e81 | 2015-11-20 02:10:52 +0000 | [diff] [blame] | 45 | } | 
|  | 46 |  | 
|  | 47 | template <class ELFT> | 
| Rui Ueyama | 9328b2c | 2016-03-14 23:16:09 +0000 | [diff] [blame] | 48 | typename ELFT::SymRange ELFFileBase<ELFT>::getElfSymbols(bool OnlyGlobals) { | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 49 | if (!Symtab) | 
|  | 50 | return Elf_Sym_Range(nullptr, nullptr); | 
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 51 | Elf_Sym_Range Syms = ELFObj.symbols(Symtab); | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 52 | uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); | 
|  | 53 | uint32_t FirstNonLocal = Symtab->sh_info; | 
|  | 54 | if (FirstNonLocal > NumSymbols) | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 55 | fatal("invalid sh_info in symbol table"); | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 56 |  | 
|  | 57 | if (OnlyGlobals) | 
| Rui Ueyama | 90b3daa | 2015-09-30 02:37:51 +0000 | [diff] [blame] | 58 | return make_range(Syms.begin() + FirstNonLocal, Syms.end()); | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 59 | return make_range(Syms.begin(), Syms.end()); | 
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 60 | } | 
|  | 61 |  | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 62 | template <class ELFT> | 
|  | 63 | uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const { | 
| Rui Ueyama | dc8d3a2 | 2015-12-24 08:36:56 +0000 | [diff] [blame] | 64 | uint32_t I = Sym.st_shndx; | 
|  | 65 | if (I == ELF::SHN_XINDEX) | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 66 | return ELFObj.getExtendedSymbolTableIndex(&Sym, Symtab, SymtabSHNDX); | 
| Rafael Espindola | 972b236 | 2016-03-09 14:31:18 +0000 | [diff] [blame] | 67 | if (I >= ELF::SHN_LORESERVE) | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 68 | return 0; | 
| Rui Ueyama | dc8d3a2 | 2015-12-24 08:36:56 +0000 | [diff] [blame] | 69 | return I; | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 70 | } | 
|  | 71 |  | 
| Rafael Espindola | af70764 | 2015-10-12 01:55:32 +0000 | [diff] [blame] | 72 | template <class ELFT> void ELFFileBase<ELFT>::initStringTable() { | 
| Rafael Espindola | 3e60379 | 2015-10-01 20:26:37 +0000 | [diff] [blame] | 73 | if (!Symtab) | 
|  | 74 | return; | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 75 | StringTable = check(ELFObj.getStringTableForSymtab(*Symtab)); | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 76 | } | 
|  | 77 |  | 
|  | 78 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 79 | elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M) | 
| Rafael Espindola | 2a4b271 | 2015-10-13 01:17:02 +0000 | [diff] [blame] | 80 | : ELFFileBase<ELFT>(Base::ObjectKind, M) {} | 
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 81 |  | 
|  | 82 | template <class ELFT> | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 83 | ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getNonLocalSymbols() { | 
|  | 84 | if (!this->Symtab) | 
|  | 85 | return this->SymbolBodies; | 
|  | 86 | uint32_t FirstNonLocal = this->Symtab->sh_info; | 
|  | 87 | return makeArrayRef(this->SymbolBodies).slice(FirstNonLocal); | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | template <class ELFT> | 
|  | 91 | ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() { | 
|  | 92 | if (!this->Symtab) | 
|  | 93 | return this->SymbolBodies; | 
|  | 94 | uint32_t FirstNonLocal = this->Symtab->sh_info; | 
|  | 95 | return makeArrayRef(this->SymbolBodies).slice(1, FirstNonLocal - 1); | 
|  | 96 | } | 
|  | 97 |  | 
|  | 98 | template <class ELFT> | 
|  | 99 | ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getSymbols() { | 
|  | 100 | if (!this->Symtab) | 
|  | 101 | return this->SymbolBodies; | 
|  | 102 | return makeArrayRef(this->SymbolBodies).slice(1); | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 103 | } | 
|  | 104 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 105 | template <class ELFT> uint32_t elf::ObjectFile<ELFT>::getMipsGp0() const { | 
| Rui Ueyama | 70eed36 | 2016-01-06 22:42:43 +0000 | [diff] [blame] | 106 | if (MipsReginfo) | 
|  | 107 | return MipsReginfo->Reginfo->ri_gp_value; | 
|  | 108 | return 0; | 
| Simon Atanasyan | 57830b6 | 2015-12-25 13:02:13 +0000 | [diff] [blame] | 109 | } | 
|  | 110 |  | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 111 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 112 | void elf::ObjectFile<ELFT>::parse(DenseSet<StringRef> &ComdatGroups) { | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 113 | // Read section and symbol tables. | 
| Rui Ueyama | 52d3b67 | 2016-01-06 02:06:33 +0000 | [diff] [blame] | 114 | initializeSections(ComdatGroups); | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 115 | initializeSymbols(); | 
|  | 116 | } | 
|  | 117 |  | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 118 | // Sections with SHT_GROUP and comdat bits define comdat section groups. | 
|  | 119 | // They are identified and deduplicated by group name. This function | 
|  | 120 | // returns a group name. | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 121 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 122 | StringRef elf::ObjectFile<ELFT>::getShtGroupSignature(const Elf_Shdr &Sec) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 123 | const ELFFile<ELFT> &Obj = this->ELFObj; | 
|  | 124 | uint32_t SymtabdSectionIndex = Sec.sh_link; | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 125 | const Elf_Shdr *SymtabSec = check(Obj.getSection(SymtabdSectionIndex)); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 126 | uint32_t SymIndex = Sec.sh_info; | 
|  | 127 | const Elf_Sym *Sym = Obj.getSymbol(SymtabSec, SymIndex); | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 128 | StringRef StringTable = check(Obj.getStringTableForSymtab(*SymtabSec)); | 
|  | 129 | return check(Sym->getName(StringTable)); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 130 | } | 
|  | 131 |  | 
|  | 132 | template <class ELFT> | 
| Rui Ueyama | 368e1ea | 2016-03-13 22:02:04 +0000 | [diff] [blame] | 133 | ArrayRef<typename elf::ObjectFile<ELFT>::Elf_Word> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 134 | elf::ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 135 | const ELFFile<ELFT> &Obj = this->ELFObj; | 
| Rui Ueyama | 368e1ea | 2016-03-13 22:02:04 +0000 | [diff] [blame] | 136 | ArrayRef<Elf_Word> Entries = | 
|  | 137 | check(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec)); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 138 | if (Entries.empty() || Entries[0] != GRP_COMDAT) | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 139 | fatal("unsupported SHT_GROUP format"); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 140 | return Entries.slice(1); | 
|  | 141 | } | 
|  | 142 |  | 
| Rui Ueyama | 9328b2c | 2016-03-14 23:16:09 +0000 | [diff] [blame] | 143 | template <class ELFT> static bool shouldMerge(const typename ELFT::Shdr &Sec) { | 
|  | 144 | typedef typename ELFT::uint uintX_t; | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 145 | uintX_t Flags = Sec.sh_flags; | 
|  | 146 | if (!(Flags & SHF_MERGE)) | 
|  | 147 | return false; | 
|  | 148 | if (Flags & SHF_WRITE) | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 149 | fatal("writable SHF_MERGE sections are not supported"); | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 150 | uintX_t EntSize = Sec.sh_entsize; | 
| Rafael Espindola | 0d2ad42 | 2016-03-21 14:57:20 +0000 | [diff] [blame] | 151 | if (!EntSize || Sec.sh_size % EntSize) | 
| Rui Ueyama | 64cfffd | 2016-01-28 18:40:06 +0000 | [diff] [blame] | 152 | fatal("SHF_MERGE section size must be a multiple of sh_entsize"); | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 153 |  | 
| Rafael Espindola | 7efa5be | 2016-02-19 14:17:40 +0000 | [diff] [blame] | 154 | // Don't try to merge if the aligment is larger than the sh_entsize and this | 
|  | 155 | // is not SHF_STRINGS. | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 156 | // | 
| Rafael Espindola | 7efa5be | 2016-02-19 14:17:40 +0000 | [diff] [blame] | 157 | // Since this is not a SHF_STRINGS, we would need to pad after every entity. | 
|  | 158 | // It would be equivalent for the producer of the .o to just set a larger | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 159 | // sh_entsize. | 
| Rafael Espindola | 7efa5be | 2016-02-19 14:17:40 +0000 | [diff] [blame] | 160 | if (Flags & SHF_STRINGS) | 
|  | 161 | return true; | 
|  | 162 |  | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 163 | if (Sec.sh_addralign > EntSize) | 
|  | 164 | return false; | 
|  | 165 |  | 
|  | 166 | return true; | 
|  | 167 | } | 
|  | 168 |  | 
|  | 169 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 170 | void elf::ObjectFile<ELFT>::initializeSections( | 
| Rafael Espindola | f1d598c | 2016-02-12 21:17:10 +0000 | [diff] [blame] | 171 | DenseSet<StringRef> &ComdatGroups) { | 
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 172 | uint64_t Size = this->ELFObj.getNumSections(); | 
| Rafael Espindola | 7167585 | 2015-09-22 00:16:19 +0000 | [diff] [blame] | 173 | Sections.resize(Size); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 174 | unsigned I = -1; | 
| Rafael Espindola | d42f4e5 | 2015-10-08 12:02:38 +0000 | [diff] [blame] | 175 | const ELFFile<ELFT> &Obj = this->ELFObj; | 
|  | 176 | for (const Elf_Shdr &Sec : Obj.sections()) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 177 | ++I; | 
| Rui Ueyama | 733153d | 2016-02-24 18:33:35 +0000 | [diff] [blame] | 178 | if (Sections[I] == InputSection<ELFT>::Discarded) | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 179 | continue; | 
|  | 180 |  | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 181 | switch (Sec.sh_type) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 182 | case SHT_GROUP: | 
| Rui Ueyama | 733153d | 2016-02-24 18:33:35 +0000 | [diff] [blame] | 183 | Sections[I] = InputSection<ELFT>::Discarded; | 
| Rui Ueyama | 52d3b67 | 2016-01-06 02:06:33 +0000 | [diff] [blame] | 184 | if (ComdatGroups.insert(getShtGroupSignature(Sec)).second) | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 185 | continue; | 
| Rui Ueyama | 33b3f21 | 2016-01-06 20:30:02 +0000 | [diff] [blame] | 186 | for (uint32_t SecIndex : getShtGroupEntries(Sec)) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 187 | if (SecIndex >= Size) | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 188 | fatal("invalid section index in group"); | 
| Rui Ueyama | 733153d | 2016-02-24 18:33:35 +0000 | [diff] [blame] | 189 | Sections[SecIndex] = InputSection<ELFT>::Discarded; | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 190 | } | 
|  | 191 | break; | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 192 | case SHT_SYMTAB: | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 193 | this->Symtab = &Sec; | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 194 | break; | 
| Rafael Espindola | 1130935c | 2016-03-03 16:21:44 +0000 | [diff] [blame] | 195 | case SHT_SYMTAB_SHNDX: | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 196 | this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec)); | 
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 197 | break; | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 198 | case SHT_STRTAB: | 
|  | 199 | case SHT_NULL: | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 200 | break; | 
| Michael J. Spencer | 67bc8d6 | 2015-08-27 23:15:56 +0000 | [diff] [blame] | 201 | case SHT_RELA: | 
|  | 202 | case SHT_REL: { | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 203 | // This section contains relocation information. | 
|  | 204 | // If -r is given, we do not interpret or apply relocation | 
|  | 205 | // but just copy relocation sections to output. | 
| George Rimar | 58941ee | 2016-02-25 08:23:37 +0000 | [diff] [blame] | 206 | if (Config->Relocatable) { | 
| George Rimar | 58941ee | 2016-02-25 08:23:37 +0000 | [diff] [blame] | 207 | Sections[I] = new (Alloc) InputSection<ELFT>(this, &Sec); | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 208 | break; | 
|  | 209 | } | 
|  | 210 |  | 
|  | 211 | // Find the relocation target section and associate this | 
|  | 212 | // section with it. | 
|  | 213 | InputSectionBase<ELFT> *Target = getRelocTarget(Sec); | 
|  | 214 | if (!Target) | 
|  | 215 | break; | 
|  | 216 | if (auto *S = dyn_cast<InputSection<ELFT>>(Target)) { | 
| Rafael Espindola | c159c96 | 2015-10-19 21:00:02 +0000 | [diff] [blame] | 217 | S->RelocSections.push_back(&Sec); | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 218 | break; | 
|  | 219 | } | 
|  | 220 | if (auto *S = dyn_cast<EHInputSection<ELFT>>(Target)) { | 
| Rafael Espindola | 0c6a4f1 | 2015-11-11 19:54:14 +0000 | [diff] [blame] | 221 | if (S->RelocSection) | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 222 | fatal("multiple relocation sections to .eh_frame are not supported"); | 
| Rafael Espindola | 0c6a4f1 | 2015-11-11 19:54:14 +0000 | [diff] [blame] | 223 | S->RelocSection = &Sec; | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 224 | break; | 
| Rafael Espindola | 0c6a4f1 | 2015-11-11 19:54:14 +0000 | [diff] [blame] | 225 | } | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 226 | fatal("relocations pointing to SHF_MERGE are not supported"); | 
| Michael J. Spencer | 67bc8d6 | 2015-08-27 23:15:56 +0000 | [diff] [blame] | 227 | } | 
| Rui Ueyama | e79b09a | 2015-11-21 22:19:32 +0000 | [diff] [blame] | 228 | default: | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 229 | Sections[I] = createInputSection(Sec); | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 230 | } | 
|  | 231 | } | 
|  | 232 | } | 
|  | 233 |  | 
| Rafael Espindola | f1d598c | 2016-02-12 21:17:10 +0000 | [diff] [blame] | 234 | template <class ELFT> | 
|  | 235 | InputSectionBase<ELFT> * | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 236 | elf::ObjectFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) { | 
|  | 237 | uint32_t Idx = Sec.sh_info; | 
|  | 238 | if (Idx >= Sections.size()) | 
|  | 239 | fatal("invalid relocated section index"); | 
|  | 240 | InputSectionBase<ELFT> *Target = Sections[Idx]; | 
|  | 241 |  | 
|  | 242 | // Strictly speaking, a relocation section must be included in the | 
|  | 243 | // group of the section it relocates. However, LLVM 3.3 and earlier | 
|  | 244 | // would fail to do so, so we gracefully handle that case. | 
|  | 245 | if (Target == InputSection<ELFT>::Discarded) | 
|  | 246 | return nullptr; | 
|  | 247 |  | 
|  | 248 | if (!Target) | 
|  | 249 | fatal("unsupported relocation reference"); | 
|  | 250 | return Target; | 
|  | 251 | } | 
|  | 252 |  | 
|  | 253 | template <class ELFT> | 
|  | 254 | InputSectionBase<ELFT> * | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 255 | elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 256 | StringRef Name = check(this->ELFObj.getSectionName(&Sec)); | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 257 |  | 
|  | 258 | // .note.GNU-stack is a marker section to control the presence of | 
|  | 259 | // PT_GNU_STACK segment in outputs. Since the presence of the segment | 
|  | 260 | // is controlled only by the command line option (-z execstack) in LLD, | 
|  | 261 | // .note.GNU-stack is ignored. | 
|  | 262 | if (Name == ".note.GNU-stack") | 
| Rui Ueyama | 733153d | 2016-02-24 18:33:35 +0000 | [diff] [blame] | 263 | return InputSection<ELFT>::Discarded; | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 264 |  | 
| George Rimar | 3c45ed2 | 2016-03-09 18:01:45 +0000 | [diff] [blame] | 265 | if (Name == ".note.GNU-split-stack") | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 266 | error("objects using splitstacks are not supported"); | 
| George Rimar | 3c45ed2 | 2016-03-09 18:01:45 +0000 | [diff] [blame] | 267 |  | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 268 | // A MIPS object file has a special section that contains register | 
|  | 269 | // usage info, which needs to be handled by the linker specially. | 
| Simon Atanasyan | 57830b6 | 2015-12-25 13:02:13 +0000 | [diff] [blame] | 270 | if (Config->EMachine == EM_MIPS && Name == ".reginfo") { | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 271 | MipsReginfo = new (Alloc) MipsReginfoInputSection<ELFT>(this, &Sec); | 
| Simon Atanasyan | 57830b6 | 2015-12-25 13:02:13 +0000 | [diff] [blame] | 272 | return MipsReginfo; | 
|  | 273 | } | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 274 |  | 
| George Rimar | 4cfe572 | 2016-03-03 07:49:35 +0000 | [diff] [blame] | 275 | // We dont need special handling of .eh_frame sections if relocatable | 
|  | 276 | // output was choosen. Proccess them as usual input sections. | 
|  | 277 | if (!Config->Relocatable && Name == ".eh_frame") | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 278 | return new (EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec); | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 279 | if (shouldMerge<ELFT>(Sec)) | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 280 | return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec); | 
|  | 281 | return new (Alloc) InputSection<ELFT>(this, &Sec); | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 282 | } | 
|  | 283 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 284 | template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() { | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 285 | this->initStringTable(); | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 286 | Elf_Sym_Range Syms = this->getElfSymbols(false); | 
| Reid Kleckner | f7b85e0 | 2015-08-11 20:06:51 +0000 | [diff] [blame] | 287 | uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 288 | SymbolBodies.reserve(NumSymbols); | 
| Rafael Espindola | 3031851 | 2015-08-04 14:00:56 +0000 | [diff] [blame] | 289 | for (const Elf_Sym &Sym : Syms) | 
| Rui Ueyama | c5e372d | 2016-01-21 02:10:12 +0000 | [diff] [blame] | 290 | SymbolBodies.push_back(createSymbolBody(&Sym)); | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 291 | } | 
|  | 292 |  | 
|  | 293 | template <class ELFT> | 
| Rafael Espindola | c159c96 | 2015-10-19 21:00:02 +0000 | [diff] [blame] | 294 | InputSectionBase<ELFT> * | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 295 | elf::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 296 | uint32_t Index = this->getSectionIndex(Sym); | 
|  | 297 | if (Index == 0) | 
| Rafael Espindola | 4cda581 | 2015-10-16 15:29:48 +0000 | [diff] [blame] | 298 | return nullptr; | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 299 | if (Index >= Sections.size() || !Sections[Index]) | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 300 | fatal("invalid section index"); | 
| Rui Ueyama | 0b28952 | 2016-02-25 18:43:51 +0000 | [diff] [blame] | 301 | InputSectionBase<ELFT> *S = Sections[Index]; | 
|  | 302 | if (S == InputSectionBase<ELFT>::Discarded) | 
|  | 303 | return S; | 
|  | 304 | return S->Repl; | 
| Rafael Espindola | 4cda581 | 2015-10-16 15:29:48 +0000 | [diff] [blame] | 305 | } | 
|  | 306 |  | 
|  | 307 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 308 | SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) { | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 309 | unsigned char Binding = Sym->getBinding(); | 
| Rafael Espindola | 1f5b70f | 2016-03-11 14:21:37 +0000 | [diff] [blame] | 310 | InputSectionBase<ELFT> *Sec = getSection(*Sym); | 
|  | 311 | if (Binding == STB_LOCAL) { | 
|  | 312 | if (Sec == InputSection<ELFT>::Discarded) | 
|  | 313 | Sec = nullptr; | 
|  | 314 | return new (Alloc) DefinedRegular<ELFT>("", *Sym, Sec); | 
|  | 315 | } | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 316 |  | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 317 | StringRef Name = check(Sym->getName(this->StringTable)); | 
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 318 |  | 
| Rafael Espindola | 4cda581 | 2015-10-16 15:29:48 +0000 | [diff] [blame] | 319 | switch (Sym->st_shndx) { | 
| Rafael Espindola | 51d4690 | 2015-08-28 21:26:51 +0000 | [diff] [blame] | 320 | case SHN_UNDEF: | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 321 | return new (Alloc) UndefinedElf<ELFT>(Name, *Sym); | 
| Rafael Espindola | 51d4690 | 2015-08-28 21:26:51 +0000 | [diff] [blame] | 322 | case SHN_COMMON: | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 323 | return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value, | 
|  | 324 | Sym->getBinding() == llvm::ELF::STB_WEAK, | 
|  | 325 | Sym->getVisibility()); | 
| Rafael Espindola | 51d4690 | 2015-08-28 21:26:51 +0000 | [diff] [blame] | 326 | } | 
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 327 |  | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 328 | switch (Binding) { | 
| Rafael Espindola | b13df65 | 2015-08-11 17:33:02 +0000 | [diff] [blame] | 329 | default: | 
| George Rimar | 5761042 | 2016-03-11 14:43:02 +0000 | [diff] [blame] | 330 | fatal("unexpected binding"); | 
| Rafael Espindola | b13df65 | 2015-08-11 17:33:02 +0000 | [diff] [blame] | 331 | case STB_GLOBAL: | 
| Rafael Espindola | 3a63f3f | 2015-08-28 20:19:34 +0000 | [diff] [blame] | 332 | case STB_WEAK: | 
| Rafael Espindola | 1f5b70f | 2016-03-11 14:21:37 +0000 | [diff] [blame] | 333 | case STB_GNU_UNIQUE: | 
| Rui Ueyama | 733153d | 2016-02-24 18:33:35 +0000 | [diff] [blame] | 334 | if (Sec == InputSection<ELFT>::Discarded) | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 335 | return new (Alloc) UndefinedElf<ELFT>(Name, *Sym); | 
|  | 336 | return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 337 | } | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 338 | } | 
|  | 339 |  | 
| Igor Kudrin | 2696bbe | 2015-10-01 18:02:21 +0000 | [diff] [blame] | 340 | void ArchiveFile::parse() { | 
| Rui Ueyama | 64bd8df | 2016-03-14 21:31:07 +0000 | [diff] [blame] | 341 | File = check(Archive::create(MB), "failed to parse archive"); | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 342 |  | 
|  | 343 | // Allocate a buffer for Lazy objects. | 
|  | 344 | size_t NumSyms = File->getNumberOfSymbols(); | 
|  | 345 | LazySymbols.reserve(NumSyms); | 
|  | 346 |  | 
|  | 347 | // Read the symbol table to construct Lazy objects. | 
|  | 348 | for (const Archive::Symbol &Sym : File->symbols()) | 
|  | 349 | LazySymbols.emplace_back(this, Sym); | 
|  | 350 | } | 
|  | 351 |  | 
|  | 352 | // Returns a buffer pointing to a member file containing a given symbol. | 
|  | 353 | MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) { | 
| Rafael Espindola | 1130935c | 2016-03-03 16:21:44 +0000 | [diff] [blame] | 354 | Archive::Child C = | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 355 | check(Sym->getMember(), | 
| Rui Ueyama | 64bd8df | 2016-03-14 21:31:07 +0000 | [diff] [blame] | 356 | "could not get the member for symbol " + Sym->getName()); | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 357 |  | 
| Rafael Espindola | 8f3a6ae | 2015-11-05 14:40:28 +0000 | [diff] [blame] | 358 | if (!Seen.insert(C.getChildOffset()).second) | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 359 | return MemoryBufferRef(); | 
| Michael J. Spencer | 88f0d63 | 2015-09-08 20:36:20 +0000 | [diff] [blame] | 360 |  | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 361 | return check(C.getMemoryBufferRef(), | 
| Rui Ueyama | 64bd8df | 2016-03-14 21:31:07 +0000 | [diff] [blame] | 362 | "could not get the buffer for the member defining symbol " + | 
| Rafael Espindola | 1130935c | 2016-03-03 16:21:44 +0000 | [diff] [blame] | 363 | Sym->getName()); | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 364 | } | 
|  | 365 |  | 
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 366 | template <class ELFT> | 
|  | 367 | SharedFile<ELFT>::SharedFile(MemoryBufferRef M) | 
| Rui Ueyama | f588ac4 | 2016-01-06 00:09:41 +0000 | [diff] [blame] | 368 | : ELFFileBase<ELFT>(Base::SharedKind, M), AsNeeded(Config->AsNeeded) {} | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 369 |  | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 370 | template <class ELFT> | 
| Rui Ueyama | 9328b2c | 2016-03-14 23:16:09 +0000 | [diff] [blame] | 371 | const typename ELFT::Shdr * | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 372 | SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const { | 
|  | 373 | uint32_t Index = this->getSectionIndex(Sym); | 
|  | 374 | if (Index == 0) | 
|  | 375 | return nullptr; | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 376 | return check(this->ELFObj.getSection(Index)); | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 377 | } | 
|  | 378 |  | 
| Rui Ueyama | 7c71331 | 2016-01-06 01:56:36 +0000 | [diff] [blame] | 379 | // Partially parse the shared object file so that we can call | 
|  | 380 | // getSoName on this object. | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 381 | template <class ELFT> void SharedFile<ELFT>::parseSoName() { | 
| Rui Ueyama | 9328b2c | 2016-03-14 23:16:09 +0000 | [diff] [blame] | 382 | typedef typename ELFT::Dyn Elf_Dyn; | 
|  | 383 | typedef typename ELFT::uint uintX_t; | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 384 | const Elf_Shdr *DynamicSec = nullptr; | 
|  | 385 |  | 
|  | 386 | const ELFFile<ELFT> Obj = this->ELFObj; | 
|  | 387 | for (const Elf_Shdr &Sec : Obj.sections()) { | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 388 | switch (Sec.sh_type) { | 
|  | 389 | default: | 
|  | 390 | continue; | 
|  | 391 | case SHT_DYNSYM: | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 392 | this->Symtab = &Sec; | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 393 | break; | 
|  | 394 | case SHT_DYNAMIC: | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 395 | DynamicSec = &Sec; | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 396 | break; | 
| Rafael Espindola | 1130935c | 2016-03-03 16:21:44 +0000 | [diff] [blame] | 397 | case SHT_SYMTAB_SHNDX: | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 398 | this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec)); | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 399 | break; | 
|  | 400 | } | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 401 | } | 
|  | 402 |  | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 403 | this->initStringTable(); | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 404 | SoName = this->getName(); | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 405 |  | 
| Rui Ueyama | 361d8b9 | 2015-10-12 15:49:02 +0000 | [diff] [blame] | 406 | if (!DynamicSec) | 
|  | 407 | return; | 
|  | 408 | auto *Begin = | 
|  | 409 | reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset); | 
|  | 410 | const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn); | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 411 |  | 
| Rui Ueyama | 361d8b9 | 2015-10-12 15:49:02 +0000 | [diff] [blame] | 412 | for (const Elf_Dyn &Dyn : make_range(Begin, End)) { | 
|  | 413 | if (Dyn.d_tag == DT_SONAME) { | 
|  | 414 | uintX_t Val = Dyn.getVal(); | 
|  | 415 | if (Val >= this->StringTable.size()) | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 416 | fatal("invalid DT_SONAME entry"); | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 417 | SoName = StringRef(this->StringTable.data() + Val); | 
| Rui Ueyama | 361d8b9 | 2015-10-12 15:49:02 +0000 | [diff] [blame] | 418 | return; | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 419 | } | 
|  | 420 | } | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 421 | } | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 422 |  | 
| Rui Ueyama | 7c71331 | 2016-01-06 01:56:36 +0000 | [diff] [blame] | 423 | // Fully parse the shared object file. This must be called after parseSoName(). | 
|  | 424 | template <class ELFT> void SharedFile<ELFT>::parseRest() { | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 425 | Elf_Sym_Range Syms = this->getElfSymbols(true); | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 426 | uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); | 
|  | 427 | SymbolBodies.reserve(NumSymbols); | 
|  | 428 | for (const Elf_Sym &Sym : Syms) { | 
| Rui Ueyama | a3cb80a | 2016-03-04 01:56:52 +0000 | [diff] [blame] | 429 | StringRef Name = check(Sym.getName(this->StringTable)); | 
| Rui Ueyama | f8432d9 | 2015-10-13 16:34:14 +0000 | [diff] [blame] | 430 | if (Sym.isUndefined()) | 
|  | 431 | Undefs.push_back(Name); | 
|  | 432 | else | 
|  | 433 | SymbolBodies.emplace_back(this, Name, Sym); | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 434 | } | 
|  | 435 | } | 
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 436 |  | 
| Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 437 | BitcodeFile::BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {} | 
|  | 438 |  | 
|  | 439 | bool BitcodeFile::classof(const InputFile *F) { | 
|  | 440 | return F->kind() == BitcodeKind; | 
|  | 441 | } | 
|  | 442 |  | 
| Rui Ueyama | fd4fee5 | 2016-03-07 00:54:17 +0000 | [diff] [blame] | 443 | static uint8_t getGvVisibility(const GlobalValue *GV) { | 
|  | 444 | switch (GV->getVisibility()) { | 
| Rui Ueyama | 68fae23 | 2016-03-07 19:06:14 +0000 | [diff] [blame] | 445 | case GlobalValue::DefaultVisibility: | 
|  | 446 | return STV_DEFAULT; | 
| Rui Ueyama | fd4fee5 | 2016-03-07 00:54:17 +0000 | [diff] [blame] | 447 | case GlobalValue::HiddenVisibility: | 
|  | 448 | return STV_HIDDEN; | 
|  | 449 | case GlobalValue::ProtectedVisibility: | 
|  | 450 | return STV_PROTECTED; | 
| Rui Ueyama | fd4fee5 | 2016-03-07 00:54:17 +0000 | [diff] [blame] | 451 | } | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 452 | llvm_unreachable("unknown visibility"); | 
| Rui Ueyama | f714955 | 2016-03-11 18:46:51 +0000 | [diff] [blame] | 453 | } | 
|  | 454 |  | 
|  | 455 | SymbolBody * | 
|  | 456 | BitcodeFile::createSymbolBody(const DenseSet<const Comdat *> &KeptComdats, | 
|  | 457 | const IRObjectFile &Obj, | 
|  | 458 | const BasicSymbolRef &Sym) { | 
|  | 459 | const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl()); | 
|  | 460 | assert(GV); | 
|  | 461 | if (const Comdat *C = GV->getComdat()) | 
|  | 462 | if (!KeptComdats.count(C)) | 
|  | 463 | return nullptr; | 
|  | 464 |  | 
|  | 465 | uint8_t Visibility = getGvVisibility(GV); | 
|  | 466 |  | 
|  | 467 | SmallString<64> Name; | 
|  | 468 | raw_svector_ostream OS(Name); | 
|  | 469 | Sym.printName(OS); | 
|  | 470 | StringRef NameRef = Saver.save(StringRef(Name)); | 
|  | 471 |  | 
|  | 472 | const Module &M = Obj.getModule(); | 
|  | 473 | SymbolBody *Body; | 
|  | 474 | uint32_t Flags = Sym.getFlags(); | 
|  | 475 | bool IsWeak = Flags & BasicSymbolRef::SF_Weak; | 
|  | 476 | if (Flags & BasicSymbolRef::SF_Undefined) { | 
|  | 477 | Body = new (Alloc) Undefined(NameRef, IsWeak, Visibility, false); | 
|  | 478 | } else if (Flags & BasicSymbolRef::SF_Common) { | 
|  | 479 | const DataLayout &DL = M.getDataLayout(); | 
|  | 480 | uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); | 
|  | 481 | Body = new (Alloc) | 
|  | 482 | DefinedCommon(NameRef, Size, GV->getAlignment(), IsWeak, Visibility); | 
|  | 483 | } else { | 
|  | 484 | Body = new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility); | 
|  | 485 | } | 
|  | 486 | Body->IsTls = GV->isThreadLocal(); | 
|  | 487 | return Body; | 
|  | 488 | } | 
|  | 489 |  | 
|  | 490 | bool BitcodeFile::shouldSkip(const BasicSymbolRef &Sym) { | 
|  | 491 | uint32_t Flags = Sym.getFlags(); | 
|  | 492 | if (!(Flags & BasicSymbolRef::SF_Global)) | 
|  | 493 | return true; | 
|  | 494 | if (Flags & BasicSymbolRef::SF_FormatSpecific) | 
|  | 495 | return true; | 
|  | 496 | return false; | 
| Rafael Espindola | 9b3acf9 | 2016-03-11 16:11:47 +0000 | [diff] [blame] | 497 | } | 
|  | 498 |  | 
| Rafael Espindola | 4de44b7 | 2016-03-02 15:43:50 +0000 | [diff] [blame] | 499 | void BitcodeFile::parse(DenseSet<StringRef> &ComdatGroups) { | 
| Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 500 | LLVMContext Context; | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 501 | std::unique_ptr<IRObjectFile> Obj = check(IRObjectFile::create(MB, Context)); | 
| Rafael Espindola | 1130935c | 2016-03-03 16:21:44 +0000 | [diff] [blame] | 502 | const Module &M = Obj->getModule(); | 
| Rafael Espindola | 4de44b7 | 2016-03-02 15:43:50 +0000 | [diff] [blame] | 503 |  | 
|  | 504 | DenseSet<const Comdat *> KeptComdats; | 
|  | 505 | for (const auto &P : M.getComdatSymbolTable()) { | 
|  | 506 | StringRef N = Saver.save(P.first()); | 
|  | 507 | if (ComdatGroups.insert(N).second) | 
|  | 508 | KeptComdats.insert(&P.second); | 
|  | 509 | } | 
|  | 510 |  | 
| Rui Ueyama | f714955 | 2016-03-11 18:46:51 +0000 | [diff] [blame] | 511 | for (const BasicSymbolRef &Sym : Obj->symbols()) | 
|  | 512 | if (!shouldSkip(Sym)) | 
|  | 513 | SymbolBodies.push_back(createSymbolBody(KeptComdats, *Obj, Sym)); | 
| Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 514 | } | 
|  | 515 |  | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 516 | template <typename T> | 
|  | 517 | static std::unique_ptr<InputFile> createELFFileAux(MemoryBufferRef MB) { | 
|  | 518 | std::unique_ptr<T> Ret = llvm::make_unique<T>(MB); | 
|  | 519 |  | 
|  | 520 | if (!Config->FirstElf) | 
|  | 521 | Config->FirstElf = Ret.get(); | 
|  | 522 |  | 
| Rui Ueyama | e717a71 | 2015-10-13 16:20:50 +0000 | [diff] [blame] | 523 | if (Config->EKind == ELFNoneKind) { | 
|  | 524 | Config->EKind = Ret->getELFKind(); | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 525 | Config->EMachine = Ret->getEMachine(); | 
|  | 526 | } | 
|  | 527 |  | 
|  | 528 | return std::move(Ret); | 
|  | 529 | } | 
|  | 530 |  | 
|  | 531 | template <template <class> class T> | 
| Rui Ueyama | 533c030 | 2016-01-06 00:09:43 +0000 | [diff] [blame] | 532 | static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) { | 
| Rui Ueyama | d94478b | 2015-11-20 02:19:36 +0000 | [diff] [blame] | 533 | std::pair<unsigned char, unsigned char> Type = getElfArchType(MB.getBuffer()); | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 534 | if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB) | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 535 | fatal("invalid data encoding: " + MB.getBufferIdentifier()); | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 536 |  | 
|  | 537 | if (Type.first == ELF::ELFCLASS32) { | 
|  | 538 | if (Type.second == ELF::ELFDATA2LSB) | 
| Rui Ueyama | d94478b | 2015-11-20 02:19:36 +0000 | [diff] [blame] | 539 | return createELFFileAux<T<ELF32LE>>(MB); | 
|  | 540 | return createELFFileAux<T<ELF32BE>>(MB); | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 541 | } | 
|  | 542 | if (Type.first == ELF::ELFCLASS64) { | 
|  | 543 | if (Type.second == ELF::ELFDATA2LSB) | 
| Rui Ueyama | d94478b | 2015-11-20 02:19:36 +0000 | [diff] [blame] | 544 | return createELFFileAux<T<ELF64LE>>(MB); | 
|  | 545 | return createELFFileAux<T<ELF64BE>>(MB); | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 546 | } | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 547 | fatal("invalid file class: " + MB.getBufferIdentifier()); | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 548 | } | 
|  | 549 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 550 | std::unique_ptr<InputFile> elf::createObjectFile(MemoryBufferRef MB, | 
|  | 551 | StringRef ArchiveName) { | 
| Rui Ueyama | c89bff2 | 2016-02-23 18:17:11 +0000 | [diff] [blame] | 552 | using namespace sys::fs; | 
|  | 553 | std::unique_ptr<InputFile> F; | 
|  | 554 | if (identify_magic(MB.getBuffer()) == file_magic::bitcode) | 
|  | 555 | F.reset(new BitcodeFile(MB)); | 
|  | 556 | else | 
|  | 557 | F = createELFFile<ObjectFile>(MB); | 
| Rui Ueyama | 71c066d | 2016-02-02 08:22:41 +0000 | [diff] [blame] | 558 | F->ArchiveName = ArchiveName; | 
|  | 559 | return F; | 
| Rui Ueyama | 533c030 | 2016-01-06 00:09:43 +0000 | [diff] [blame] | 560 | } | 
|  | 561 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 562 | std::unique_ptr<InputFile> elf::createSharedFile(MemoryBufferRef MB) { | 
| Rui Ueyama | 533c030 | 2016-01-06 00:09:43 +0000 | [diff] [blame] | 563 | return createELFFile<SharedFile>(MB); | 
|  | 564 | } | 
|  | 565 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 566 | template class elf::ELFFileBase<ELF32LE>; | 
|  | 567 | template class elf::ELFFileBase<ELF32BE>; | 
|  | 568 | template class elf::ELFFileBase<ELF64LE>; | 
|  | 569 | template class elf::ELFFileBase<ELF64BE>; | 
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 570 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 571 | template class elf::ObjectFile<ELF32LE>; | 
|  | 572 | template class elf::ObjectFile<ELF32BE>; | 
|  | 573 | template class elf::ObjectFile<ELF64LE>; | 
|  | 574 | template class elf::ObjectFile<ELF64BE>; | 
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 575 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 576 | template class elf::SharedFile<ELF32LE>; | 
|  | 577 | template class elf::SharedFile<ELF32BE>; | 
|  | 578 | template class elf::SharedFile<ELF64LE>; | 
|  | 579 | template class elf::SharedFile<ELF64BE>; |