diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -333,7 +333,7 @@ } else { COFFSymbolRef coffSym = check(file->getCOFFObj()->getSymbol(rel.SymbolTableIndex)); - file->getCOFFObj()->getSymbolName(coffSym, name); + name = check(file->getCOFFObj()->getSymbolName(coffSym)); } std::vector symbolLocations = diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -169,8 +169,7 @@ if (coffSym.isUndefined() || !coffSym.isExternal() || coffSym.isWeakExternal()) continue; - StringRef name; - coffObj->getSymbolName(coffSym, name); + StringRef name = check(coffObj->getSymbolName(coffSym)); if (coffSym.isAbsolute() && ignoredSymbolName(name)) continue; symtab->addLazyObject(this, name); @@ -196,11 +195,11 @@ initializeDependencies(); } -const coff_section* ObjFile::getSection(uint32_t i) { - const coff_section *sec; - if (auto ec = coffObj->getSection(i, sec)) - fatal("getSection failed: #" + Twine(i) + ": " + ec.message()); - return sec; +const coff_section *ObjFile::getSection(uint32_t i) { + auto sec = coffObj->getSection(i); + if (!sec) + fatal("getSection failed: #" + Twine(i) + ": " + toString(sec.takeError())); + return *sec; } // We set SectionChunk pointers in the SparseChunks vector to this value @@ -308,9 +307,9 @@ int32_t sectionNumber = sym.getSectionNumber(); auto diag = [&]() { - StringRef name, parentName; - coffObj->getSymbolName(sym, name); + StringRef name = check(coffObj->getSymbolName(sym)); + StringRef parentName; const coff_section *parentSec = getSection(parentIndex); if (Expected e = coffObj->getSectionName(parentSec)) parentName = *e; @@ -351,7 +350,7 @@ SectionChunk *sc = sparseChunks[sectionNumber]; if (sc && sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) { StringRef name; - coffObj->getSymbolName(sym, name); + name = check(coffObj->getSymbolName(sym)); if (getMachineType() == I386) name.consume_front("_"); prevailingSectionMap[name] = sectionNumber; @@ -361,8 +360,7 @@ void ObjFile::maybeAssociateSEHForMingw( COFFSymbolRef sym, const coff_aux_section_definition *def, const DenseMap &prevailingSectionMap) { - StringRef name; - coffObj->getSymbolName(sym, name); + StringRef name = check(coffObj->getSymbolName(sym)); if (name.consume_front(".pdata$") || name.consume_front(".xdata$") || name.consume_front(".eh_frame$")) { // For MinGW, treat .[px]data$ and .eh_frame$ as implicitly @@ -376,8 +374,7 @@ Symbol *ObjFile::createRegular(COFFSymbolRef sym) { SectionChunk *sc = sparseChunks[sym.getSectionNumber()]; if (sym.isExternal()) { - StringRef name; - coffObj->getSymbolName(sym, name); + StringRef name = check(coffObj->getSymbolName(sym)); if (sc) return symtab->addRegular(this, name, sym.getGeneric(), sc, sym.getValue()); @@ -445,8 +442,7 @@ maybeAssociateSEHForMingw(sym, def, prevailingSectionMap); } if (sparseChunks[sym.getSectionNumber()] == pendingComdat) { - StringRef name; - coffObj->getSymbolName(sym, name); + StringRef name = check(coffObj->getSymbolName(sym)); log("comdat section " + name + " without leader and unassociated, discarding"); continue; @@ -462,8 +458,7 @@ } Symbol *ObjFile::createUndefined(COFFSymbolRef sym) { - StringRef name; - coffObj->getSymbolName(sym, name); + StringRef name = check(coffObj->getSymbolName(sym)); return symtab->addUndefined(name, this, sym.isWeakExternal()); } @@ -559,8 +554,7 @@ case IMAGE_COMDAT_SELECT_LARGEST: if (leaderChunk->getSize() < getSection(sym)->SizeOfRawData) { // Replace the existing comdat symbol with the new one. - StringRef name; - coffObj->getSymbolName(sym, name); + StringRef name = check(coffObj->getSymbolName(sym)); // FIXME: This is incorrect: With /opt:noref, the previous sections // make it into the final executable as well. Correct handling would // be to undo reading of the whole old section that's being replaced, @@ -584,11 +578,7 @@ std::vector &comdatDefs, bool &prevailing) { prevailing = false; - auto getName = [&]() { - StringRef s; - coffObj->getSymbolName(sym, s); - return s; - }; + auto getName = [&]() { return check(coffObj->getSymbolName(sym)); }; if (sym.isCommon()) { auto *c = make(sym); diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -56,8 +56,8 @@ assert(nameData == nullptr && "should only compute the name once for DefinedCOFF symbols"); auto *d = cast(this); - StringRef nameStr; - cast(d->file)->getCOFFObj()->getSymbolName(d->sym, nameStr); + StringRef nameStr = + check(cast(d->file)->getCOFFObj()->getSymbolName(d->sym)); nameData = nameStr.data(); nameSize = nameStr.size(); assert(nameSize == nameStr.size() && "name length truncated"); diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h --- a/llvm/include/llvm/Object/COFF.h +++ b/llvm/include/llvm/Object/COFF.h @@ -787,7 +787,7 @@ // Either coff_load_configuration32 or coff_load_configuration64. const void *LoadConfig = nullptr; - std::error_code getString(uint32_t offset, StringRef &Res) const; + Expected getString(uint32_t offset) const; template const coff_symbol_type *toSymb(DataRefImpl Symb) const; @@ -985,32 +985,15 @@ std::error_code getDataDirectory(uint32_t index, const data_directory *&Res) const; - std::error_code getSection(int32_t index, const coff_section *&Res) const; - std::error_code getSection(StringRef SectionName, - const coff_section *&Res) const; + Expected getSection(int32_t index) const; - template - std::error_code getSymbol(uint32_t Index, - const coff_symbol_type *&Res) const { - if (Index >= getNumberOfSymbols()) - return object_error::parse_failed; - - Res = reinterpret_cast(getSymbolTable()) + Index; - return std::error_code(); - } Expected getSymbol(uint32_t index) const { - if (SymbolTable16) { - const coff_symbol16 *Symb = nullptr; - if (std::error_code EC = getSymbol(index, Symb)) - return errorCodeToError(EC); - return COFFSymbolRef(Symb); - } - if (SymbolTable32) { - const coff_symbol32 *Symb = nullptr; - if (std::error_code EC = getSymbol(index, Symb)) - return errorCodeToError(EC); - return COFFSymbolRef(Symb); - } + if (index >= getNumberOfSymbols()) + return errorCodeToError(object_error::parse_failed); + if (SymbolTable16) + return COFFSymbolRef(SymbolTable16 + index); + if (SymbolTable32) + return COFFSymbolRef(SymbolTable32 + index); return errorCodeToError(object_error::parse_failed); } @@ -1023,9 +1006,8 @@ return std::error_code(); } - std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const; - std::error_code getSymbolName(const coff_symbol_generic *Symbol, - StringRef &Res) const; + Expected getSymbolName(COFFSymbolRef Symbol) const; + Expected getSymbolName(const coff_symbol_generic *Symbol) const; ArrayRef getSymbolAuxData(COFFSymbolRef Symbol) const; diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -147,11 +147,7 @@ } Expected COFFObjectFile::getSymbolName(DataRefImpl Ref) const { - COFFSymbolRef Symb = getCOFFSymbol(Ref); - StringRef Result; - if (std::error_code EC = getSymbolName(Symb, Result)) - return errorCodeToError(EC); - return Result; + return getSymbolName(getCOFFSymbol(Ref)); } uint64_t COFFObjectFile::getSymbolValueImpl(DataRefImpl Ref) const { @@ -174,10 +170,10 @@ COFF::isReservedSectionNumber(SectionNumber)) return Result; - const coff_section *Section = nullptr; - if (std::error_code EC = getSection(SectionNumber, Section)) - return errorCodeToError(EC); - Result += Section->VirtualAddress; + Expected Section = getSection(SectionNumber); + if (!Section) + return Section.takeError(); + Result += (*Section)->VirtualAddress; // The section VirtualAddress does not include ImageBase, and we want to // return virtual addresses. @@ -250,11 +246,11 @@ COFFSymbolRef Symb = getCOFFSymbol(Ref); if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) return section_end(); - const coff_section *Sec = nullptr; - if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) - return errorCodeToError(EC); + Expected Sec = getSection(Symb.getSectionNumber()); + if (!Sec) + return Sec.takeError(); DataRefImpl Ret; - Ret.p = reinterpret_cast(Sec); + Ret.p = reinterpret_cast(*Sec); return section_iterator(SectionRef(Ret, this)); } @@ -961,67 +957,43 @@ return std::error_code(); } -std::error_code COFFObjectFile::getSection(int32_t Index, - const coff_section *&Result) const { - Result = nullptr; +Expected COFFObjectFile::getSection(int32_t Index) const { + // Perhaps getting the section of a reserved section index should be an error, + // but callers rely on this to return null. if (COFF::isReservedSectionNumber(Index)) - return std::error_code(); + return (const coff_section *)nullptr; if (static_cast(Index) <= getNumberOfSections()) { // We already verified the section table data, so no need to check again. - Result = SectionTable + (Index - 1); - return std::error_code(); - } - return object_error::parse_failed; -} - -std::error_code COFFObjectFile::getSection(StringRef SectionName, - const coff_section *&Result) const { - Result = nullptr; - for (const SectionRef &Section : sections()) { - auto NameOrErr = Section.getName(); - if (!NameOrErr) - return errorToErrorCode(NameOrErr.takeError()); - - if (*NameOrErr == SectionName) { - Result = getCOFFSection(Section); - return std::error_code(); - } + return SectionTable + (Index - 1); } - return object_error::parse_failed; + return errorCodeToError(object_error::parse_failed); } -std::error_code COFFObjectFile::getString(uint32_t Offset, - StringRef &Result) const { +Expected COFFObjectFile::getString(uint32_t Offset) const { if (StringTableSize <= 4) // Tried to get a string from an empty string table. - return object_error::parse_failed; + return errorCodeToError(object_error::parse_failed); if (Offset >= StringTableSize) - return object_error::unexpected_eof; - Result = StringRef(StringTable + Offset); - return std::error_code(); + return errorCodeToError(object_error::unexpected_eof); + return StringRef(StringTable + Offset); } -std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol, - StringRef &Res) const { - return getSymbolName(Symbol.getGeneric(), Res); +Expected COFFObjectFile::getSymbolName(COFFSymbolRef Symbol) const { + return getSymbolName(Symbol.getGeneric()); } -std::error_code COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol, - StringRef &Res) const { +Expected +COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol) const { // Check for string table entry. First 4 bytes are 0. - if (Symbol->Name.Offset.Zeroes == 0) { - if (std::error_code EC = getString(Symbol->Name.Offset.Offset, Res)) - return EC; - return std::error_code(); - } + if (Symbol->Name.Offset.Zeroes == 0) + return getString(Symbol->Name.Offset.Offset); + // Null terminated, let ::strlen figure out the length. if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0) - // Null terminated, let ::strlen figure out the length. - Res = StringRef(Symbol->Name.ShortName); - else - // Not null terminated, use all 8 bytes. - Res = StringRef(Symbol->Name.ShortName, COFF::NameSize); - return std::error_code(); + return StringRef(Symbol->Name.ShortName); + + // Not null terminated, use all 8 bytes. + return StringRef(Symbol->Name.ShortName, COFF::NameSize); } ArrayRef @@ -1079,8 +1051,7 @@ return createStringError(object_error::parse_failed, "invalid section name"); } - if (std::error_code EC = getString(Offset, Name)) - return errorCodeToError(EC); + return getString(Offset); } return Name; @@ -1829,15 +1800,16 @@ Expected Sym = Obj->getSymbol(R.SymbolTableIndex); if (!Sym) return Sym.takeError(); - const coff_section *Section = nullptr; // And the symbol's section - if (std::error_code EC = Obj->getSection(Sym->getSectionNumber(), Section)) - return errorCodeToError(EC); + Expected Section = + Obj->getSection(Sym->getSectionNumber()); + if (!Section) + return Section.takeError(); // Add the initial value of DataRVA to the symbol's offset to find the // data it points at. uint64_t Offset = Entry.DataRVA + Sym->getValue(); ArrayRef Contents; - if (Error E = Obj->getSectionContents(Section, Contents)) + if (Error E = Obj->getSectionContents(*Section, Contents)) return std::move(E); if (Offset + Entry.DataSize > Contents.size()) return createStringError(object_error::parse_failed, diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp --- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp @@ -57,9 +57,10 @@ std::vector
Sections; // Section indexing starts from 1. for (size_t I = 1, E = COFFObj.getNumberOfSections(); I <= E; I++) { - const coff_section *Sec; - if (auto EC = COFFObj.getSection(I, Sec)) - return errorCodeToError(EC); + Expected SecOrErr = COFFObj.getSection(I); + if (!SecOrErr) + return SecOrErr.takeError(); + const coff_section *Sec = *SecOrErr; Sections.push_back(Section()); Section &S = Sections.back(); S.Header = *Sec; @@ -99,8 +100,10 @@ else copySymbol(Sym.Sym, *reinterpret_cast(SymRef.getRawPtr())); - if (auto EC = COFFObj.getSymbolName(SymRef, Sym.Name)) - return errorCodeToError(EC); + auto NameOrErr = COFFObj.getSymbolName(SymRef); + if (!NameOrErr) + return NameOrErr.takeError(); + Sym.Name = *NameOrErr; ArrayRef AuxData = COFFObj.getSymbolAuxData(SymRef); size_t SymSize = IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16); diff --git a/llvm/tools/llvm-objdump/COFFDump.cpp b/llvm/tools/llvm-objdump/COFFDump.cpp --- a/llvm/tools/llvm-objdump/COFFDump.cpp +++ b/llvm/tools/llvm-objdump/COFFDump.cpp @@ -664,9 +664,10 @@ if (!Symbol) reportError(Symbol.takeError(), coff->getFileName()); - StringRef Name; - if (std::error_code EC = coff->getSymbolName(*Symbol, Name)) - reportError(errorCodeToError(EC), coff->getFileName()); + Expected NameOrErr = coff->getSymbolName(*Symbol); + if (!NameOrErr) + reportError(NameOrErr.takeError(), coff->getFileName()); + StringRef Name = *NameOrErr; outs() << "[" << format("%2d", SI) << "]" << "(sec " << format("%2d", int(Symbol->getSectionNumber())) << ")" diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -1469,21 +1469,25 @@ DictScope D(W, "Symbol"); COFFSymbolRef Symbol = Obj->getCOFFSymbol(Sym); - const coff_section *Section; - if (std::error_code EC = Obj->getSection(Symbol.getSectionNumber(), Section)) { - W.startLine() << "Invalid section number: " << EC.message() << "\n"; + Expected SecOrErr = + Obj->getSection(Symbol.getSectionNumber()); + if (!SecOrErr) { + W.startLine() << "Invalid section number: " << Symbol.getSectionNumber() + << "\n"; W.flush(); + consumeError(SecOrErr.takeError()); return; } + const coff_section *Section = *SecOrErr; StringRef SymbolName; - if (Obj->getSymbolName(Symbol, SymbolName)) - SymbolName = ""; + if (Expected SymNameOrErr = Obj->getSymbolName(Symbol)) + SymbolName = *SymNameOrErr; StringRef SectionName; - if (Expected NameOrErr = + if (Expected SecNameOrErr = getSectionName(Obj, Symbol.getSectionNumber(), Section)) - SectionName = *NameOrErr; + SectionName = *SecNameOrErr; W.printString("Name", SymbolName); W.printNumber("Value", Symbol.getValue()); @@ -1516,12 +1520,12 @@ if (!Linked) reportError(Linked.takeError(), Obj->getFileName()); - StringRef LinkedName; - if (std::error_code EC = Obj->getSymbolName(*Linked, LinkedName)) - reportError(errorCodeToError(EC), Obj->getFileName()); + Expected LinkedName = Obj->getSymbolName(*Linked); + if (!LinkedName) + reportError(LinkedName.takeError(), Obj->getFileName()); DictScope AS(W, "AuxWeakExternal"); - W.printNumber("Linked", LinkedName, Aux->TagIndex); + W.printNumber("Linked", *LinkedName, Aux->TagIndex); W.printEnum ("Search", Aux->Characteristics, makeArrayRef(WeakExternalCharacteristics)); @@ -1552,16 +1556,14 @@ if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { - const coff_section *Assoc; - StringRef AssocName = ""; - if (std::error_code EC = Obj->getSection(AuxNumber, Assoc)) - reportError(errorCodeToError(EC), Obj->getFileName()); - Expected Res = getSectionName(Obj, AuxNumber, Assoc); - if (!Res) - reportError(Res.takeError(), Obj->getFileName()); - AssocName = *Res; - - W.printNumber("AssocSection", AssocName, AuxNumber); + Expected Assoc = Obj->getSection(AuxNumber); + if (!Assoc) + reportError(Assoc.takeError(), Obj->getFileName()); + Expected AssocName = getSectionName(Obj, AuxNumber, *Assoc); + if (!AssocName) + reportError(AssocName.takeError(), Obj->getFileName()); + + W.printNumber("AssocSection", *AssocName, AuxNumber); } } else if (Symbol.isCLRToken()) { const coff_aux_clr_token *Aux; @@ -1573,14 +1575,14 @@ if (!ReferredSym) reportError(ReferredSym.takeError(), Obj->getFileName()); - StringRef ReferredName; - if (std::error_code EC = Obj->getSymbolName(*ReferredSym, ReferredName)) - reportError(errorCodeToError(EC), Obj->getFileName()); + Expected ReferredName = Obj->getSymbolName(*ReferredSym); + if (!ReferredName) + reportError(ReferredName.takeError(), Obj->getFileName()); DictScope AS(W, "AuxCLRToken"); W.printNumber("AuxType", Aux->AuxType); W.printNumber("Reserved", Aux->Reserved); - W.printNumber("SymbolTableIndex", ReferredName, Aux->SymbolTableIndex); + W.printNumber("SymbolTableIndex", *ReferredName, Aux->SymbolTableIndex); } else { W.startLine() << "\n"; @@ -1969,11 +1971,11 @@ if (!Sym) reportError(Sym.takeError(), Obj->getFileName()); - StringRef SymName; - if (std::error_code EC = Obj->getSymbolName(*Sym, SymName)) - reportError(errorCodeToError(EC), Obj->getFileName()); + Expected SymName = Obj->getSymbolName(*Sym); + if (!SymName) + reportError(SymName.takeError(), Obj->getFileName()); - W.printNumber("Sym", SymName, SymIndex); + W.printNumber("Sym", *SymName, SymIndex); Cur += Size; } } diff --git a/llvm/tools/obj2yaml/coff2yaml.cpp b/llvm/tools/obj2yaml/coff2yaml.cpp --- a/llvm/tools/obj2yaml/coff2yaml.cpp +++ b/llvm/tools/obj2yaml/coff2yaml.cpp @@ -100,7 +100,7 @@ initializeFileAndStringTable(const llvm::object::COFFObjectFile &Obj, codeview::StringsAndChecksumsRef &SC) { - ExitOnError Err("Invalid .debug$S section!"); + ExitOnError Err("invalid .debug$S section"); // Iterate all .debug$S sections looking for the checksums and string table. // Exit as soon as both sections are found. for (const auto &S : Obj.sections()) { @@ -139,11 +139,10 @@ codeview::StringsAndChecksumsRef SC; initializeFileAndStringTable(Obj, SC); + ExitOnError Err("invalid section table"); StringMap SymbolUnique; for (const auto &S : Obj.symbols()) { - object::COFFSymbolRef Symbol = Obj.getCOFFSymbol(S); - StringRef Name; - Obj.getSymbolName(Symbol, Name); + StringRef Name = Err(Obj.getSymbolName(Obj.getCOFFSymbol(S))); StringMap::iterator It; bool Inserted; std::tie(It, Inserted) = SymbolUnique.insert(std::make_pair(Name, true)); @@ -277,11 +276,13 @@ } void COFFDumper::dumpSymbols(unsigned NumSymbols) { + ExitOnError Err("invalid symbol table"); + std::vector &Symbols = YAMLObj.Symbols; for (const auto &S : Obj.symbols()) { object::COFFSymbolRef Symbol = Obj.getCOFFSymbol(S); COFFYAML::Symbol Sym; - Obj.getSymbolName(Symbol, Sym.Name); + Sym.Name = Err(Obj.getSymbolName(Symbol)); Sym.SimpleType = COFF::SymbolBaseType(Symbol.getBaseType()); Sym.ComplexType = COFF::SymbolComplexType(Symbol.getComplexType()); Sym.Header.StorageClass = Symbol.getStorageClass();