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