| 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 | 156f4ee | 2016-04-28 19:30:41 +0000 | [diff] [blame] | 11 | #include "Driver.h" | 
| Rafael Espindola | 5217f84 | 2016-09-28 16:31:05 +0000 | [diff] [blame] | 12 | #include "ELFCreator.h" | 
| Rafael Espindola | 192e1fa | 2015-08-06 15:08:23 +0000 | [diff] [blame] | 13 | #include "Error.h" | 
| Rafael Espindola | 9d13d04 | 2016-02-11 15:24:48 +0000 | [diff] [blame] | 14 | #include "InputSection.h" | 
| George Rimar | 67e3ff8 | 2016-08-12 19:56:57 +0000 | [diff] [blame] | 15 | #include "LinkerScript.h" | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 16 | #include "SymbolTable.h" | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 17 | #include "Symbols.h" | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 18 | #include "llvm/ADT/STLExtras.h" | 
| Davide Italiano | 60976ba | 2016-06-29 06:12:39 +0000 | [diff] [blame] | 19 | #include "llvm/Bitcode/ReaderWriter.h" | 
| Rafael Espindola | 4d480ed | 2016-04-21 21:44:25 +0000 | [diff] [blame] | 20 | #include "llvm/CodeGen/Analysis.h" | 
| Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 21 | #include "llvm/IR/LLVMContext.h" | 
| Rafael Espindola | 4de44b7 | 2016-03-02 15:43:50 +0000 | [diff] [blame] | 22 | #include "llvm/IR/Module.h" | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 23 | #include "llvm/LTO/LTO.h" | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 24 | #include "llvm/MC/StringTableBuilder.h" | 
| Davide Italiano | e02ba98 | 2016-09-08 21:18:38 +0000 | [diff] [blame] | 25 | #include "llvm/Support/Path.h" | 
| Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 26 | #include "llvm/Support/raw_ostream.h" | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 27 |  | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 28 | using namespace llvm; | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 29 | using namespace llvm::ELF; | 
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 30 | using namespace llvm::object; | 
| Rui Ueyama | f5c4aca | 2015-09-30 17:06:09 +0000 | [diff] [blame] | 31 | using namespace llvm::sys::fs; | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 32 |  | 
|  | 33 | using namespace lld; | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 34 | using namespace lld::elf; | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 35 |  | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 36 | std::vector<InputFile *> InputFile::Pool; | 
|  | 37 |  | 
|  | 38 | // Deletes all InputFile instances created so far. | 
|  | 39 | void InputFile::freePool() { | 
|  | 40 | // Files are freed in reverse order so that files created | 
|  | 41 | // from other files (e.g. object files extracted from archives) | 
|  | 42 | // are freed in the proper order. | 
|  | 43 | for (int I = Pool.size() - 1; I >= 0; --I) | 
|  | 44 | delete Pool[I]; | 
|  | 45 | } | 
|  | 46 |  | 
| Rafael Espindola | 78db5a9 | 2016-05-09 21:40:06 +0000 | [diff] [blame] | 47 | // Returns "(internal)", "foo.a(bar.o)" or "baz.o". | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 48 | std::string elf::getFilename(const InputFile *F) { | 
| Rafael Espindola | 78db5a9 | 2016-05-09 21:40:06 +0000 | [diff] [blame] | 49 | if (!F) | 
|  | 50 | return "(internal)"; | 
|  | 51 | if (!F->ArchiveName.empty()) | 
|  | 52 | return (F->ArchiveName + "(" + F->getName() + ")").str(); | 
|  | 53 | return F->getName(); | 
|  | 54 | } | 
|  | 55 |  | 
| George Rimar | 10874f7 | 2016-10-03 11:13:55 +0000 | [diff] [blame^] | 56 | template <class ELFT> static ELFFile<ELFT> createELFObj(MemoryBufferRef MB) { | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 57 | std::error_code EC; | 
| Rui Ueyama | eb3413e | 2016-03-03 06:22:29 +0000 | [diff] [blame] | 58 | ELFFile<ELFT> F(MB.getBuffer(), EC); | 
| Rui Ueyama | f8292e9 | 2016-07-15 02:01:03 +0000 | [diff] [blame] | 59 | if (EC) | 
|  | 60 | error(EC, "failed to read " + MB.getBufferIdentifier()); | 
| Rui Ueyama | eb3413e | 2016-03-03 06:22:29 +0000 | [diff] [blame] | 61 | return F; | 
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 62 | } | 
|  | 63 |  | 
| Rui Ueyama | 5e64d3f | 2016-06-29 01:30:50 +0000 | [diff] [blame] | 64 | template <class ELFT> static ELFKind getELFKind() { | 
| Rui Ueyama | f588ac4 | 2016-01-06 00:09:41 +0000 | [diff] [blame] | 65 | if (ELFT::TargetEndianness == support::little) | 
|  | 66 | return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind; | 
|  | 67 | return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind; | 
| Rui Ueyama | 2022e81 | 2015-11-20 02:10:52 +0000 | [diff] [blame] | 68 | } | 
|  | 69 |  | 
|  | 70 | template <class ELFT> | 
| Rui Ueyama | 5e64d3f | 2016-06-29 01:30:50 +0000 | [diff] [blame] | 71 | ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) | 
|  | 72 | : InputFile(K, MB), ELFObj(createELFObj<ELFT>(MB)) { | 
|  | 73 | EKind = getELFKind<ELFT>(); | 
|  | 74 | EMachine = ELFObj.getHeader()->e_machine; | 
|  | 75 | } | 
|  | 76 |  | 
|  | 77 | template <class ELFT> | 
| Rui Ueyama | 9328b2c | 2016-03-14 23:16:09 +0000 | [diff] [blame] | 78 | typename ELFT::SymRange ELFFileBase<ELFT>::getElfSymbols(bool OnlyGlobals) { | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 79 | if (!Symtab) | 
|  | 80 | return Elf_Sym_Range(nullptr, nullptr); | 
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 81 | Elf_Sym_Range Syms = ELFObj.symbols(Symtab); | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 82 | uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); | 
|  | 83 | uint32_t FirstNonLocal = Symtab->sh_info; | 
|  | 84 | if (FirstNonLocal > NumSymbols) | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 85 | fatal(getFilename(this) + ": invalid sh_info in symbol table"); | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 86 |  | 
|  | 87 | if (OnlyGlobals) | 
| Rafael Espindola | 0f7ccc3 | 2016-04-05 14:47:28 +0000 | [diff] [blame] | 88 | return makeArrayRef(Syms.begin() + FirstNonLocal, Syms.end()); | 
|  | 89 | return makeArrayRef(Syms.begin(), Syms.end()); | 
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 90 | } | 
|  | 91 |  | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 92 | template <class ELFT> | 
|  | 93 | uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const { | 
| Rui Ueyama | dc8d3a2 | 2015-12-24 08:36:56 +0000 | [diff] [blame] | 94 | uint32_t I = Sym.st_shndx; | 
|  | 95 | if (I == ELF::SHN_XINDEX) | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 96 | return ELFObj.getExtendedSymbolTableIndex(&Sym, Symtab, SymtabSHNDX); | 
| Rafael Espindola | 972b236 | 2016-03-09 14:31:18 +0000 | [diff] [blame] | 97 | if (I >= ELF::SHN_LORESERVE) | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 98 | return 0; | 
| Rui Ueyama | dc8d3a2 | 2015-12-24 08:36:56 +0000 | [diff] [blame] | 99 | return I; | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 100 | } | 
|  | 101 |  | 
| Rafael Espindola | af70764 | 2015-10-12 01:55:32 +0000 | [diff] [blame] | 102 | template <class ELFT> void ELFFileBase<ELFT>::initStringTable() { | 
| Rafael Espindola | 3e60379 | 2015-10-01 20:26:37 +0000 | [diff] [blame] | 103 | if (!Symtab) | 
|  | 104 | return; | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 105 | StringTable = check(ELFObj.getStringTableForSymtab(*Symtab)); | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 106 | } | 
|  | 107 |  | 
|  | 108 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 109 | elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M) | 
| Rafael Espindola | 2a4b271 | 2015-10-13 01:17:02 +0000 | [diff] [blame] | 110 | : ELFFileBase<ELFT>(Base::ObjectKind, M) {} | 
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 111 |  | 
|  | 112 | template <class ELFT> | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 113 | ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getNonLocalSymbols() { | 
|  | 114 | if (!this->Symtab) | 
|  | 115 | return this->SymbolBodies; | 
|  | 116 | uint32_t FirstNonLocal = this->Symtab->sh_info; | 
|  | 117 | return makeArrayRef(this->SymbolBodies).slice(FirstNonLocal); | 
|  | 118 | } | 
|  | 119 |  | 
|  | 120 | template <class ELFT> | 
|  | 121 | ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() { | 
|  | 122 | if (!this->Symtab) | 
|  | 123 | return this->SymbolBodies; | 
|  | 124 | uint32_t FirstNonLocal = this->Symtab->sh_info; | 
|  | 125 | return makeArrayRef(this->SymbolBodies).slice(1, FirstNonLocal - 1); | 
|  | 126 | } | 
|  | 127 |  | 
|  | 128 | template <class ELFT> | 
|  | 129 | ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getSymbols() { | 
|  | 130 | if (!this->Symtab) | 
|  | 131 | return this->SymbolBodies; | 
|  | 132 | return makeArrayRef(this->SymbolBodies).slice(1); | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 133 | } | 
|  | 134 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 135 | template <class ELFT> uint32_t elf::ObjectFile<ELFT>::getMipsGp0() const { | 
| Simon Atanasyan | add74f3 | 2016-05-04 10:07:38 +0000 | [diff] [blame] | 136 | if (ELFT::Is64Bits && MipsOptions && MipsOptions->Reginfo) | 
|  | 137 | return MipsOptions->Reginfo->ri_gp_value; | 
|  | 138 | if (!ELFT::Is64Bits && MipsReginfo && MipsReginfo->Reginfo) | 
| Rui Ueyama | 70eed36 | 2016-01-06 22:42:43 +0000 | [diff] [blame] | 139 | return MipsReginfo->Reginfo->ri_gp_value; | 
|  | 140 | return 0; | 
| Simon Atanasyan | 57830b6 | 2015-12-25 13:02:13 +0000 | [diff] [blame] | 141 | } | 
|  | 142 |  | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 143 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 144 | void elf::ObjectFile<ELFT>::parse(DenseSet<StringRef> &ComdatGroups) { | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 145 | // Read section and symbol tables. | 
| Rui Ueyama | 52d3b67 | 2016-01-06 02:06:33 +0000 | [diff] [blame] | 146 | initializeSections(ComdatGroups); | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 147 | initializeSymbols(); | 
|  | 148 | } | 
|  | 149 |  | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 150 | // Sections with SHT_GROUP and comdat bits define comdat section groups. | 
|  | 151 | // They are identified and deduplicated by group name. This function | 
|  | 152 | // returns a group name. | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 153 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 154 | StringRef elf::ObjectFile<ELFT>::getShtGroupSignature(const Elf_Shdr &Sec) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 155 | const ELFFile<ELFT> &Obj = this->ELFObj; | 
| Rui Ueyama | 188d2c3 | 2016-07-15 20:05:05 +0000 | [diff] [blame] | 156 | const Elf_Shdr *Symtab = check(Obj.getSection(Sec.sh_link)); | 
|  | 157 | const Elf_Sym *Sym = Obj.getSymbol(Symtab, Sec.sh_info); | 
|  | 158 | StringRef Strtab = check(Obj.getStringTableForSymtab(*Symtab)); | 
|  | 159 | return check(Sym->getName(Strtab)); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 160 | } | 
|  | 161 |  | 
|  | 162 | template <class ELFT> | 
| Rui Ueyama | 368e1ea | 2016-03-13 22:02:04 +0000 | [diff] [blame] | 163 | ArrayRef<typename elf::ObjectFile<ELFT>::Elf_Word> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 164 | elf::ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 165 | const ELFFile<ELFT> &Obj = this->ELFObj; | 
| Rui Ueyama | 368e1ea | 2016-03-13 22:02:04 +0000 | [diff] [blame] | 166 | ArrayRef<Elf_Word> Entries = | 
|  | 167 | check(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec)); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 168 | if (Entries.empty() || Entries[0] != GRP_COMDAT) | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 169 | fatal(getFilename(this) + ": unsupported SHT_GROUP format"); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 170 | return Entries.slice(1); | 
|  | 171 | } | 
|  | 172 |  | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 173 | template <class ELFT> | 
|  | 174 | bool elf::ObjectFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { | 
| Rui Ueyama | fb6d499 | 2016-04-29 16:12:29 +0000 | [diff] [blame] | 175 | // We don't merge sections if -O0 (default is -O1). This makes sometimes | 
|  | 176 | // the linker significantly faster, although the output will be bigger. | 
|  | 177 | if (Config->Optimize == 0) | 
|  | 178 | return false; | 
|  | 179 |  | 
| Rui Ueyama | 3ebc71e | 2016-08-03 05:28:02 +0000 | [diff] [blame] | 180 | // A mergeable section with size 0 is useless because they don't have | 
|  | 181 | // any data to merge. A mergeable string section with size 0 can be | 
|  | 182 | // argued as invalid because it doesn't end with a null character. | 
|  | 183 | // We'll avoid a mess by handling them as if they were non-mergeable. | 
|  | 184 | if (Sec.sh_size == 0) | 
|  | 185 | return false; | 
|  | 186 |  | 
| Rui Ueyama | c75ef85 | 2016-09-21 03:22:18 +0000 | [diff] [blame] | 187 | // Check for sh_entsize. The ELF spec is not clear about the zero | 
|  | 188 | // sh_entsize. It says that "the member [sh_entsize] contains 0 if | 
|  | 189 | // the section does not hold a table of fixed-size entries". We know | 
|  | 190 | // that Rust 1.13 produces a string mergeable section with a zero | 
|  | 191 | // sh_entsize. Here we just accept it rather than being picky about it. | 
|  | 192 | uintX_t EntSize = Sec.sh_entsize; | 
|  | 193 | if (EntSize == 0) | 
|  | 194 | return false; | 
|  | 195 | if (Sec.sh_size % EntSize) | 
|  | 196 | fatal(getFilename(this) + | 
|  | 197 | ": SHF_MERGE section size must be a multiple of sh_entsize"); | 
|  | 198 |  | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 199 | uintX_t Flags = Sec.sh_flags; | 
|  | 200 | if (!(Flags & SHF_MERGE)) | 
|  | 201 | return false; | 
|  | 202 | if (Flags & SHF_WRITE) | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 203 | fatal(getFilename(this) + ": writable SHF_MERGE section is not supported"); | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 204 |  | 
| Peter Smith | 4df2e14 | 2016-05-18 11:40:16 +0000 | [diff] [blame] | 205 | // Don't try to merge if the alignment is larger than the sh_entsize and this | 
| Rafael Espindola | 7efa5be | 2016-02-19 14:17:40 +0000 | [diff] [blame] | 206 | // is not SHF_STRINGS. | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 207 | // | 
| Rafael Espindola | 7efa5be | 2016-02-19 14:17:40 +0000 | [diff] [blame] | 208 | // Since this is not a SHF_STRINGS, we would need to pad after every entity. | 
|  | 209 | // 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] | 210 | // sh_entsize. | 
| Rafael Espindola | 7efa5be | 2016-02-19 14:17:40 +0000 | [diff] [blame] | 211 | if (Flags & SHF_STRINGS) | 
|  | 212 | return true; | 
|  | 213 |  | 
| George Rimar | dcddfb6 | 2016-06-08 12:04:59 +0000 | [diff] [blame] | 214 | return Sec.sh_addralign <= EntSize; | 
| Rafael Espindola | f82ed2a | 2015-10-24 22:51:01 +0000 | [diff] [blame] | 215 | } | 
|  | 216 |  | 
|  | 217 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 218 | void elf::ObjectFile<ELFT>::initializeSections( | 
| Rafael Espindola | f1d598c | 2016-02-12 21:17:10 +0000 | [diff] [blame] | 219 | DenseSet<StringRef> &ComdatGroups) { | 
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 220 | uint64_t Size = this->ELFObj.getNumSections(); | 
| Rafael Espindola | 7167585 | 2015-09-22 00:16:19 +0000 | [diff] [blame] | 221 | Sections.resize(Size); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 222 | unsigned I = -1; | 
| Rafael Espindola | d42f4e5 | 2015-10-08 12:02:38 +0000 | [diff] [blame] | 223 | const ELFFile<ELFT> &Obj = this->ELFObj; | 
|  | 224 | for (const Elf_Shdr &Sec : Obj.sections()) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 225 | ++I; | 
| Rafael Espindola | ccfe3cb | 2016-04-04 14:04:16 +0000 | [diff] [blame] | 226 | if (Sections[I] == &InputSection<ELFT>::Discarded) | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 227 | continue; | 
|  | 228 |  | 
| Eugene Leviant | 27be542 | 2016-09-28 08:42:02 +0000 | [diff] [blame] | 229 | if (Sec.sh_flags & SHF_EXCLUDE) { | 
|  | 230 | Sections[I] = &InputSection<ELFT>::Discarded; | 
|  | 231 | continue; | 
|  | 232 | } | 
|  | 233 |  | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 234 | switch (Sec.sh_type) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 235 | case SHT_GROUP: | 
| Rafael Espindola | ccfe3cb | 2016-04-04 14:04:16 +0000 | [diff] [blame] | 236 | Sections[I] = &InputSection<ELFT>::Discarded; | 
| Rui Ueyama | 52d3b67 | 2016-01-06 02:06:33 +0000 | [diff] [blame] | 237 | if (ComdatGroups.insert(getShtGroupSignature(Sec)).second) | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 238 | continue; | 
| Rui Ueyama | 33b3f21 | 2016-01-06 20:30:02 +0000 | [diff] [blame] | 239 | for (uint32_t SecIndex : getShtGroupEntries(Sec)) { | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 240 | if (SecIndex >= Size) | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 241 | fatal(getFilename(this) + ": invalid section index in group: " + | 
|  | 242 | Twine(SecIndex)); | 
| Rafael Espindola | ccfe3cb | 2016-04-04 14:04:16 +0000 | [diff] [blame] | 243 | Sections[SecIndex] = &InputSection<ELFT>::Discarded; | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 244 | } | 
|  | 245 | break; | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 246 | case SHT_SYMTAB: | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 247 | this->Symtab = &Sec; | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 248 | break; | 
| Rafael Espindola | 1130935c | 2016-03-03 16:21:44 +0000 | [diff] [blame] | 249 | case SHT_SYMTAB_SHNDX: | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 250 | this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec)); | 
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 251 | break; | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 252 | case SHT_STRTAB: | 
|  | 253 | case SHT_NULL: | 
| Rafael Espindola | cde2513 | 2015-08-13 14:45:44 +0000 | [diff] [blame] | 254 | break; | 
| Rui Ueyama | e79b09a | 2015-11-21 22:19:32 +0000 | [diff] [blame] | 255 | default: | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 256 | Sections[I] = createInputSection(Sec); | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 257 | } | 
|  | 258 | } | 
|  | 259 | } | 
|  | 260 |  | 
| Rafael Espindola | f1d598c | 2016-02-12 21:17:10 +0000 | [diff] [blame] | 261 | template <class ELFT> | 
|  | 262 | InputSectionBase<ELFT> * | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 263 | elf::ObjectFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) { | 
|  | 264 | uint32_t Idx = Sec.sh_info; | 
|  | 265 | if (Idx >= Sections.size()) | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 266 | fatal(getFilename(this) + ": invalid relocated section index: " + | 
|  | 267 | Twine(Idx)); | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 268 | InputSectionBase<ELFT> *Target = Sections[Idx]; | 
|  | 269 |  | 
|  | 270 | // Strictly speaking, a relocation section must be included in the | 
|  | 271 | // group of the section it relocates. However, LLVM 3.3 and earlier | 
|  | 272 | // would fail to do so, so we gracefully handle that case. | 
| Rafael Espindola | ccfe3cb | 2016-04-04 14:04:16 +0000 | [diff] [blame] | 273 | if (Target == &InputSection<ELFT>::Discarded) | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 274 | return nullptr; | 
|  | 275 |  | 
|  | 276 | if (!Target) | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 277 | fatal(getFilename(this) + ": unsupported relocation reference"); | 
| Rui Ueyama | e270c0a | 2016-03-13 21:52:57 +0000 | [diff] [blame] | 278 | return Target; | 
|  | 279 | } | 
|  | 280 |  | 
|  | 281 | template <class ELFT> | 
|  | 282 | InputSectionBase<ELFT> * | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 283 | elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 284 | StringRef Name = check(this->ELFObj.getSectionName(&Sec)); | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 285 |  | 
| Rafael Espindola | 042a3f2 | 2016-09-08 14:06:08 +0000 | [diff] [blame] | 286 | switch (Sec.sh_type) { | 
|  | 287 | case SHT_ARM_ATTRIBUTES: | 
|  | 288 | // FIXME: ARM meta-data section. At present attributes are ignored, | 
|  | 289 | // they can be used to reason about object compatibility. | 
|  | 290 | return &InputSection<ELFT>::Discarded; | 
|  | 291 | case SHT_MIPS_REGINFO: | 
|  | 292 | MipsReginfo.reset(new MipsReginfoInputSection<ELFT>(this, &Sec, Name)); | 
|  | 293 | return MipsReginfo.get(); | 
|  | 294 | case SHT_MIPS_OPTIONS: | 
|  | 295 | MipsOptions.reset(new MipsOptionsInputSection<ELFT>(this, &Sec, Name)); | 
|  | 296 | return MipsOptions.get(); | 
|  | 297 | case SHT_MIPS_ABIFLAGS: | 
|  | 298 | MipsAbiFlags.reset(new MipsAbiFlagsInputSection<ELFT>(this, &Sec, Name)); | 
|  | 299 | return MipsAbiFlags.get(); | 
|  | 300 | case SHT_RELA: | 
|  | 301 | case SHT_REL: { | 
|  | 302 | // This section contains relocation information. | 
|  | 303 | // If -r is given, we do not interpret or apply relocation | 
|  | 304 | // but just copy relocation sections to output. | 
|  | 305 | if (Config->Relocatable) | 
|  | 306 | return new (IAlloc.Allocate()) InputSection<ELFT>(this, &Sec, Name); | 
|  | 307 |  | 
|  | 308 | // Find the relocation target section and associate this | 
|  | 309 | // section with it. | 
|  | 310 | InputSectionBase<ELFT> *Target = getRelocTarget(Sec); | 
|  | 311 | if (!Target) | 
|  | 312 | return nullptr; | 
|  | 313 | if (auto *S = dyn_cast<InputSection<ELFT>>(Target)) { | 
|  | 314 | S->RelocSections.push_back(&Sec); | 
|  | 315 | return nullptr; | 
|  | 316 | } | 
|  | 317 | if (auto *S = dyn_cast<EhInputSection<ELFT>>(Target)) { | 
|  | 318 | if (S->RelocSection) | 
|  | 319 | fatal(getFilename(this) + | 
|  | 320 | ": multiple relocation sections to .eh_frame are not supported"); | 
|  | 321 | S->RelocSection = &Sec; | 
|  | 322 | return nullptr; | 
|  | 323 | } | 
|  | 324 | fatal(getFilename(this) + | 
|  | 325 | ": relocations pointing to SHF_MERGE are not supported"); | 
|  | 326 | } | 
|  | 327 | } | 
|  | 328 |  | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 329 | // .note.GNU-stack is a marker section to control the presence of | 
|  | 330 | // PT_GNU_STACK segment in outputs. Since the presence of the segment | 
|  | 331 | // is controlled only by the command line option (-z execstack) in LLD, | 
|  | 332 | // .note.GNU-stack is ignored. | 
|  | 333 | if (Name == ".note.GNU-stack") | 
| Rafael Espindola | ccfe3cb | 2016-04-04 14:04:16 +0000 | [diff] [blame] | 334 | return &InputSection<ELFT>::Discarded; | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 335 |  | 
| Rui Ueyama | fc6a4b0 | 2016-04-07 21:04:51 +0000 | [diff] [blame] | 336 | if (Name == ".note.GNU-split-stack") { | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 337 | error("objects using splitstacks are not supported"); | 
| Rui Ueyama | fc6a4b0 | 2016-04-07 21:04:51 +0000 | [diff] [blame] | 338 | return &InputSection<ELFT>::Discarded; | 
|  | 339 | } | 
|  | 340 |  | 
| George Rimar | f21aade | 2016-08-31 08:38:11 +0000 | [diff] [blame] | 341 | if (Config->Strip != StripPolicy::None && Name.startswith(".debug")) | 
| Rui Ueyama | fc6a4b0 | 2016-04-07 21:04:51 +0000 | [diff] [blame] | 342 | return &InputSection<ELFT>::Discarded; | 
| George Rimar | 3c45ed2 | 2016-03-09 18:01:45 +0000 | [diff] [blame] | 343 |  | 
| Rui Ueyama | eba9b63 | 2016-07-15 04:57:44 +0000 | [diff] [blame] | 344 | // The linker merges EH (exception handling) frames and creates a | 
|  | 345 | // .eh_frame_hdr section for runtime. So we handle them with a special | 
|  | 346 | // class. For relocatable outputs, they are just passed through. | 
|  | 347 | if (Name == ".eh_frame" && !Config->Relocatable) | 
| Rafael Espindola | 042a3f2 | 2016-09-08 14:06:08 +0000 | [diff] [blame] | 348 | return new (EHAlloc.Allocate()) EhInputSection<ELFT>(this, &Sec, Name); | 
| Rui Ueyama | eba9b63 | 2016-07-15 04:57:44 +0000 | [diff] [blame] | 349 |  | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 350 | if (shouldMerge(Sec)) | 
| Rafael Espindola | 042a3f2 | 2016-09-08 14:06:08 +0000 | [diff] [blame] | 351 | return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec, Name); | 
|  | 352 | return new (IAlloc.Allocate()) InputSection<ELFT>(this, &Sec, Name); | 
| Rui Ueyama | 3f11c8c | 2015-12-24 08:41:12 +0000 | [diff] [blame] | 353 | } | 
|  | 354 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 355 | template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() { | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 356 | this->initStringTable(); | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 357 | Elf_Sym_Range Syms = this->getElfSymbols(false); | 
| Reid Kleckner | f7b85e0 | 2015-08-11 20:06:51 +0000 | [diff] [blame] | 358 | uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 359 | SymbolBodies.reserve(NumSymbols); | 
| Rafael Espindola | 3031851 | 2015-08-04 14:00:56 +0000 | [diff] [blame] | 360 | for (const Elf_Sym &Sym : Syms) | 
| Rui Ueyama | c5e372d | 2016-01-21 02:10:12 +0000 | [diff] [blame] | 361 | SymbolBodies.push_back(createSymbolBody(&Sym)); | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 362 | } | 
|  | 363 |  | 
|  | 364 | template <class ELFT> | 
| Rafael Espindola | c159c96 | 2015-10-19 21:00:02 +0000 | [diff] [blame] | 365 | InputSectionBase<ELFT> * | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 366 | elf::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 367 | uint32_t Index = this->getSectionIndex(Sym); | 
|  | 368 | if (Index == 0) | 
| Rafael Espindola | 4cda581 | 2015-10-16 15:29:48 +0000 | [diff] [blame] | 369 | return nullptr; | 
| George Rimar | 683a35d | 2016-08-12 19:25:54 +0000 | [diff] [blame] | 370 | if (Index >= Sections.size()) | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 371 | fatal(getFilename(this) + ": invalid section index: " + Twine(Index)); | 
| Rui Ueyama | 0b28952 | 2016-02-25 18:43:51 +0000 | [diff] [blame] | 372 | InputSectionBase<ELFT> *S = Sections[Index]; | 
| George Rimar | 683a35d | 2016-08-12 19:25:54 +0000 | [diff] [blame] | 373 | // We found that GNU assembler 2.17.50 [FreeBSD] 2007-07-03 | 
|  | 374 | // could generate broken objects. STT_SECTION symbols can be | 
|  | 375 | // associated with SHT_REL[A]/SHT_SYMTAB/SHT_STRTAB sections. | 
|  | 376 | // In this case it is fine for section to be null here as we | 
|  | 377 | // do not allocate sections of these types. | 
|  | 378 | if (!S || S == &InputSectionBase<ELFT>::Discarded) | 
| Rui Ueyama | 0b28952 | 2016-02-25 18:43:51 +0000 | [diff] [blame] | 379 | return S; | 
|  | 380 | return S->Repl; | 
| Rafael Espindola | 4cda581 | 2015-10-16 15:29:48 +0000 | [diff] [blame] | 381 | } | 
|  | 382 |  | 
|  | 383 | template <class ELFT> | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 384 | SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) { | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 385 | int Binding = Sym->getBinding(); | 
| Rafael Espindola | 1f5b70f | 2016-03-11 14:21:37 +0000 | [diff] [blame] | 386 | InputSectionBase<ELFT> *Sec = getSection(*Sym); | 
|  | 387 | if (Binding == STB_LOCAL) { | 
| Rafael Espindola | ccfe3cb | 2016-04-04 14:04:16 +0000 | [diff] [blame] | 388 | if (Sym->st_shndx == SHN_UNDEF) | 
| Rui Ueyama | 8b8d005 | 2016-07-08 17:58:54 +0000 | [diff] [blame] | 389 | return new (this->Alloc) | 
| Rui Ueyama | 434b561 | 2016-07-17 03:11:46 +0000 | [diff] [blame] | 390 | Undefined(Sym->st_name, Sym->st_other, Sym->getType(), this); | 
| Rui Ueyama | 8b8d005 | 2016-07-08 17:58:54 +0000 | [diff] [blame] | 391 | return new (this->Alloc) DefinedRegular<ELFT>(*Sym, Sec); | 
| Rafael Espindola | 1f5b70f | 2016-03-11 14:21:37 +0000 | [diff] [blame] | 392 | } | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 393 |  | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 394 | StringRef Name = check(Sym->getName(this->StringTable)); | 
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 395 |  | 
| Rafael Espindola | 4cda581 | 2015-10-16 15:29:48 +0000 | [diff] [blame] | 396 | switch (Sym->st_shndx) { | 
| Rafael Espindola | 51d4690 | 2015-08-28 21:26:51 +0000 | [diff] [blame] | 397 | case SHN_UNDEF: | 
| George Rimar | 10874f7 | 2016-10-03 11:13:55 +0000 | [diff] [blame^] | 398 | return elf::Symtab<ELFT>::X->addUndefined(Name, Binding, Sym->st_other, | 
|  | 399 | Sym->getType(), | 
|  | 400 | /*CanOmitFromDynSym*/ false, this) | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 401 | ->body(); | 
| Rafael Espindola | 51d4690 | 2015-08-28 21:26:51 +0000 | [diff] [blame] | 402 | case SHN_COMMON: | 
| George Rimar | 10874f7 | 2016-10-03 11:13:55 +0000 | [diff] [blame^] | 403 | return elf::Symtab<ELFT>::X->addCommon(Name, Sym->st_size, Sym->st_value, | 
|  | 404 | Binding, Sym->st_other, | 
|  | 405 | Sym->getType(), this) | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 406 | ->body(); | 
| Rafael Espindola | 51d4690 | 2015-08-28 21:26:51 +0000 | [diff] [blame] | 407 | } | 
| Rafael Espindola | 2034822 | 2015-08-24 21:43:25 +0000 | [diff] [blame] | 408 |  | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 409 | switch (Binding) { | 
| Rafael Espindola | b13df65 | 2015-08-11 17:33:02 +0000 | [diff] [blame] | 410 | default: | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 411 | fatal(getFilename(this) + ": unexpected binding: " + Twine(Binding)); | 
| Rafael Espindola | b13df65 | 2015-08-11 17:33:02 +0000 | [diff] [blame] | 412 | case STB_GLOBAL: | 
| Rafael Espindola | 3a63f3f | 2015-08-28 20:19:34 +0000 | [diff] [blame] | 413 | case STB_WEAK: | 
| Rafael Espindola | 1f5b70f | 2016-03-11 14:21:37 +0000 | [diff] [blame] | 414 | case STB_GNU_UNIQUE: | 
| Rafael Espindola | ccfe3cb | 2016-04-04 14:04:16 +0000 | [diff] [blame] | 415 | if (Sec == &InputSection<ELFT>::Discarded) | 
| George Rimar | 10874f7 | 2016-10-03 11:13:55 +0000 | [diff] [blame^] | 416 | return elf::Symtab<ELFT>::X->addUndefined(Name, Binding, Sym->st_other, | 
|  | 417 | Sym->getType(), | 
|  | 418 | /*CanOmitFromDynSym*/ false, | 
|  | 419 | this) | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 420 | ->body(); | 
| Peter Collingbourne | 3db410e | 2016-05-01 06:00:09 +0000 | [diff] [blame] | 421 | return elf::Symtab<ELFT>::X->addRegular(Name, *Sym, Sec)->body(); | 
| Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 422 | } | 
| Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 423 | } | 
|  | 424 |  | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 425 | template <class ELFT> void ArchiveFile::parse() { | 
| Rui Ueyama | 64bd8df | 2016-03-14 21:31:07 +0000 | [diff] [blame] | 426 | File = check(Archive::create(MB), "failed to parse archive"); | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 427 |  | 
| Rui Ueyama | 3d0f77b | 2016-09-30 17:56:20 +0000 | [diff] [blame] | 428 | // Read the symbol table to construct Lazy objects. | 
|  | 429 | for (const Archive::Symbol &Sym : File->symbols()) | 
|  | 430 | Symtab<ELFT>::X->addLazyArchive(this, Sym); | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 431 | } | 
|  | 432 |  | 
|  | 433 | // Returns a buffer pointing to a member file containing a given symbol. | 
|  | 434 | MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) { | 
| Rafael Espindola | 1130935c | 2016-03-03 16:21:44 +0000 | [diff] [blame] | 435 | Archive::Child C = | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 436 | check(Sym->getMember(), | 
| Rui Ueyama | 64bd8df | 2016-03-14 21:31:07 +0000 | [diff] [blame] | 437 | "could not get the member for symbol " + Sym->getName()); | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 438 |  | 
| Rafael Espindola | 8f3a6ae | 2015-11-05 14:40:28 +0000 | [diff] [blame] | 439 | if (!Seen.insert(C.getChildOffset()).second) | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 440 | return MemoryBufferRef(); | 
| Michael J. Spencer | 88f0d63 | 2015-09-08 20:36:20 +0000 | [diff] [blame] | 441 |  | 
| Rafael Espindola | 1dd2b3d | 2016-05-03 17:30:44 +0000 | [diff] [blame] | 442 | MemoryBufferRef Ret = | 
|  | 443 | check(C.getMemoryBufferRef(), | 
|  | 444 | "could not get the buffer for the member defining symbol " + | 
|  | 445 | Sym->getName()); | 
| Rafael Espindola | d1cbe4d | 2016-05-02 13:54:10 +0000 | [diff] [blame] | 446 |  | 
| Rui Ueyama | fe65877 | 2016-05-15 17:10:23 +0000 | [diff] [blame] | 447 | if (C.getParent()->isThin() && Driver->Cpio) | 
|  | 448 | Driver->Cpio->append(relativeToRoot(check(C.getFullName())), | 
|  | 449 | Ret.getBuffer()); | 
| Rafael Espindola | 1dd2b3d | 2016-05-03 17:30:44 +0000 | [diff] [blame] | 450 |  | 
|  | 451 | return Ret; | 
| Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 452 | } | 
|  | 453 |  | 
| Rafael Espindola | e1901cc | 2015-09-24 15:11:50 +0000 | [diff] [blame] | 454 | template <class ELFT> | 
|  | 455 | SharedFile<ELFT>::SharedFile(MemoryBufferRef M) | 
| Rui Ueyama | f588ac4 | 2016-01-06 00:09:41 +0000 | [diff] [blame] | 456 | : ELFFileBase<ELFT>(Base::SharedKind, M), AsNeeded(Config->AsNeeded) {} | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 457 |  | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 458 | template <class ELFT> | 
| Rui Ueyama | 9328b2c | 2016-03-14 23:16:09 +0000 | [diff] [blame] | 459 | const typename ELFT::Shdr * | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 460 | SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const { | 
|  | 461 | uint32_t Index = this->getSectionIndex(Sym); | 
|  | 462 | if (Index == 0) | 
|  | 463 | return nullptr; | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 464 | return check(this->ELFObj.getSection(Index)); | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 465 | } | 
|  | 466 |  | 
| Rui Ueyama | 7c71331 | 2016-01-06 01:56:36 +0000 | [diff] [blame] | 467 | // Partially parse the shared object file so that we can call | 
|  | 468 | // getSoName on this object. | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 469 | template <class ELFT> void SharedFile<ELFT>::parseSoName() { | 
| Rui Ueyama | 9328b2c | 2016-03-14 23:16:09 +0000 | [diff] [blame] | 470 | typedef typename ELFT::Dyn Elf_Dyn; | 
|  | 471 | typedef typename ELFT::uint uintX_t; | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 472 | const Elf_Shdr *DynamicSec = nullptr; | 
|  | 473 |  | 
|  | 474 | const ELFFile<ELFT> Obj = this->ELFObj; | 
|  | 475 | for (const Elf_Shdr &Sec : Obj.sections()) { | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 476 | switch (Sec.sh_type) { | 
|  | 477 | default: | 
|  | 478 | continue; | 
|  | 479 | case SHT_DYNSYM: | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 480 | this->Symtab = &Sec; | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 481 | break; | 
|  | 482 | case SHT_DYNAMIC: | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 483 | DynamicSec = &Sec; | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 484 | break; | 
| Rafael Espindola | 1130935c | 2016-03-03 16:21:44 +0000 | [diff] [blame] | 485 | case SHT_SYMTAB_SHNDX: | 
| Rafael Espindola | 75714f6 | 2016-03-03 22:24:39 +0000 | [diff] [blame] | 486 | this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec)); | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 487 | break; | 
| Peter Collingbourne | 21a12fc | 2016-04-27 20:22:31 +0000 | [diff] [blame] | 488 | case SHT_GNU_versym: | 
|  | 489 | this->VersymSec = &Sec; | 
|  | 490 | break; | 
|  | 491 | case SHT_GNU_verdef: | 
|  | 492 | this->VerdefSec = &Sec; | 
|  | 493 | break; | 
| Rafael Espindola | 115f0f3 | 2015-11-03 14:13:40 +0000 | [diff] [blame] | 494 | } | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 495 | } | 
|  | 496 |  | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 497 | this->initStringTable(); | 
| Rui Ueyama | 478f8eb | 2016-09-09 21:35:38 +0000 | [diff] [blame] | 498 |  | 
|  | 499 | // DSOs are identified by soname, and they usually contain | 
|  | 500 | // DT_SONAME tag in their header. But if they are missing, | 
|  | 501 | // filenames are used as default sonames. | 
| Davide Italiano | e02ba98 | 2016-09-08 21:18:38 +0000 | [diff] [blame] | 502 | SoName = sys::path::filename(this->getName()); | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 503 |  | 
| Rui Ueyama | 361d8b9 | 2015-10-12 15:49:02 +0000 | [diff] [blame] | 504 | if (!DynamicSec) | 
|  | 505 | return; | 
|  | 506 | auto *Begin = | 
|  | 507 | reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset); | 
|  | 508 | const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn); | 
| Rafael Espindola | c8b1581 | 2015-10-01 15:47:50 +0000 | [diff] [blame] | 509 |  | 
| Rui Ueyama | 361d8b9 | 2015-10-12 15:49:02 +0000 | [diff] [blame] | 510 | for (const Elf_Dyn &Dyn : make_range(Begin, End)) { | 
|  | 511 | if (Dyn.d_tag == DT_SONAME) { | 
|  | 512 | uintX_t Val = Dyn.getVal(); | 
|  | 513 | if (Val >= this->StringTable.size()) | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 514 | fatal(getFilename(this) + ": invalid DT_SONAME entry"); | 
| Rui Ueyama | e69ab10 | 2016-01-06 01:14:11 +0000 | [diff] [blame] | 515 | SoName = StringRef(this->StringTable.data() + Val); | 
| Rui Ueyama | 361d8b9 | 2015-10-12 15:49:02 +0000 | [diff] [blame] | 516 | return; | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 517 | } | 
|  | 518 | } | 
| Rafael Espindola | 6a3b5de | 2015-10-01 19:52:48 +0000 | [diff] [blame] | 519 | } | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 520 |  | 
| Peter Collingbourne | 21a12fc | 2016-04-27 20:22:31 +0000 | [diff] [blame] | 521 | // Parse the version definitions in the object file if present. Returns a vector | 
|  | 522 | // whose nth element contains a pointer to the Elf_Verdef for version identifier | 
|  | 523 | // n. Version identifiers that are not definitions map to nullptr. The array | 
|  | 524 | // always has at least length 1. | 
|  | 525 | template <class ELFT> | 
|  | 526 | std::vector<const typename ELFT::Verdef *> | 
|  | 527 | SharedFile<ELFT>::parseVerdefs(const Elf_Versym *&Versym) { | 
|  | 528 | std::vector<const Elf_Verdef *> Verdefs(1); | 
|  | 529 | // We only need to process symbol versions for this DSO if it has both a | 
|  | 530 | // versym and a verdef section, which indicates that the DSO contains symbol | 
|  | 531 | // version definitions. | 
|  | 532 | if (!VersymSec || !VerdefSec) | 
|  | 533 | return Verdefs; | 
|  | 534 |  | 
|  | 535 | // The location of the first global versym entry. | 
|  | 536 | Versym = reinterpret_cast<const Elf_Versym *>(this->ELFObj.base() + | 
|  | 537 | VersymSec->sh_offset) + | 
|  | 538 | this->Symtab->sh_info; | 
|  | 539 |  | 
|  | 540 | // We cannot determine the largest verdef identifier without inspecting | 
|  | 541 | // every Elf_Verdef, but both bfd and gold assign verdef identifiers | 
|  | 542 | // sequentially starting from 1, so we predict that the largest identifier | 
|  | 543 | // will be VerdefCount. | 
|  | 544 | unsigned VerdefCount = VerdefSec->sh_info; | 
|  | 545 | Verdefs.resize(VerdefCount + 1); | 
|  | 546 |  | 
|  | 547 | // Build the Verdefs array by following the chain of Elf_Verdef objects | 
|  | 548 | // from the start of the .gnu.version_d section. | 
|  | 549 | const uint8_t *Verdef = this->ELFObj.base() + VerdefSec->sh_offset; | 
|  | 550 | for (unsigned I = 0; I != VerdefCount; ++I) { | 
|  | 551 | auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef); | 
|  | 552 | Verdef += CurVerdef->vd_next; | 
|  | 553 | unsigned VerdefIndex = CurVerdef->vd_ndx; | 
|  | 554 | if (Verdefs.size() <= VerdefIndex) | 
|  | 555 | Verdefs.resize(VerdefIndex + 1); | 
|  | 556 | Verdefs[VerdefIndex] = CurVerdef; | 
|  | 557 | } | 
|  | 558 |  | 
|  | 559 | return Verdefs; | 
|  | 560 | } | 
|  | 561 |  | 
| Rui Ueyama | 7c71331 | 2016-01-06 01:56:36 +0000 | [diff] [blame] | 562 | // Fully parse the shared object file. This must be called after parseSoName(). | 
|  | 563 | template <class ELFT> void SharedFile<ELFT>::parseRest() { | 
| Peter Collingbourne | 21a12fc | 2016-04-27 20:22:31 +0000 | [diff] [blame] | 564 | // Create mapping from version identifiers to Elf_Verdef entries. | 
|  | 565 | const Elf_Versym *Versym = nullptr; | 
|  | 566 | std::vector<const Elf_Verdef *> Verdefs = parseVerdefs(Versym); | 
|  | 567 |  | 
| Rafael Espindola | 67d72c0 | 2016-03-11 12:06:30 +0000 | [diff] [blame] | 568 | Elf_Sym_Range Syms = this->getElfSymbols(true); | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 569 | for (const Elf_Sym &Sym : Syms) { | 
| Rafael Espindola | fb4f2fe | 2016-04-29 17:46:07 +0000 | [diff] [blame] | 570 | unsigned VersymIndex = 0; | 
|  | 571 | if (Versym) { | 
|  | 572 | VersymIndex = Versym->vs_index; | 
|  | 573 | ++Versym; | 
|  | 574 | } | 
|  | 575 |  | 
| Rafael Espindola | 18da0e5 | 2016-04-29 16:23:31 +0000 | [diff] [blame] | 576 | StringRef Name = check(Sym.getName(this->StringTable)); | 
|  | 577 | if (Sym.isUndefined()) { | 
|  | 578 | Undefs.push_back(Name); | 
|  | 579 | continue; | 
|  | 580 | } | 
|  | 581 |  | 
| Peter Collingbourne | 21a12fc | 2016-04-27 20:22:31 +0000 | [diff] [blame] | 582 | if (Versym) { | 
| Peter Collingbourne | 21a12fc | 2016-04-27 20:22:31 +0000 | [diff] [blame] | 583 | // Ignore local symbols and non-default versions. | 
| Rafael Espindola | d2454d6 | 2016-06-09 15:45:49 +0000 | [diff] [blame] | 584 | if (VersymIndex == VER_NDX_LOCAL || (VersymIndex & VERSYM_HIDDEN)) | 
| Peter Collingbourne | 21a12fc | 2016-04-27 20:22:31 +0000 | [diff] [blame] | 585 | continue; | 
|  | 586 | } | 
| Rafael Espindola | d2454d6 | 2016-06-09 15:45:49 +0000 | [diff] [blame] | 587 |  | 
|  | 588 | const Elf_Verdef *V = | 
|  | 589 | VersymIndex == VER_NDX_GLOBAL ? nullptr : Verdefs[VersymIndex]; | 
|  | 590 | elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V); | 
| Rafael Espindola | 18173d4 | 2015-09-08 15:50:05 +0000 | [diff] [blame] | 591 | } | 
|  | 592 | } | 
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 593 |  | 
| Rui Ueyama | 8035688 | 2016-08-03 20:33:17 +0000 | [diff] [blame] | 594 | static ELFKind getBitcodeELFKind(MemoryBufferRef MB) { | 
| Rui Ueyama | 7fdb438 | 2016-08-03 20:25:29 +0000 | [diff] [blame] | 595 | Triple T(getBitcodeTargetTriple(MB, Driver->Context)); | 
|  | 596 | if (T.isLittleEndian()) | 
|  | 597 | return T.isArch64Bit() ? ELF64LEKind : ELF32LEKind; | 
|  | 598 | return T.isArch64Bit() ? ELF64BEKind : ELF32BEKind; | 
| Davide Italiano | 60976ba | 2016-06-29 06:12:39 +0000 | [diff] [blame] | 599 | } | 
|  | 600 |  | 
| Rui Ueyama | 8035688 | 2016-08-03 20:33:17 +0000 | [diff] [blame] | 601 | static uint8_t getBitcodeMachineKind(MemoryBufferRef MB) { | 
| Rui Ueyama | 7fdb438 | 2016-08-03 20:25:29 +0000 | [diff] [blame] | 602 | Triple T(getBitcodeTargetTriple(MB, Driver->Context)); | 
|  | 603 | switch (T.getArch()) { | 
| Rui Ueyama | 523744d | 2016-07-07 02:46:30 +0000 | [diff] [blame] | 604 | case Triple::aarch64: | 
|  | 605 | return EM_AARCH64; | 
|  | 606 | case Triple::arm: | 
|  | 607 | return EM_ARM; | 
|  | 608 | case Triple::mips: | 
|  | 609 | case Triple::mipsel: | 
|  | 610 | case Triple::mips64: | 
|  | 611 | case Triple::mips64el: | 
|  | 612 | return EM_MIPS; | 
|  | 613 | case Triple::ppc: | 
|  | 614 | return EM_PPC; | 
|  | 615 | case Triple::ppc64: | 
|  | 616 | return EM_PPC64; | 
|  | 617 | case Triple::x86: | 
| Rui Ueyama | 7fdb438 | 2016-08-03 20:25:29 +0000 | [diff] [blame] | 618 | return T.isOSIAMCU() ? EM_IAMCU : EM_386; | 
| Rui Ueyama | 523744d | 2016-07-07 02:46:30 +0000 | [diff] [blame] | 619 | case Triple::x86_64: | 
|  | 620 | return EM_X86_64; | 
|  | 621 | default: | 
| Rui Ueyama | 429ef2a | 2016-07-15 20:38:28 +0000 | [diff] [blame] | 622 | fatal(MB.getBufferIdentifier() + | 
| Rui Ueyama | 7fdb438 | 2016-08-03 20:25:29 +0000 | [diff] [blame] | 623 | ": could not infer e_machine from bitcode target triple " + T.str()); | 
| Davide Italiano | 60976ba | 2016-06-29 06:12:39 +0000 | [diff] [blame] | 624 | } | 
|  | 625 | } | 
|  | 626 |  | 
| Rui Ueyama | 523744d | 2016-07-07 02:46:30 +0000 | [diff] [blame] | 627 | BitcodeFile::BitcodeFile(MemoryBufferRef MB) : InputFile(BitcodeKind, MB) { | 
| Rui Ueyama | 8035688 | 2016-08-03 20:33:17 +0000 | [diff] [blame] | 628 | EKind = getBitcodeELFKind(MB); | 
|  | 629 | EMachine = getBitcodeMachineKind(MB); | 
| Davide Italiano | 60976ba | 2016-06-29 06:12:39 +0000 | [diff] [blame] | 630 | } | 
| Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 631 |  | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 632 | static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { | 
|  | 633 | switch (GvVisibility) { | 
| Rui Ueyama | 68fae23 | 2016-03-07 19:06:14 +0000 | [diff] [blame] | 634 | case GlobalValue::DefaultVisibility: | 
|  | 635 | return STV_DEFAULT; | 
| Rui Ueyama | fd4fee5 | 2016-03-07 00:54:17 +0000 | [diff] [blame] | 636 | case GlobalValue::HiddenVisibility: | 
|  | 637 | return STV_HIDDEN; | 
|  | 638 | case GlobalValue::ProtectedVisibility: | 
|  | 639 | return STV_PROTECTED; | 
| Rui Ueyama | fd4fee5 | 2016-03-07 00:54:17 +0000 | [diff] [blame] | 640 | } | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 641 | llvm_unreachable("unknown visibility"); | 
| Rui Ueyama | f714955 | 2016-03-11 18:46:51 +0000 | [diff] [blame] | 642 | } | 
|  | 643 |  | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 644 | template <class ELFT> | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 645 | static Symbol *createBitcodeSymbol(const DenseSet<const Comdat *> &KeptComdats, | 
|  | 646 | const lto::InputFile::Symbol &ObjSym, | 
|  | 647 | StringSaver &Saver, BitcodeFile *F) { | 
|  | 648 | StringRef NameRef = Saver.save(ObjSym.getName()); | 
|  | 649 | uint32_t Flags = ObjSym.getFlags(); | 
| Rafael Espindola | cceb92a | 2016-08-30 20:53:26 +0000 | [diff] [blame] | 650 | uint32_t Binding = (Flags & BasicSymbolRef::SF_Weak) ? STB_WEAK : STB_GLOBAL; | 
| Davide Italiano | 9f8efff | 2016-04-22 18:26:33 +0000 | [diff] [blame] | 651 |  | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 652 | uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE; | 
|  | 653 | uint8_t Visibility = mapVisibility(ObjSym.getVisibility()); | 
|  | 654 | bool CanOmitFromDynSym = ObjSym.canBeOmittedFromSymbolTable(); | 
| Davide Italiano | 29fa6ab | 2016-08-31 12:27:47 +0000 | [diff] [blame] | 655 |  | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 656 | if (const Comdat *C = check(ObjSym.getComdat())) | 
|  | 657 | if (!KeptComdats.count(C)) | 
|  | 658 | return Symtab<ELFT>::X->addUndefined(NameRef, Binding, Visibility, Type, | 
|  | 659 | CanOmitFromDynSym, F); | 
| Rui Ueyama | f714955 | 2016-03-11 18:46:51 +0000 | [diff] [blame] | 660 |  | 
| Davide Italiano | 9f8efff | 2016-04-22 18:26:33 +0000 | [diff] [blame] | 661 | if (Flags & BasicSymbolRef::SF_Undefined) | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 662 | return Symtab<ELFT>::X->addUndefined(NameRef, Binding, Visibility, Type, | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 663 | CanOmitFromDynSym, F); | 
| Davide Italiano | 9f8efff | 2016-04-22 18:26:33 +0000 | [diff] [blame] | 664 |  | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 665 | if (Flags & BasicSymbolRef::SF_Common) | 
|  | 666 | return Symtab<ELFT>::X->addCommon(NameRef, ObjSym.getCommonSize(), | 
|  | 667 | ObjSym.getCommonAlignment(), Binding, | 
|  | 668 | Visibility, STT_OBJECT, F); | 
|  | 669 |  | 
|  | 670 | return Symtab<ELFT>::X->addBitcode(NameRef, Binding, Visibility, Type, | 
|  | 671 | CanOmitFromDynSym, F); | 
| Rafael Espindola | 9b3acf9 | 2016-03-11 16:11:47 +0000 | [diff] [blame] | 672 | } | 
|  | 673 |  | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 674 | template <class ELFT> | 
| Rafael Espindola | 4de44b7 | 2016-03-02 15:43:50 +0000 | [diff] [blame] | 675 | void BitcodeFile::parse(DenseSet<StringRef> &ComdatGroups) { | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 676 | Obj = check(lto::InputFile::create(MB)); | 
| Rafael Espindola | 4de44b7 | 2016-03-02 15:43:50 +0000 | [diff] [blame] | 677 | DenseSet<const Comdat *> KeptComdats; | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 678 | for (const auto &P : Obj->getComdatSymbolTable()) { | 
| Rafael Espindola | 4de44b7 | 2016-03-02 15:43:50 +0000 | [diff] [blame] | 679 | StringRef N = Saver.save(P.first()); | 
|  | 680 | if (ComdatGroups.insert(N).second) | 
|  | 681 | KeptComdats.insert(&P.second); | 
|  | 682 | } | 
|  | 683 |  | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 684 | for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) | 
|  | 685 | Symbols.push_back( | 
|  | 686 | createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, Saver, this)); | 
| Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 687 | } | 
|  | 688 |  | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 689 | template <template <class> class T> | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 690 | static InputFile *createELFFile(MemoryBufferRef MB) { | 
| Rui Ueyama | 57bbdaf | 2016-04-08 00:18:25 +0000 | [diff] [blame] | 691 | unsigned char Size; | 
|  | 692 | unsigned char Endian; | 
|  | 693 | std::tie(Size, Endian) = getElfArchType(MB.getBuffer()); | 
|  | 694 | if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB) | 
| George Rimar | 777f963 | 2016-03-12 08:31:34 +0000 | [diff] [blame] | 695 | fatal("invalid data encoding: " + MB.getBufferIdentifier()); | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 696 |  | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 697 | InputFile *Obj; | 
| Rui Ueyama | 5e64d3f | 2016-06-29 01:30:50 +0000 | [diff] [blame] | 698 | if (Size == ELFCLASS32 && Endian == ELFDATA2LSB) | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 699 | Obj = new T<ELF32LE>(MB); | 
| Rui Ueyama | 5e64d3f | 2016-06-29 01:30:50 +0000 | [diff] [blame] | 700 | else if (Size == ELFCLASS32 && Endian == ELFDATA2MSB) | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 701 | Obj = new T<ELF32BE>(MB); | 
| Rui Ueyama | 5e64d3f | 2016-06-29 01:30:50 +0000 | [diff] [blame] | 702 | else if (Size == ELFCLASS64 && Endian == ELFDATA2LSB) | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 703 | Obj = new T<ELF64LE>(MB); | 
| Rui Ueyama | 5e64d3f | 2016-06-29 01:30:50 +0000 | [diff] [blame] | 704 | else if (Size == ELFCLASS64 && Endian == ELFDATA2MSB) | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 705 | Obj = new T<ELF64BE>(MB); | 
| Rui Ueyama | 5e64d3f | 2016-06-29 01:30:50 +0000 | [diff] [blame] | 706 | else | 
|  | 707 | fatal("invalid file class: " + MB.getBufferIdentifier()); | 
|  | 708 |  | 
|  | 709 | if (!Config->FirstElf) | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 710 | Config->FirstElf = Obj; | 
| Rui Ueyama | 5e64d3f | 2016-06-29 01:30:50 +0000 | [diff] [blame] | 711 | return Obj; | 
| Rui Ueyama | c4b6506 | 2015-10-12 15:31:09 +0000 | [diff] [blame] | 712 | } | 
|  | 713 |  | 
| Rui Ueyama | e364d1f | 2016-09-29 23:04:50 +0000 | [diff] [blame] | 714 | // Wraps a binary blob with an ELF header and footer | 
|  | 715 | // so that we can link it as a regular ELF file. | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 716 | template <class ELFT> InputFile *BinaryFile::createELF() { | 
| Rui Ueyama | e364d1f | 2016-09-29 23:04:50 +0000 | [diff] [blame] | 717 | // Fill the ELF file header. | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 718 | ELFCreator<ELFT> ELF(ET_REL, Config->EMachine); | 
|  | 719 | auto DataSec = ELF.addSection(".data"); | 
|  | 720 | DataSec.Header->sh_flags = SHF_ALLOC; | 
|  | 721 | DataSec.Header->sh_size = MB.getBufferSize(); | 
|  | 722 | DataSec.Header->sh_type = SHT_PROGBITS; | 
|  | 723 | DataSec.Header->sh_addralign = 8; | 
|  | 724 |  | 
| Rui Ueyama | e364d1f | 2016-09-29 23:04:50 +0000 | [diff] [blame] | 725 | // Replace non-alphanumeric characters with '_'. | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 726 | std::string Filepath = MB.getBufferIdentifier(); | 
|  | 727 | std::transform(Filepath.begin(), Filepath.end(), Filepath.begin(), | 
|  | 728 | [](char C) { return isalnum(C) ? C : '_'; }); | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 729 |  | 
| Rui Ueyama | e364d1f | 2016-09-29 23:04:50 +0000 | [diff] [blame] | 730 | // Add _start, _end and _size symbols. | 
|  | 731 | std::string StartSym = "_binary_" + Filepath + "_start"; | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 732 | auto SSym = ELF.addSymbol(StartSym); | 
|  | 733 | SSym.Sym->setBindingAndType(STB_GLOBAL, STT_OBJECT); | 
|  | 734 | SSym.Sym->st_shndx = DataSec.Index; | 
|  | 735 |  | 
| Rui Ueyama | e364d1f | 2016-09-29 23:04:50 +0000 | [diff] [blame] | 736 | std::string EndSym = "_binary_" + Filepath + "_end"; | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 737 | auto ESym = ELF.addSymbol(EndSym); | 
|  | 738 | ESym.Sym->setBindingAndType(STB_GLOBAL, STT_OBJECT); | 
|  | 739 | ESym.Sym->st_shndx = DataSec.Index; | 
|  | 740 | ESym.Sym->st_value = MB.getBufferSize(); | 
|  | 741 |  | 
| Rui Ueyama | e364d1f | 2016-09-29 23:04:50 +0000 | [diff] [blame] | 742 | std::string SizeSym = "_binary_" + Filepath + "_size"; | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 743 | auto SZSym = ELF.addSymbol(SizeSym); | 
|  | 744 | SZSym.Sym->setBindingAndType(STB_GLOBAL, STT_OBJECT); | 
|  | 745 | SZSym.Sym->st_shndx = SHN_ABS; | 
|  | 746 | SZSym.Sym->st_value = MB.getBufferSize(); | 
|  | 747 |  | 
| Rui Ueyama | e364d1f | 2016-09-29 23:04:50 +0000 | [diff] [blame] | 748 | // Fix the ELF file layout and write it down to ELFData uint8_t vector. | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 749 | std::size_t Size = ELF.layout(); | 
|  | 750 | ELFData.resize(Size); | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 751 | ELF.write(ELFData.data()); | 
|  | 752 |  | 
| Rui Ueyama | e364d1f | 2016-09-29 23:04:50 +0000 | [diff] [blame] | 753 | // Fill .data section with actual data. | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 754 | std::copy(MB.getBufferStart(), MB.getBufferEnd(), | 
|  | 755 | ELFData.data() + DataSec.Header->sh_offset); | 
|  | 756 |  | 
|  | 757 | return createELFFile<ObjectFile>(MemoryBufferRef( | 
|  | 758 | StringRef((char *)ELFData.data(), Size), MB.getBufferIdentifier())); | 
|  | 759 | } | 
|  | 760 |  | 
| Rui Ueyama | 4655ea3 | 2016-04-08 00:14:55 +0000 | [diff] [blame] | 761 | static bool isBitcode(MemoryBufferRef MB) { | 
|  | 762 | using namespace sys::fs; | 
|  | 763 | return identify_magic(MB.getBuffer()) == file_magic::bitcode; | 
|  | 764 | } | 
|  | 765 |  | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 766 | InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName) { | 
|  | 767 | InputFile *F = | 
|  | 768 | isBitcode(MB) ? new BitcodeFile(MB) : createELFFile<ObjectFile>(MB); | 
| Rui Ueyama | 71c066d | 2016-02-02 08:22:41 +0000 | [diff] [blame] | 769 | F->ArchiveName = ArchiveName; | 
|  | 770 | return F; | 
| Rui Ueyama | 533c030 | 2016-01-06 00:09:43 +0000 | [diff] [blame] | 771 | } | 
|  | 772 |  | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 773 | InputFile *elf::createSharedFile(MemoryBufferRef MB) { | 
| Rui Ueyama | 533c030 | 2016-01-06 00:09:43 +0000 | [diff] [blame] | 774 | return createELFFile<SharedFile>(MB); | 
|  | 775 | } | 
|  | 776 |  | 
| Rafael Espindola | 65c65ce | 2016-06-14 21:56:36 +0000 | [diff] [blame] | 777 | MemoryBufferRef LazyObjectFile::getBuffer() { | 
|  | 778 | if (Seen) | 
|  | 779 | return MemoryBufferRef(); | 
|  | 780 | Seen = true; | 
|  | 781 | return MB; | 
|  | 782 | } | 
|  | 783 |  | 
| George Rimar | 10874f7 | 2016-10-03 11:13:55 +0000 | [diff] [blame^] | 784 | template <class ELFT> void LazyObjectFile::parse() { | 
| Rui Ueyama | f8baa66 | 2016-04-07 19:24:51 +0000 | [diff] [blame] | 785 | for (StringRef Sym : getSymbols()) | 
| Rafael Espindola | 65c65ce | 2016-06-14 21:56:36 +0000 | [diff] [blame] | 786 | Symtab<ELFT>::X->addLazyObject(Sym, *this); | 
| Rui Ueyama | f8baa66 | 2016-04-07 19:24:51 +0000 | [diff] [blame] | 787 | } | 
|  | 788 |  | 
|  | 789 | template <class ELFT> std::vector<StringRef> LazyObjectFile::getElfSymbols() { | 
|  | 790 | typedef typename ELFT::Shdr Elf_Shdr; | 
|  | 791 | typedef typename ELFT::Sym Elf_Sym; | 
|  | 792 | typedef typename ELFT::SymRange Elf_Sym_Range; | 
|  | 793 |  | 
|  | 794 | const ELFFile<ELFT> Obj = createELFObj<ELFT>(this->MB); | 
|  | 795 | for (const Elf_Shdr &Sec : Obj.sections()) { | 
|  | 796 | if (Sec.sh_type != SHT_SYMTAB) | 
|  | 797 | continue; | 
|  | 798 | Elf_Sym_Range Syms = Obj.symbols(&Sec); | 
|  | 799 | uint32_t FirstNonLocal = Sec.sh_info; | 
|  | 800 | StringRef StringTable = check(Obj.getStringTableForSymtab(Sec)); | 
|  | 801 | std::vector<StringRef> V; | 
|  | 802 | for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal)) | 
| Rui Ueyama | 1f49289 | 2016-04-08 20:49:31 +0000 | [diff] [blame] | 803 | if (Sym.st_shndx != SHN_UNDEF) | 
|  | 804 | V.push_back(check(Sym.getName(StringTable))); | 
| Rui Ueyama | f8baa66 | 2016-04-07 19:24:51 +0000 | [diff] [blame] | 805 | return V; | 
|  | 806 | } | 
|  | 807 | return {}; | 
|  | 808 | } | 
|  | 809 |  | 
|  | 810 | std::vector<StringRef> LazyObjectFile::getBitcodeSymbols() { | 
| Davide Italiano | 786d8e3 | 2016-09-29 00:40:08 +0000 | [diff] [blame] | 811 | std::unique_ptr<lto::InputFile> Obj = check(lto::InputFile::create(this->MB)); | 
| Rui Ueyama | d72dd1f | 2016-09-29 00:58:10 +0000 | [diff] [blame] | 812 | std::vector<StringRef> V; | 
|  | 813 | for (const lto::InputFile::Symbol &Sym : Obj->symbols()) | 
|  | 814 | if (!(Sym.getFlags() & BasicSymbolRef::SF_Undefined)) | 
|  | 815 | V.push_back(Saver.save(Sym.getName())); | 
| Rui Ueyama | f8baa66 | 2016-04-07 19:24:51 +0000 | [diff] [blame] | 816 | return V; | 
|  | 817 | } | 
|  | 818 |  | 
| Rui Ueyama | 1f49289 | 2016-04-08 20:49:31 +0000 | [diff] [blame] | 819 | // Returns a vector of globally-visible defined symbol names. | 
| Rui Ueyama | f8baa66 | 2016-04-07 19:24:51 +0000 | [diff] [blame] | 820 | std::vector<StringRef> LazyObjectFile::getSymbols() { | 
| Rui Ueyama | 4655ea3 | 2016-04-08 00:14:55 +0000 | [diff] [blame] | 821 | if (isBitcode(this->MB)) | 
| Rui Ueyama | f8baa66 | 2016-04-07 19:24:51 +0000 | [diff] [blame] | 822 | return getBitcodeSymbols(); | 
|  | 823 |  | 
| Rui Ueyama | 4655ea3 | 2016-04-08 00:14:55 +0000 | [diff] [blame] | 824 | unsigned char Size; | 
|  | 825 | unsigned char Endian; | 
|  | 826 | std::tie(Size, Endian) = getElfArchType(this->MB.getBuffer()); | 
|  | 827 | if (Size == ELFCLASS32) { | 
|  | 828 | if (Endian == ELFDATA2LSB) | 
| Rui Ueyama | f8baa66 | 2016-04-07 19:24:51 +0000 | [diff] [blame] | 829 | return getElfSymbols<ELF32LE>(); | 
|  | 830 | return getElfSymbols<ELF32BE>(); | 
|  | 831 | } | 
| Rui Ueyama | 4655ea3 | 2016-04-08 00:14:55 +0000 | [diff] [blame] | 832 | if (Endian == ELFDATA2LSB) | 
| Rui Ueyama | f8baa66 | 2016-04-07 19:24:51 +0000 | [diff] [blame] | 833 | return getElfSymbols<ELF64LE>(); | 
|  | 834 | return getElfSymbols<ELF64BE>(); | 
|  | 835 | } | 
|  | 836 |  | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 837 | template void ArchiveFile::parse<ELF32LE>(); | 
|  | 838 | template void ArchiveFile::parse<ELF32BE>(); | 
|  | 839 | template void ArchiveFile::parse<ELF64LE>(); | 
|  | 840 | template void ArchiveFile::parse<ELF64BE>(); | 
|  | 841 |  | 
| Rui Ueyama | 818bb2f | 2016-07-16 18:55:47 +0000 | [diff] [blame] | 842 | template void BitcodeFile::parse<ELF32LE>(DenseSet<StringRef> &); | 
|  | 843 | template void BitcodeFile::parse<ELF32BE>(DenseSet<StringRef> &); | 
|  | 844 | template void BitcodeFile::parse<ELF64LE>(DenseSet<StringRef> &); | 
|  | 845 | template void BitcodeFile::parse<ELF64BE>(DenseSet<StringRef> &); | 
| Peter Collingbourne | 4f95270 | 2016-05-01 04:55:03 +0000 | [diff] [blame] | 846 |  | 
|  | 847 | template void LazyObjectFile::parse<ELF32LE>(); | 
|  | 848 | template void LazyObjectFile::parse<ELF32BE>(); | 
|  | 849 | template void LazyObjectFile::parse<ELF64LE>(); | 
|  | 850 | template void LazyObjectFile::parse<ELF64BE>(); | 
|  | 851 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 852 | template class elf::ELFFileBase<ELF32LE>; | 
|  | 853 | template class elf::ELFFileBase<ELF32BE>; | 
|  | 854 | template class elf::ELFFileBase<ELF64LE>; | 
|  | 855 | template class elf::ELFFileBase<ELF64BE>; | 
| Davide Italiano | 6d328d3 | 2015-09-16 20:45:57 +0000 | [diff] [blame] | 856 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 857 | template class elf::ObjectFile<ELF32LE>; | 
|  | 858 | template class elf::ObjectFile<ELF32BE>; | 
|  | 859 | template class elf::ObjectFile<ELF64LE>; | 
|  | 860 | template class elf::ObjectFile<ELF64BE>; | 
| Rafael Espindola | f98d6d8 | 2015-09-03 20:03:54 +0000 | [diff] [blame] | 861 |  | 
| Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame] | 862 | template class elf::SharedFile<ELF32LE>; | 
|  | 863 | template class elf::SharedFile<ELF32BE>; | 
|  | 864 | template class elf::SharedFile<ELF64LE>; | 
|  | 865 | template class elf::SharedFile<ELF64BE>; | 
| Michael J. Spencer | a9424f3 | 2016-09-09 22:08:04 +0000 | [diff] [blame] | 866 |  | 
| Rui Ueyama | 38dbd3e | 2016-09-14 00:05:51 +0000 | [diff] [blame] | 867 | template InputFile *BinaryFile::createELF<ELF32LE>(); | 
|  | 868 | template InputFile *BinaryFile::createELF<ELF32BE>(); | 
|  | 869 | template InputFile *BinaryFile::createELF<ELF64LE>(); | 
|  | 870 | template InputFile *BinaryFile::createELF<ELF64BE>(); |