//===- InputFiles.cpp -----------------------------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "InputFiles.h" #include "Driver.h" #include "Error.h" #include "InputSection.h" #include "SymbolTable.h" #include "Symbols.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; using namespace llvm::ELF; using namespace llvm::object; using namespace llvm::sys::fs; using namespace lld; using namespace lld::elf; // Returns "(internal)", "foo.a(bar.o)" or "baz.o". std::string elf::getFilename(const InputFile *F) { if (!F) return "(internal)"; if (!F->ArchiveName.empty()) return (F->ArchiveName + "(" + F->getName() + ")").str(); return F->getName(); } template static ELFFile createELFObj(MemoryBufferRef MB) { std::error_code EC; ELFFile F(MB.getBuffer(), EC); if (EC) error(EC, "failed to read " + MB.getBufferIdentifier()); return F; } template static ELFKind getELFKind() { if (ELFT::TargetEndianness == support::little) return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind; return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind; } template ELFFileBase::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB), ELFObj(createELFObj(MB)) { EKind = getELFKind(); EMachine = ELFObj.getHeader()->e_machine; } template typename ELFT::SymRange ELFFileBase::getElfSymbols(bool OnlyGlobals) { if (!Symtab) return Elf_Sym_Range(nullptr, nullptr); Elf_Sym_Range Syms = ELFObj.symbols(Symtab); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); uint32_t FirstNonLocal = Symtab->sh_info; if (FirstNonLocal > NumSymbols) fatal(getFilename(this) + ": invalid sh_info in symbol table"); if (OnlyGlobals) return makeArrayRef(Syms.begin() + FirstNonLocal, Syms.end()); return makeArrayRef(Syms.begin(), Syms.end()); } template uint32_t ELFFileBase::getSectionIndex(const Elf_Sym &Sym) const { uint32_t I = Sym.st_shndx; if (I == ELF::SHN_XINDEX) return ELFObj.getExtendedSymbolTableIndex(&Sym, Symtab, SymtabSHNDX); if (I >= ELF::SHN_LORESERVE) return 0; return I; } template void ELFFileBase::initStringTable() { if (!Symtab) return; StringTable = check(ELFObj.getStringTableForSymtab(*Symtab)); } template elf::ObjectFile::ObjectFile(MemoryBufferRef M) : ELFFileBase(Base::ObjectKind, M) {} template ArrayRef elf::ObjectFile::getNonLocalSymbols() { if (!this->Symtab) return this->SymbolBodies; uint32_t FirstNonLocal = this->Symtab->sh_info; return makeArrayRef(this->SymbolBodies).slice(FirstNonLocal); } template ArrayRef elf::ObjectFile::getLocalSymbols() { if (!this->Symtab) return this->SymbolBodies; uint32_t FirstNonLocal = this->Symtab->sh_info; return makeArrayRef(this->SymbolBodies).slice(1, FirstNonLocal - 1); } template ArrayRef elf::ObjectFile::getSymbols() { if (!this->Symtab) return this->SymbolBodies; return makeArrayRef(this->SymbolBodies).slice(1); } template uint32_t elf::ObjectFile::getMipsGp0() const { if (ELFT::Is64Bits && MipsOptions && MipsOptions->Reginfo) return MipsOptions->Reginfo->ri_gp_value; if (!ELFT::Is64Bits && MipsReginfo && MipsReginfo->Reginfo) return MipsReginfo->Reginfo->ri_gp_value; return 0; } template void elf::ObjectFile::parse(DenseSet &ComdatGroups) { // Read section and symbol tables. initializeSections(ComdatGroups); initializeSymbols(); } // Sections with SHT_GROUP and comdat bits define comdat section groups. // They are identified and deduplicated by group name. This function // returns a group name. template StringRef elf::ObjectFile::getShtGroupSignature(const Elf_Shdr &Sec) { const ELFFile &Obj = this->ELFObj; const Elf_Shdr *Symtab = check(Obj.getSection(Sec.sh_link)); const Elf_Sym *Sym = Obj.getSymbol(Symtab, Sec.sh_info); StringRef Strtab = check(Obj.getStringTableForSymtab(*Symtab)); return check(Sym->getName(Strtab)); } template ArrayRef::Elf_Word> elf::ObjectFile::getShtGroupEntries(const Elf_Shdr &Sec) { const ELFFile &Obj = this->ELFObj; ArrayRef Entries = check(Obj.template getSectionContentsAsArray(&Sec)); if (Entries.empty() || Entries[0] != GRP_COMDAT) fatal(getFilename(this) + ": unsupported SHT_GROUP format"); return Entries.slice(1); } template bool elf::ObjectFile::shouldMerge(const Elf_Shdr &Sec) { // We don't merge sections if -O0 (default is -O1). This makes sometimes // the linker significantly faster, although the output will be bigger. if (Config->Optimize == 0) return false; uintX_t Flags = Sec.sh_flags; if (!(Flags & SHF_MERGE)) return false; if (Flags & SHF_WRITE) fatal(getFilename(this) + ": writable SHF_MERGE section is not supported"); uintX_t EntSize = Sec.sh_entsize; if (!EntSize || Sec.sh_size % EntSize) fatal(getFilename(this) + ": SHF_MERGE section size must be a multiple of sh_entsize"); // Don't try to merge if the alignment is larger than the sh_entsize and this // is not SHF_STRINGS. // // Since this is not a SHF_STRINGS, we would need to pad after every entity. // It would be equivalent for the producer of the .o to just set a larger // sh_entsize. if (Flags & SHF_STRINGS) return true; return Sec.sh_addralign <= EntSize; } template void elf::ObjectFile::initializeSections( DenseSet &ComdatGroups) { uint64_t Size = this->ELFObj.getNumSections(); Sections.resize(Size); unsigned I = -1; const ELFFile &Obj = this->ELFObj; for (const Elf_Shdr &Sec : Obj.sections()) { ++I; if (Sections[I] == &InputSection::Discarded) continue; switch (Sec.sh_type) { case SHT_GROUP: Sections[I] = &InputSection::Discarded; if (ComdatGroups.insert(getShtGroupSignature(Sec)).second) continue; for (uint32_t SecIndex : getShtGroupEntries(Sec)) { if (SecIndex >= Size) fatal(getFilename(this) + ": invalid section index in group: " + Twine(SecIndex)); Sections[SecIndex] = &InputSection::Discarded; } break; case SHT_SYMTAB: this->Symtab = &Sec; break; case SHT_SYMTAB_SHNDX: this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec)); break; case SHT_STRTAB: case SHT_NULL: break; case SHT_RELA: case SHT_REL: { // This section contains relocation information. // If -r is given, we do not interpret or apply relocation // but just copy relocation sections to output. if (Config->Relocatable) { Sections[I] = new (IAlloc.Allocate()) InputSection(this, &Sec); break; } // Find the relocation target section and associate this // section with it. InputSectionBase *Target = getRelocTarget(Sec); if (!Target) break; if (auto *S = dyn_cast>(Target)) { S->RelocSections.push_back(&Sec); break; } if (auto *S = dyn_cast>(Target)) { if (S->RelocSection) fatal( getFilename(this) + ": multiple relocation sections to .eh_frame are not supported"); S->RelocSection = &Sec; break; } fatal(getFilename(this) + ": relocations pointing to SHF_MERGE are not supported"); } case SHT_ARM_ATTRIBUTES: // FIXME: ARM meta-data section. At present attributes are ignored, // they can be used to reason about object compatibility. Sections[I] = &InputSection::Discarded; break; default: Sections[I] = createInputSection(Sec); } } } template InputSectionBase * elf::ObjectFile::getRelocTarget(const Elf_Shdr &Sec) { uint32_t Idx = Sec.sh_info; if (Idx >= Sections.size()) fatal(getFilename(this) + ": invalid relocated section index: " + Twine(Idx)); InputSectionBase *Target = Sections[Idx]; // Strictly speaking, a relocation section must be included in the // group of the section it relocates. However, LLVM 3.3 and earlier // would fail to do so, so we gracefully handle that case. if (Target == &InputSection::Discarded) return nullptr; if (!Target) fatal(getFilename(this) + ": unsupported relocation reference"); return Target; } template InputSectionBase * elf::ObjectFile::createInputSection(const Elf_Shdr &Sec) { StringRef Name = check(this->ELFObj.getSectionName(&Sec)); // .note.GNU-stack is a marker section to control the presence of // PT_GNU_STACK segment in outputs. Since the presence of the segment // is controlled only by the command line option (-z execstack) in LLD, // .note.GNU-stack is ignored. if (Name == ".note.GNU-stack") return &InputSection::Discarded; if (Name == ".note.GNU-split-stack") { error("objects using splitstacks are not supported"); return &InputSection::Discarded; } if (Config->StripDebug && Name.startswith(".debug")) return &InputSection::Discarded; // A MIPS object file has a special sections that contain register // usage info, which need to be handled by the linker specially. if (Config->EMachine == EM_MIPS) { if (Name == ".reginfo") { MipsReginfo.reset(new MipsReginfoInputSection(this, &Sec)); return MipsReginfo.get(); } if (Name == ".MIPS.options") { MipsOptions.reset(new MipsOptionsInputSection(this, &Sec)); return MipsOptions.get(); } } // The linker merges EH (exception handling) frames and creates a // .eh_frame_hdr section for runtime. So we handle them with a special // class. For relocatable outputs, they are just passed through. if (Name == ".eh_frame" && !Config->Relocatable) return new (EHAlloc.Allocate()) EhInputSection(this, &Sec); if (shouldMerge(Sec)) return new (MAlloc.Allocate()) MergeInputSection(this, &Sec); return new (IAlloc.Allocate()) InputSection(this, &Sec); } template void elf::ObjectFile::initializeSymbols() { this->initStringTable(); Elf_Sym_Range Syms = this->getElfSymbols(false); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); SymbolBodies.reserve(NumSymbols); for (const Elf_Sym &Sym : Syms) SymbolBodies.push_back(createSymbolBody(&Sym)); } template InputSectionBase * elf::ObjectFile::getSection(const Elf_Sym &Sym) const { uint32_t Index = this->getSectionIndex(Sym); if (Index == 0) return nullptr; if (Index >= Sections.size() || !Sections[Index]) fatal(getFilename(this) + ": invalid section index: " + Twine(Index)); InputSectionBase *S = Sections[Index]; if (S == &InputSectionBase::Discarded) return S; return S->Repl; } template SymbolBody *elf::ObjectFile::createSymbolBody(const Elf_Sym *Sym) { int Binding = Sym->getBinding(); InputSectionBase *Sec = getSection(*Sym); if (Binding == STB_LOCAL) { if (Sym->st_shndx == SHN_UNDEF) return new (this->Alloc) Undefined(Sym->st_name, Sym->st_other, Sym->getType(), this); return new (this->Alloc) DefinedRegular(*Sym, Sec); } StringRef Name = check(Sym->getName(this->StringTable)); switch (Sym->st_shndx) { case SHN_UNDEF: return elf::Symtab::X ->addUndefined(Name, Binding, Sym->st_other, Sym->getType(), /*CanOmitFromDynSym*/ false, this) ->body(); case SHN_COMMON: return elf::Symtab::X ->addCommon(Name, Sym->st_size, Sym->st_value, Binding, Sym->st_other, Sym->getType(), this) ->body(); } switch (Binding) { default: fatal(getFilename(this) + ": unexpected binding: " + Twine(Binding)); case STB_GLOBAL: case STB_WEAK: case STB_GNU_UNIQUE: if (Sec == &InputSection::Discarded) return elf::Symtab::X ->addUndefined(Name, Binding, Sym->st_other, Sym->getType(), /*CanOmitFromDynSym*/ false, this) ->body(); return elf::Symtab::X->addRegular(Name, *Sym, Sec)->body(); } } template void ArchiveFile::parse() { File = check(Archive::create(MB), "failed to parse archive"); // Read the symbol table to construct Lazy objects. for (const Archive::Symbol &Sym : File->symbols()) Symtab::X->addLazyArchive(this, Sym); } // Returns a buffer pointing to a member file containing a given symbol. MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) { Archive::Child C = check(Sym->getMember(), "could not get the member for symbol " + Sym->getName()); if (!Seen.insert(C.getChildOffset()).second) return MemoryBufferRef(); MemoryBufferRef Ret = check(C.getMemoryBufferRef(), "could not get the buffer for the member defining symbol " + Sym->getName()); if (C.getParent()->isThin() && Driver->Cpio) Driver->Cpio->append(relativeToRoot(check(C.getFullName())), Ret.getBuffer()); return Ret; } template SharedFile::SharedFile(MemoryBufferRef M) : ELFFileBase(Base::SharedKind, M), AsNeeded(Config->AsNeeded) {} template const typename ELFT::Shdr * SharedFile::getSection(const Elf_Sym &Sym) const { uint32_t Index = this->getSectionIndex(Sym); if (Index == 0) return nullptr; return check(this->ELFObj.getSection(Index)); } // Partially parse the shared object file so that we can call // getSoName on this object. template void SharedFile::parseSoName() { typedef typename ELFT::Dyn Elf_Dyn; typedef typename ELFT::uint uintX_t; const Elf_Shdr *DynamicSec = nullptr; const ELFFile Obj = this->ELFObj; for (const Elf_Shdr &Sec : Obj.sections()) { switch (Sec.sh_type) { default: continue; case SHT_DYNSYM: this->Symtab = &Sec; break; case SHT_DYNAMIC: DynamicSec = &Sec; break; case SHT_SYMTAB_SHNDX: this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec)); break; case SHT_GNU_versym: this->VersymSec = &Sec; break; case SHT_GNU_verdef: this->VerdefSec = &Sec; break; } } this->initStringTable(); SoName = sys::path::filename(this->getName()); if (!DynamicSec) return; auto *Begin = reinterpret_cast(Obj.base() + DynamicSec->sh_offset); const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn); for (const Elf_Dyn &Dyn : make_range(Begin, End)) { if (Dyn.d_tag == DT_SONAME) { uintX_t Val = Dyn.getVal(); if (Val >= this->StringTable.size()) fatal(getFilename(this) + ": invalid DT_SONAME entry"); SoName = StringRef(this->StringTable.data() + Val); return; } } } // Parse the version definitions in the object file if present. Returns a vector // whose nth element contains a pointer to the Elf_Verdef for version identifier // n. Version identifiers that are not definitions map to nullptr. The array // always has at least length 1. template std::vector SharedFile::parseVerdefs(const Elf_Versym *&Versym) { std::vector Verdefs(1); // We only need to process symbol versions for this DSO if it has both a // versym and a verdef section, which indicates that the DSO contains symbol // version definitions. if (!VersymSec || !VerdefSec) return Verdefs; // The location of the first global versym entry. Versym = reinterpret_cast(this->ELFObj.base() + VersymSec->sh_offset) + this->Symtab->sh_info; // We cannot determine the largest verdef identifier without inspecting // every Elf_Verdef, but both bfd and gold assign verdef identifiers // sequentially starting from 1, so we predict that the largest identifier // will be VerdefCount. unsigned VerdefCount = VerdefSec->sh_info; Verdefs.resize(VerdefCount + 1); // Build the Verdefs array by following the chain of Elf_Verdef objects // from the start of the .gnu.version_d section. const uint8_t *Verdef = this->ELFObj.base() + VerdefSec->sh_offset; for (unsigned I = 0; I != VerdefCount; ++I) { auto *CurVerdef = reinterpret_cast(Verdef); Verdef += CurVerdef->vd_next; unsigned VerdefIndex = CurVerdef->vd_ndx; if (Verdefs.size() <= VerdefIndex) Verdefs.resize(VerdefIndex + 1); Verdefs[VerdefIndex] = CurVerdef; } return Verdefs; } // Fully parse the shared object file. This must be called after parseSoName(). template void SharedFile::parseRest() { // Create mapping from version identifiers to Elf_Verdef entries. const Elf_Versym *Versym = nullptr; std::vector Verdefs = parseVerdefs(Versym); Elf_Sym_Range Syms = this->getElfSymbols(true); for (const Elf_Sym &Sym : Syms) { unsigned VersymIndex = 0; if (Versym) { VersymIndex = Versym->vs_index; ++Versym; } StringRef Name = check(Sym.getName(this->StringTable)); if (Sym.isUndefined()) { Undefs.push_back(Name); continue; } if (Versym) { // Ignore local symbols and non-default versions. if (VersymIndex == VER_NDX_LOCAL || (VersymIndex & VERSYM_HIDDEN)) continue; } const Elf_Verdef *V = VersymIndex == VER_NDX_GLOBAL ? nullptr : Verdefs[VersymIndex]; elf::Symtab::X->addShared(this, Name, Sym, V); } } static ELFKind getELFKind(MemoryBufferRef MB) { std::string TripleStr = getBitcodeTargetTriple(MB, Driver->Context); Triple TheTriple(TripleStr); bool Is64Bits = TheTriple.isArch64Bit(); if (TheTriple.isLittleEndian()) return Is64Bits ? ELF64LEKind : ELF32LEKind; return Is64Bits ? ELF64BEKind : ELF32BEKind; } static uint8_t getMachineKind(MemoryBufferRef MB) { std::string TripleStr = getBitcodeTargetTriple(MB, Driver->Context); switch (Triple(TripleStr).getArch()) { case Triple::aarch64: return EM_AARCH64; case Triple::arm: return EM_ARM; case Triple::mips: case Triple::mipsel: case Triple::mips64: case Triple::mips64el: return EM_MIPS; case Triple::ppc: return EM_PPC; case Triple::ppc64: return EM_PPC64; case Triple::x86: return EM_386; case Triple::x86_64: return EM_X86_64; default: fatal(MB.getBufferIdentifier() + ": could not infer e_machine from bitcode target triple " + TripleStr); } } BitcodeFile::BitcodeFile(MemoryBufferRef MB) : InputFile(BitcodeKind, MB) { EKind = getELFKind(MB); EMachine = getMachineKind(MB); } static uint8_t getGvVisibility(const GlobalValue *GV) { switch (GV->getVisibility()) { case GlobalValue::DefaultVisibility: return STV_DEFAULT; case GlobalValue::HiddenVisibility: return STV_HIDDEN; case GlobalValue::ProtectedVisibility: return STV_PROTECTED; } llvm_unreachable("unknown visibility"); } template Symbol *BitcodeFile::createSymbol(const DenseSet &KeptComdats, const IRObjectFile &Obj, const BasicSymbolRef &Sym) { const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl()); SmallString<64> Name; raw_svector_ostream OS(Name); Sym.printName(OS); StringRef NameRef = Saver.save(StringRef(Name)); uint32_t Flags = Sym.getFlags(); bool IsWeak = Flags & BasicSymbolRef::SF_Weak; uint32_t Binding = IsWeak ? STB_WEAK : STB_GLOBAL; uint8_t Type = STT_NOTYPE; bool CanOmitFromDynSym = false; // FIXME: Expose a thread-local flag for module asm symbols. if (GV) { if (GV->isThreadLocal()) Type = STT_TLS; CanOmitFromDynSym = canBeOmittedFromSymbolTable(GV); } uint8_t Visibility; if (GV) Visibility = getGvVisibility(GV); else // FIXME: Set SF_Hidden flag correctly for module asm symbols, and expose // protected visibility. Visibility = STV_DEFAULT; if (GV) if (const Comdat *C = GV->getComdat()) if (!KeptComdats.count(C)) return Symtab::X->addUndefined(NameRef, Binding, Visibility, Type, CanOmitFromDynSym, this); const Module &M = Obj.getModule(); if (Flags & BasicSymbolRef::SF_Undefined) return Symtab::X->addUndefined(NameRef, Binding, Visibility, Type, CanOmitFromDynSym, this); if (Flags & BasicSymbolRef::SF_Common) { // FIXME: Set SF_Common flag correctly for module asm symbols, and expose // size and alignment. assert(GV); const DataLayout &DL = M.getDataLayout(); uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); return Symtab::X->addCommon(NameRef, Size, GV->getAlignment(), Binding, Visibility, STT_OBJECT, this); } return Symtab::X->addBitcode(NameRef, IsWeak, Visibility, Type, CanOmitFromDynSym, this); } bool BitcodeFile::shouldSkip(uint32_t Flags) { return !(Flags & BasicSymbolRef::SF_Global) || (Flags & BasicSymbolRef::SF_FormatSpecific); } template void BitcodeFile::parse(DenseSet &ComdatGroups) { Obj = check(IRObjectFile::create(MB, Driver->Context)); const Module &M = Obj->getModule(); DenseSet KeptComdats; for (const auto &P : M.getComdatSymbolTable()) { StringRef N = Saver.save(P.first()); if (ComdatGroups.insert(N).second) KeptComdats.insert(&P.second); } for (const BasicSymbolRef &Sym : Obj->symbols()) if (!shouldSkip(Sym.getFlags())) Symbols.push_back(createSymbol(KeptComdats, *Obj, Sym)); } template