Index: lld/trunk/ELF/GdbIndex.cpp =================================================================== --- lld/trunk/ELF/GdbIndex.cpp +++ lld/trunk/ELF/GdbIndex.cpp @@ -81,8 +81,7 @@ Dwarf.reset(new DWARFContextInMemory(*Obj.get())); if (!Dwarf) { - error(getFilename(DebugInfoSec->getFile()) + - ": error creating DWARF context"); + error(toString(DebugInfoSec->getFile()) + ": error creating DWARF context"); return {}; } Index: lld/trunk/ELF/InputFiles.h =================================================================== --- lld/trunk/ELF/InputFiles.h +++ lld/trunk/ELF/InputFiles.h @@ -85,7 +85,7 @@ }; // Returns "(internal)", "foo.a(bar.o)" or "baz.o". -std::string getFilename(const InputFile *F); +std::string toString(const InputFile *F); template class ELFFileBase : public InputFile { public: @@ -150,7 +150,7 @@ SymbolBody &getSymbolBody(uint32_t SymbolIndex) const { if (SymbolIndex >= SymbolBodies.size()) - fatal(getFilename(this) + ": invalid symbol index"); + fatal(toString(this) + ": invalid symbol index"); return *SymbolBodies[SymbolIndex]; } Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -95,7 +95,7 @@ } // Returns "(internal)", "foo.a(bar.o)" or "baz.o". -std::string elf::getFilename(const InputFile *F) { +std::string elf::toString(const InputFile *F) { if (!F) return "(internal)"; if (!F->ArchiveName.empty()) @@ -132,7 +132,7 @@ FirstNonLocal = Symtab->sh_info; Symbols = check(getObj().symbols(Symtab)); if (FirstNonLocal == 0 || FirstNonLocal > Symbols.size()) - fatal(getFilename(this) + ": invalid sh_info in symbol table"); + fatal(toString(this) + ": invalid sh_info in symbol table"); StringTable = check(getObj().getStringTableForSymtab(*Symtab, Sections)); } @@ -189,7 +189,7 @@ ArrayRef Entries = check(Obj.template getSectionContentsAsArray(&Sec)); if (Entries.empty() || Entries[0] != GRP_COMDAT) - fatal(getFilename(this) + ": unsupported SHT_GROUP format"); + fatal(toString(this) + ": unsupported SHT_GROUP format"); return Entries.slice(1); } @@ -225,14 +225,14 @@ if (EntSize == 0) return false; if (Sec.sh_size % EntSize) - fatal(getFilename(this) + + fatal(toString(this) + ": SHF_MERGE section size must be a multiple of sh_entsize"); 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"); + fatal(toString(this) + ": writable SHF_MERGE section is not supported"); // Don't try to merge if the alignment is larger than the sh_entsize and this // is not SHF_STRINGS. @@ -277,7 +277,7 @@ continue; for (uint32_t SecIndex : getShtGroupEntries(Sec)) { if (SecIndex >= Size) - fatal(getFilename(this) + ": invalid section index in group: " + + fatal(toString(this) + ": invalid section index in group: " + Twine(SecIndex)); Sections[SecIndex] = &InputSection::Discarded; } @@ -299,7 +299,7 @@ // have a SHF_LINK_ORDER dependency, this is identified by the sh_link. if (Sec.sh_flags & SHF_LINK_ORDER) { if (Sec.sh_link >= Sections.size()) - fatal(getFilename(this) + ": invalid sh_link index: " + + fatal(toString(this) + ": invalid sh_link index: " + Twine(Sec.sh_link)); auto *IS = cast>(Sections[Sec.sh_link]); IS->DependentSection = Sections[I]; @@ -312,8 +312,7 @@ 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)); + fatal(toString(this) + ": invalid relocated section index: " + Twine(Idx)); InputSectionBase *Target = Sections[Idx]; // Strictly speaking, a relocation section must be included in the @@ -323,7 +322,7 @@ return nullptr; if (!Target) - fatal(getFilename(this) + ": unsupported relocation reference"); + fatal(toString(this) + ": unsupported relocation reference"); return Target; } @@ -353,10 +352,10 @@ if (!Target) return nullptr; if (Target->FirstRelocation) - fatal(getFilename(this) + + fatal(toString(this) + ": multiple relocation sections to one section are not supported"); if (!isa>(Target) && !isa>(Target)) - fatal(getFilename(this) + + fatal(toString(this) + ": relocations pointing to SHF_MERGE are not supported"); size_t NumRelocations; @@ -414,7 +413,7 @@ elf::ObjectFile::getSection(const Elf_Sym &Sym) const { uint32_t Index = this->getSectionIndex(Sym); if (Index >= Sections.size()) - fatal(getFilename(this) + ": invalid section index: " + Twine(Index)); + fatal(toString(this) + ": invalid section index: " + Twine(Index)); InputSectionBase *S = Sections[Index]; // We found that GNU assembler 2.17.50 [FreeBSD] 2007-07-03 could @@ -426,7 +425,7 @@ if (Index == 0 || Sym.getType() == STT_SECTION || Sym.getType() == STT_NOTYPE) return nullptr; - fatal(getFilename(this) + ": invalid section index: " + Twine(Index)); + fatal(toString(this) + ": invalid section index: " + Twine(Index)); } if (S == &InputSection::Discarded) @@ -444,7 +443,7 @@ SourceFile = check(Sym->getName(this->StringTable)); if (this->StringTable.size() <= Sym->st_name) - fatal(getFilename(this) + ": invalid symbol name offset"); + fatal(toString(this) + ": invalid symbol name offset"); const char *Name = this->StringTable.data() + Sym->st_name; if (Sym->st_shndx == SHN_UNDEF) @@ -466,7 +465,7 @@ ->body(); case SHN_COMMON: if (Value == 0 || Value >= UINT32_MAX) - fatal(getFilename(this) + ": common symbol '" + Name + + fatal(toString(this) + ": common symbol '" + Name + "' has invalid alignment: " + Twine(Value)); return elf::Symtab::X ->addCommon(Name, Size, Value, Binding, StOther, Type, this) @@ -475,7 +474,7 @@ switch (Binding) { default: - fatal(getFilename(this) + ": unexpected binding: " + Twine(Binding)); + fatal(toString(this) + ": unexpected binding: " + Twine(Binding)); case STB_GLOBAL: case STB_WEAK: case STB_GNU_UNIQUE: @@ -577,12 +576,12 @@ ArrayRef Arr = check(Obj.template getSectionContentsAsArray(DynamicSec), - getFilename(this) + ": getSectionContentsAsArray failed"); + toString(this) + ": getSectionContentsAsArray failed"); for (const Elf_Dyn &Dyn : Arr) { if (Dyn.d_tag == DT_SONAME) { uintX_t Val = Dyn.getVal(); if (Val >= this->StringTable.size()) - fatal(getFilename(this) + ": invalid DT_SONAME entry"); + fatal(toString(this) + ": invalid DT_SONAME entry"); SoName = StringRef(this->StringTable.data() + Val); return; } Index: lld/trunk/ELF/InputSection.h =================================================================== --- lld/trunk/ELF/InputSection.h +++ lld/trunk/ELF/InputSection.h @@ -300,6 +300,8 @@ template InputSection InputSection::Discarded; +template std::string toString(const InputSectionBase *); + } // namespace elf } // namespace lld Index: lld/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -32,6 +32,12 @@ using namespace lld; using namespace lld::elf; +// Returns a string to construct an error message. +template +std::string elf::toString(const InputSectionBase *Sec) { + return (Sec->getFile()->getName() + ":(" + Sec->Name + ")").str(); +} + template static ArrayRef getSectionContents(elf::ObjectFile *File, const typename ELFT::Shdr *Hdr) { @@ -65,13 +71,13 @@ // no alignment constraits. uint64_t V = std::max(Addralign, 1); if (!isPowerOf2_64(V)) - fatal(getFilename(File) + ": section sh_addralign is not a power of 2"); + fatal(toString(File) + ": section sh_addralign is not a power of 2"); // We reject object files having insanely large alignments even though // they are allowed by the spec. I think 4GB is a reasonable limitation. // We might want to relax this in the future. if (V > UINT32_MAX) - fatal(getFilename(File) + ": section sh_addralign is too large"); + fatal(toString(File) + ": section sh_addralign is too large"); Alignment = V; } @@ -128,10 +134,10 @@ InputSectionBase::getElfCompressedData(ArrayRef Data) { // Compressed section with Elf_Chdr is the ELF standard. if (Data.size() < sizeof(Elf_Chdr)) - fatal(getName(this) + ": corrupted compressed section"); + fatal(toString(this) + ": corrupted compressed section"); auto *Hdr = reinterpret_cast(Data.data()); if (Hdr->ch_type != ELFCOMPRESS_ZLIB) - fatal(getName(this) + ": unsupported compression type"); + fatal(toString(this) + ": unsupported compression type"); return {Data.slice(sizeof(*Hdr)), Hdr->ch_size}; } @@ -147,16 +153,16 @@ }; if (Data.size() < sizeof(ZlibHeader)) - fatal(getName(this) + ": corrupted compressed section"); + fatal(toString(this) + ": corrupted compressed section"); auto *Hdr = reinterpret_cast(Data.data()); if (memcmp(Hdr->Magic, "ZLIB", 4)) - fatal(getName(this) + ": broken ZLIB-compressed section"); + fatal(toString(this) + ": broken ZLIB-compressed section"); return {Data.slice(sizeof(*Hdr)), read64be(Hdr->Size)}; } template void InputSectionBase::uncompress() { if (!zlib::isAvailable()) - fatal(getName(this) + + fatal(toString(this) + ": build lld with zlib to enable compressed sections support"); // This section is compressed. Here we decompress it. Ideally, all @@ -175,7 +181,7 @@ // Uncompress Buf. char *OutputBuf = BAlloc.Allocate(Size); if (zlib::uncompress(toStringRef(Buf), OutputBuf, Size) != zlib::StatusOK) - fatal(getName(this) + ": error while uncompressing section"); + fatal(toString(this) + ": error while uncompressing section"); Data = ArrayRef((uint8_t *)OutputBuf, Size); } @@ -667,7 +673,7 @@ while (!Data.empty()) { size_t End = findNull(Data, EntSize); if (End == StringRef::npos) - fatal(getName(this) + ": string is not null terminated"); + fatal(toString(this) + ": string is not null terminated"); size_t Size = End + EntSize; V.emplace_back(Off, !IsAlloca); Hashes.push_back(hash_value(toStringRef(Data.slice(0, Size)))); @@ -753,7 +759,7 @@ MergeInputSection::getSectionPiece(uintX_t Offset) const { uintX_t Size = this->Data.size(); if (Offset >= Size) - fatal(getName(this) + ": entry is past the end of the section"); + fatal(toString(this) + ": entry is past the end of the section"); // Find the element this offset points to. auto I = fastUpperBound( Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -271,8 +271,8 @@ return ((read32(BufLoc) & 0xffff) << 16) + readSignedLo16(Buf + RI->r_offset); } - warn("can't find matching " + getRelName(Type) + " relocation for " + - getRelName(Rel->getType(Config->Mips64EL))); + warn("can't find matching " + toString(Type) + " relocation for " + + toString(Rel->getType(Config->Mips64EL))); return 0; } @@ -343,9 +343,9 @@ if (AbsVal && RelE) { if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) return true; - error(getLocation(S, RelOff) + ": relocation " + getRelName(Type) + + error(getLocation(S, RelOff) + ": relocation " + toString(Type) + " cannot refer to absolute symbol '" + Body.getName() + - "' defined in " + getFilename(Body.File)); + "' defined in " + toString(Body.File)); return true; } @@ -445,15 +445,15 @@ if (Config->Shared || (Config->Pic && !isRelExpr(Expr))) { StringRef Name = Body.getName(); error(getLocation(S, RelOff) + ": can't create dynamic relocation " + - getRelName(Type) + " against " + + toString(Type) + " against " + ((Name.empty() ? "local symbol in readonly segment" : "symbol '" + Name + "'")) + - " defined in " + getFilename(Body.File)); + " defined in " + toString(Body.File)); return Expr; } if (Body.getVisibility() != STV_DEFAULT) { error(getLocation(S, RelOff) + ": cannot preempt symbol '" + - Body.getName() + "' defined in " + getFilename(Body.File)); + Body.getName() + "' defined in " + toString(Body.File)); return Expr; } if (Body.isObject()) { @@ -487,7 +487,7 @@ Body.NeedsCopyOrPltAddr = true; return toPlt(Expr); } - error("symbol '" + Body.getName() + "' defined in " + getFilename(Body.File) + + error("symbol '" + Body.getName() + "' defined in " + toString(Body.File) + " is missing type"); return Expr; @@ -548,7 +548,7 @@ // missing, we use an actual filename. std::string SrcFile = File->SourceFile; if (SrcFile.empty()) - SrcFile = getFilename(File); + SrcFile = toString(File); // Find a symbol at a given location. DefinedRegular *Encl = getSymbolAt(&S, Offset); Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -74,7 +74,7 @@ } if (Config->Trace) - outs() << getFilename(File) << "\n"; + outs() << toString(File) << "\n"; // .so file if (auto *F = dyn_cast>(File)) { @@ -207,7 +207,7 @@ // Used to construct an error message. static std::string conflictMsg(SymbolBody *Existing, InputFile *NewFile) { return "'" + maybeDemangle(Existing->getName()) + "' in " + - getFilename(Existing->File) + " and " + getFilename(NewFile); + toString(Existing->File) + " and " + toString(NewFile); } // Find an existing symbol or create and insert a new one, then apply the given Index: lld/trunk/ELF/Symbols.cpp =================================================================== --- lld/trunk/ELF/Symbols.cpp +++ lld/trunk/ELF/Symbols.cpp @@ -64,7 +64,7 @@ uintX_t VA = (SC->OutSec ? SC->OutSec->Addr : 0) + SC->getOffset(Offset); if (D.isTls() && !Config->Relocatable) { if (!Out::TlsPhdr) - fatal(getFilename(D.File) + + fatal(toString(D.File) + " has a STT_TLS symbol but doesn't have a PT_TLS section"); return VA - Out::TlsPhdr->p_vaddr; } @@ -307,7 +307,7 @@ // Print out a log message for --trace-symbol. void elf::printTraceSymbol(Symbol *Sym) { SymbolBody *B = Sym->body(); - outs() << getFilename(B->File); + outs() << toString(B->File); if (B->isUndefined()) outs() << ": reference to "; Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -134,7 +134,7 @@ Sec->Live = false; Create = true; - std::string Filename = getFilename(Sec->getFile()); + std::string Filename = toString(Sec->getFile()); if (Sec->Data.size() != sizeof(Elf_Mips_ABIFlags)) { error(Filename + ": invalid size of .MIPS.abiflags section"); return nullptr; @@ -196,7 +196,7 @@ Sec->Live = false; Create = true; - std::string Filename = getFilename(Sec->getFile()); + std::string Filename = toString(Sec->getFile()); ArrayRef D = Sec->Data; while (!D.empty()) { @@ -253,12 +253,12 @@ Create = true; if (Sec->Data.size() != sizeof(Elf_Mips_RegInfo)) { - error(getFilename(Sec->getFile()) + ": invalid size of .reginfo section"); + error(toString(Sec->getFile()) + ": invalid size of .reginfo section"); return nullptr; } auto *R = reinterpret_cast(Sec->Data.data()); if (Config->Relocatable && R->ri_gp_value) - error(getFilename(Sec->getFile()) + ": unsupported non-zero ri_gp_value"); + error(toString(Sec->getFile()) + ": unsupported non-zero ri_gp_value"); Reginfo.ri_gprmask |= R->ri_gprmask; Sec->getFile()->MipsGp0 = R->ri_gp_value; Index: lld/trunk/ELF/Target.h =================================================================== --- lld/trunk/ELF/Target.h +++ lld/trunk/ELF/Target.h @@ -102,7 +102,7 @@ virtual void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const; }; -StringRef getRelName(uint32_t Type); +std::string toString(uint32_t RelType); uint64_t getPPC64TocBase(); const unsigned MipsGPOffset = 0x7ff0; Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -51,32 +51,32 @@ static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); } static void or32be(uint8_t *P, int32_t V) { write32be(P, read32be(P) | V); } -StringRef getRelName(uint32_t Type) { +std::string toString(uint32_t Type) { return getELFRelocationTypeName(Config->EMachine, Type); } template static void checkInt(int64_t V, uint32_t Type) { if (!isInt(V)) - error("relocation " + getRelName(Type) + " out of range"); + error("relocation " + toString(Type) + " out of range"); } template static void checkUInt(uint64_t V, uint32_t Type) { if (!isUInt(V)) - error("relocation " + getRelName(Type) + " out of range"); + error("relocation " + toString(Type) + " out of range"); } template static void checkIntUInt(uint64_t V, uint32_t Type) { if (!isInt(V) && !isUInt(V)) - error("relocation " + getRelName(Type) + " out of range"); + error("relocation " + toString(Type) + " out of range"); } template static void checkAlignment(uint64_t V, uint32_t Type) { if ((V & (N - 1)) != 0) - error("improper alignment for relocation " + getRelName(Type)); + error("improper alignment for relocation " + toString(Type)); } static void errorDynRel(uint32_t Type) { - error("relocation " + getRelName(Type) + + error("relocation " + toString(Type) + " cannot be used against shared object; recompile with -fPIC."); } Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -376,14 +376,16 @@ for (elf::ObjectFile *F : Symtab::X->getObjectFiles()) { for (SymbolBody *B : F->getLocalSymbols()) { if (!B->IsLocal) - fatal(getFilename(F) + + fatal(toString(F) + ": broken object: getLocalSymbols returns a non-local symbol"); auto *DR = dyn_cast>(B); + // No reason to keep local undefined symbol in symtab. if (!DR) continue; if (!includeInSymtab(*B)) continue; + InputSectionBase *Sec = DR->Section; if (!shouldKeepInSymtab(Sec, B->getName(), *B)) continue;