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 "Chunks.h" 11 #include "Error.h" 12 #include "InputFiles.h" 13 #include "Writer.h" 14 #include "llvm/ADT/STLExtras.h" 15 #include "llvm/LTO/LTOModule.h" 16 #include "llvm/Object/COFF.h" 17 #include "llvm/Support/COFF.h" 18 #include "llvm/Support/Debug.h" 19 #include "llvm/Support/Endian.h" 20 #include "llvm/Support/raw_ostream.h" 21 22 using namespace llvm::object; 23 using namespace llvm::support::endian; 24 using llvm::COFF::ImportHeader; 25 using llvm::COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 26 using llvm::RoundUpToAlignment; 27 using llvm::sys::fs::identify_magic; 28 using llvm::sys::fs::file_magic; 29 30 namespace lld { 31 namespace coff { 32 33 // Returns the last element of a path, which is supposed to be a filename. 34 static StringRef getBasename(StringRef Path) { 35 size_t Pos = Path.rfind('\\'); 36 if (Pos == StringRef::npos) 37 return Path; 38 return Path.substr(Pos + 1); 39 } 40 41 // Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)". 42 std::string InputFile::getShortName() { 43 if (ParentName == "") 44 return getName().lower(); 45 std::string Res = (getBasename(ParentName) + "(" + 46 getBasename(getName()) + ")").str(); 47 return StringRef(Res).lower(); 48 } 49 50 std::error_code ArchiveFile::parse() { 51 // Parse a MemoryBufferRef as an archive file. 52 auto ArchiveOrErr = Archive::create(MB); 53 if (auto EC = ArchiveOrErr.getError()) 54 return EC; 55 File = std::move(ArchiveOrErr.get()); 56 57 // Allocate a buffer for Lazy objects. 58 size_t BufSize = File->getNumberOfSymbols() * sizeof(Lazy); 59 Lazy *Buf = (Lazy *)Alloc.Allocate(BufSize, llvm::alignOf<Lazy>()); 60 61 // Read the symbol table to construct Lazy objects. 62 uint32_t I = 0; 63 for (const Archive::Symbol &Sym : File->symbols()) { 64 // Skip special symbol exists in import library files. 65 if (Sym.getName() == "__NULL_IMPORT_DESCRIPTOR") 66 continue; 67 SymbolBodies.push_back(new (&Buf[I++]) Lazy(this, Sym)); 68 } 69 return std::error_code(); 70 } 71 72 // Returns a buffer pointing to a member file containing a given symbol. 73 ErrorOr<MemoryBufferRef> ArchiveFile::getMember(const Archive::Symbol *Sym) { 74 auto ItOrErr = Sym->getMember(); 75 if (auto EC = ItOrErr.getError()) 76 return EC; 77 Archive::child_iterator It = ItOrErr.get(); 78 79 // Return an empty buffer if we have already returned the same buffer. 80 const char *StartAddr = It->getBuffer().data(); 81 auto Pair = Seen.insert(StartAddr); 82 if (!Pair.second) 83 return MemoryBufferRef(); 84 return It->getMemoryBufferRef(); 85 } 86 87 std::error_code ObjectFile::parse() { 88 // Parse a memory buffer as a COFF file. 89 auto BinOrErr = createBinary(MB); 90 if (auto EC = BinOrErr.getError()) 91 return EC; 92 std::unique_ptr<Binary> Bin = std::move(BinOrErr.get()); 93 94 if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) { 95 Bin.release(); 96 COFFObj.reset(Obj); 97 } else { 98 llvm::errs() << getName() << " is not a COFF file.\n"; 99 return make_error_code(LLDError::InvalidFile); 100 } 101 102 // Read section and symbol tables. 103 if (auto EC = initializeChunks()) 104 return EC; 105 return initializeSymbols(); 106 } 107 108 SymbolBody *ObjectFile::getSymbolBody(uint32_t SymbolIndex) { 109 return SparseSymbolBodies[SymbolIndex]->getReplacement(); 110 } 111 112 std::error_code ObjectFile::initializeChunks() { 113 uint32_t NumSections = COFFObj->getNumberOfSections(); 114 Chunks.reserve(NumSections); 115 SparseChunks.resize(NumSections + 1); 116 for (uint32_t I = 1; I < NumSections + 1; ++I) { 117 const coff_section *Sec; 118 StringRef Name; 119 if (auto EC = COFFObj->getSection(I, Sec)) { 120 llvm::errs() << "getSection failed: " << Name << ": " 121 << EC.message() << "\n"; 122 return make_error_code(LLDError::BrokenFile); 123 } 124 if (auto EC = COFFObj->getSectionName(Sec, Name)) { 125 llvm::errs() << "getSectionName failed: " << Name << ": " 126 << EC.message() << "\n"; 127 return make_error_code(LLDError::BrokenFile); 128 } 129 if (Name == ".drectve") { 130 ArrayRef<uint8_t> Data; 131 COFFObj->getSectionContents(Sec, Data); 132 Directives = StringRef((const char *)Data.data(), Data.size()).trim(); 133 continue; 134 } 135 if (Name.startswith(".debug")) 136 continue; 137 if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) 138 continue; 139 auto *C = new (Alloc) SectionChunk(this, Sec, I); 140 Chunks.push_back(C); 141 SparseChunks[I] = C; 142 } 143 return std::error_code(); 144 } 145 146 std::error_code ObjectFile::initializeSymbols() { 147 uint32_t NumSymbols = COFFObj->getNumberOfSymbols(); 148 SymbolBodies.reserve(NumSymbols); 149 SparseSymbolBodies.resize(NumSymbols); 150 int32_t LastSectionNumber = 0; 151 for (uint32_t I = 0; I < NumSymbols; ++I) { 152 // Get a COFFSymbolRef object. 153 auto SymOrErr = COFFObj->getSymbol(I); 154 if (auto EC = SymOrErr.getError()) { 155 llvm::errs() << "broken object file: " << getName() << ": " 156 << EC.message() << "\n"; 157 return make_error_code(LLDError::BrokenFile); 158 } 159 COFFSymbolRef Sym = SymOrErr.get(); 160 161 const void *AuxP = nullptr; 162 if (Sym.getNumberOfAuxSymbols()) 163 AuxP = COFFObj->getSymbol(I + 1)->getRawPtr(); 164 bool IsFirst = (LastSectionNumber != Sym.getSectionNumber()); 165 166 SymbolBody *Body = createSymbolBody(Sym, AuxP, IsFirst); 167 if (Body) { 168 SymbolBodies.push_back(Body); 169 SparseSymbolBodies[I] = Body; 170 } 171 I += Sym.getNumberOfAuxSymbols(); 172 LastSectionNumber = Sym.getSectionNumber(); 173 } 174 return std::error_code(); 175 } 176 177 SymbolBody *ObjectFile::createSymbolBody(COFFSymbolRef Sym, const void *AuxP, 178 bool IsFirst) { 179 StringRef Name; 180 if (Sym.isUndefined()) { 181 COFFObj->getSymbolName(Sym, Name); 182 return new (Alloc) Undefined(Name); 183 } 184 if (Sym.isCommon()) { 185 Chunk *C = new (Alloc) CommonChunk(Sym); 186 Chunks.push_back(C); 187 return new (Alloc) DefinedRegular(COFFObj.get(), Sym, C); 188 } 189 if (Sym.isAbsolute()) { 190 COFFObj->getSymbolName(Sym, Name); 191 // Skip special symbols. 192 if (Name == "@comp.id" || Name == "@feat.00") 193 return nullptr; 194 return new (Alloc) DefinedAbsolute(Name, Sym.getValue()); 195 } 196 // TODO: Handle IMAGE_WEAK_EXTERN_SEARCH_ALIAS 197 if (Sym.isWeakExternal()) { 198 COFFObj->getSymbolName(Sym, Name); 199 auto *Aux = (const coff_aux_weak_external *)AuxP; 200 return new (Alloc) Undefined(Name, &SparseSymbolBodies[Aux->TagIndex]); 201 } 202 // Handle associative sections 203 if (IsFirst && AuxP) { 204 if (Chunk *C = SparseChunks[Sym.getSectionNumber()]) { 205 auto *Aux = reinterpret_cast<const coff_aux_section_definition *>(AuxP); 206 if (Aux->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) { 207 auto *Parent = 208 (SectionChunk *)(SparseChunks[Aux->getNumber(Sym.isBigObj())]); 209 if (Parent) 210 Parent->addAssociative((SectionChunk *)C); 211 } 212 } 213 } 214 if (Chunk *C = SparseChunks[Sym.getSectionNumber()]) 215 return new (Alloc) DefinedRegular(COFFObj.get(), Sym, C); 216 return nullptr; 217 } 218 219 std::error_code ImportFile::parse() { 220 const char *Buf = MB.getBufferStart(); 221 const char *End = MB.getBufferEnd(); 222 const auto *Hdr = reinterpret_cast<const coff_import_header *>(Buf); 223 224 // Check if the total size is valid. 225 if ((size_t)(End - Buf) != (sizeof(*Hdr) + Hdr->SizeOfData)) { 226 llvm::errs() << "broken import library\n"; 227 return make_error_code(LLDError::BrokenFile); 228 } 229 230 // Read names and create an __imp_ symbol. 231 StringRef Name = StringAlloc.save(StringRef(Buf + sizeof(*Hdr))); 232 StringRef ImpName = StringAlloc.save(Twine("__imp_") + Name); 233 StringRef DLLName(Buf + sizeof(coff_import_header) + Name.size() + 1); 234 StringRef ExternalName = Name; 235 if (Hdr->getNameType() == llvm::COFF::IMPORT_ORDINAL) 236 ExternalName = ""; 237 auto *ImpSym = new (Alloc) DefinedImportData(DLLName, ImpName, ExternalName, 238 Hdr); 239 SymbolBodies.push_back(ImpSym); 240 241 // If type is function, we need to create a thunk which jump to an 242 // address pointed by the __imp_ symbol. (This allows you to call 243 // DLL functions just like regular non-DLL functions.) 244 if (Hdr->getType() == llvm::COFF::IMPORT_CODE) 245 SymbolBodies.push_back(new (Alloc) DefinedImportThunk(Name, ImpSym)); 246 return std::error_code(); 247 } 248 249 std::error_code BitcodeFile::parse() { 250 std::string Err; 251 M.reset(LTOModule::createFromBuffer(MB.getBufferStart(), 252 MB.getBufferSize(), 253 llvm::TargetOptions(), Err)); 254 if (!Err.empty()) { 255 llvm::errs() << Err << '\n'; 256 return make_error_code(LLDError::BrokenFile); 257 } 258 259 for (unsigned I = 0, E = M->getSymbolCount(); I != E; ++I) { 260 lto_symbol_attributes Attrs = M->getSymbolAttributes(I); 261 if ((Attrs & LTO_SYMBOL_SCOPE_MASK) == LTO_SYMBOL_SCOPE_INTERNAL) 262 continue; 263 264 StringRef SymName = M->getSymbolName(I); 265 int SymbolDef = Attrs & LTO_SYMBOL_DEFINITION_MASK; 266 if (SymbolDef == LTO_SYMBOL_DEFINITION_UNDEFINED) { 267 SymbolBodies.push_back(new (Alloc) Undefined(SymName)); 268 } else { 269 bool Replaceable = (SymbolDef == LTO_SYMBOL_DEFINITION_TENTATIVE || 270 (Attrs & LTO_SYMBOL_COMDAT)); 271 SymbolBodies.push_back(new (Alloc) DefinedBitcode(SymName, Replaceable)); 272 } 273 } 274 275 // Extract any linker directives from the bitcode file, which are represented 276 // as module flags with the key "Linker Options". 277 llvm::SmallVector<llvm::Module::ModuleFlagEntry, 8> Flags; 278 M->getModule().getModuleFlagsMetadata(Flags); 279 for (auto &&Flag : Flags) { 280 if (Flag.Key->getString() != "Linker Options") 281 continue; 282 283 for (llvm::Metadata *Op : cast<llvm::MDNode>(Flag.Val)->operands()) { 284 for (llvm::Metadata *InnerOp : cast<llvm::MDNode>(Op)->operands()) { 285 Directives += " "; 286 Directives += cast<llvm::MDString>(InnerOp)->getString(); 287 } 288 } 289 } 290 291 return std::error_code(); 292 } 293 294 } // namespace coff 295 } // namespace lld 296