X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-readobj%2FCOFFDumper.cpp;h=5b4129a10c536abc0fce3f3ed6efaba0fdbc35cb;hb=f2829c933c47e297b99b45a5453d751de31a9f12;hp=f5effe2924419b515c09ed608c030384df8cd627;hpb=8a80641a85a8b4afeae5058bf6e9ee405d080541;p=oota-llvm.git diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index f5effe29244..5b4129a10c5 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -48,7 +48,6 @@ public: COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter& Writer) : ObjDumper(Writer) , Obj(Obj) { - cacheRelocations(); } void printFileHeaders() override; @@ -92,6 +91,7 @@ private: typedef DenseMap > RelocMapTy; const llvm::object::COFFObjectFile *Obj; + bool RelocCached = false; RelocMapTy RelocMap; StringRef CVFileIndexToStringOffsetTable; StringRef CVStringTable; @@ -119,6 +119,7 @@ std::error_code createCOFFDumper(const object::ObjectFile *Obj, // symbol used for the relocation at the offset. std::error_code COFFDumper::resolveSymbol(const coff_section *Section, uint64_t Offset, SymbolRef &Sym) { + cacheRelocations(); const auto &Relocations = RelocMap[Section]; for (const auto &Relocation : Relocations) { uint64_t RelocationOffset = Relocation.getOffset(); @@ -218,6 +219,7 @@ static const EnumEntry PEDLLCharacteristics[] = { static const EnumEntry ImageSectionCharacteristics[] = { + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NOLOAD ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA ), @@ -339,6 +341,10 @@ static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, } void COFFDumper::cacheRelocations() { + if (RelocCached) + return; + RelocCached = true; + for (const SectionRef &S : Obj->sections()) { const coff_section *Section = Obj->getCOFFSection(S); @@ -380,14 +386,12 @@ void COFFDumper::printFileHeaders() { // Print PE header. This header does not exist if this is an object file and // not an executable. const pe32_header *PEHeader = nullptr; - if (error(Obj->getPE32Header(PEHeader))) - return; + error(Obj->getPE32Header(PEHeader)); if (PEHeader) printPEHeader(PEHeader); const pe32plus_header *PEPlusHeader = nullptr; - if (error(Obj->getPE32PlusHeader(PEPlusHeader))) - return; + error(Obj->getPE32PlusHeader(PEPlusHeader)); if (PEPlusHeader) printPEHeader(PEPlusHeader); @@ -472,8 +476,7 @@ void COFFDumper::printBaseOfDataField(const pe32plus_header *) {} void COFFDumper::printCodeViewDebugInfo(const SectionRef &Section) { StringRef Data; - if (error(Section.getContents(Data))) - return; + error(Section.getContents(Data)); SmallVector FunctionNames; StringMap FunctionLineTables; @@ -528,19 +531,18 @@ void COFFDumper::printCodeViewDebugInfo(const SectionRef &Section) { return; } - StringRef FunctionName; - if (error(resolveSymbolName(Obj->getCOFFSection(Section), Offset, - FunctionName))) - return; - W.printString("FunctionName", FunctionName); - if (FunctionLineTables.count(FunctionName) != 0) { + StringRef LinkageName; + error(resolveSymbolName(Obj->getCOFFSection(Section), Offset, + LinkageName)); + W.printString("LinkageName", LinkageName); + if (FunctionLineTables.count(LinkageName) != 0) { // Saw debug info for this function already? error(object_error::parse_failed); return; } - FunctionLineTables[FunctionName] = Contents; - FunctionNames.push_back(FunctionName); + FunctionLineTables[LinkageName] = Contents; + FunctionNames.push_back(LinkageName); break; } case COFF::DEBUG_STRING_TABLE_SUBSECTION: @@ -577,10 +579,14 @@ void COFFDumper::printCodeViewDebugInfo(const SectionRef &Section) { for (unsigned I = 0, E = FunctionNames.size(); I != E; ++I) { StringRef Name = FunctionNames[I]; ListScope S(W, "FunctionLineTable"); - W.printString("FunctionName", Name); + W.printString("LinkageName", Name); DataExtractor DE(FunctionLineTables[Name], true, 4); - uint32_t Offset = 8; // Skip relocations. + uint32_t Offset = 6; // Skip relocations. + uint16_t Flags = DE.getU16(&Offset); + W.printHex("Flags", Flags); + bool HasColumnInformation = + Flags & COFF::DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS; uint32_t FunctionSize = DE.getU32(&Offset); W.printHex("CodeSize", FunctionSize); while (DE.isValidOffset(Offset)) { @@ -588,9 +594,12 @@ void COFFDumper::printCodeViewDebugInfo(const SectionRef &Section) { // in the line table. The filename string is accessed using double // indirection to the string table subsection using the index subsection. uint32_t OffsetInIndex = DE.getU32(&Offset), - SegmentLength = DE.getU32(&Offset), + SegmentLength = DE.getU32(&Offset), FullSegmentSize = DE.getU32(&Offset); - if (FullSegmentSize != 12 + 8 * SegmentLength) { + + if (FullSegmentSize != + 12 + 8 * SegmentLength + + (HasColumnInformation ? 4 * SegmentLength : 0)) { error(object_error::parse_failed); return; } @@ -631,6 +640,15 @@ void COFFDumper::printCodeViewDebugInfo(const SectionRef &Section) { format("+0x%X", PC).snprint(Buffer, 32); W.printNumber(Buffer, LineNumber); } + if (HasColumnInformation) { + for (unsigned J = 0; J != SegmentLength && DE.isValidOffset(Offset); + ++J) { + uint16_t ColStart = DE.getU16(&Offset); + W.printNumber("ColStart", ColStart); + uint16_t ColEnd = DE.getU16(&Offset); + W.printNumber("ColEnd", ColEnd); + } + } } } } @@ -674,9 +692,8 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, uint32_t CodeSize = DE.getU32(&Offset); DE.getU8(&Offset, Unused, 12); StringRef SectionName; - if (error(resolveSymbolName(Obj->getCOFFSection(Section), - OffsetInSection + Offset, SectionName))) - return; + error(resolveSymbolName(Obj->getCOFFSection(Section), + OffsetInSection + Offset, SectionName)); Offset += 4; DE.getU8(&Offset, Unused, 3); StringRef DisplayName = DE.getCStr(&Offset); @@ -727,8 +744,7 @@ void COFFDumper::printSections() { const coff_section *Section = Obj->getCOFFSection(Sec); StringRef Name; - if (error(Sec.getName(Name))) - Name = ""; + error(Sec.getName(Name)); DictScope D(W, "Section"); W.printNumber("Number", SectionNumber); @@ -767,8 +783,7 @@ void COFFDumper::printSections() { if (opts::SectionData && !(Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) { StringRef Data; - if (error(Sec.getContents(Data))) - break; + error(Sec.getContents(Data)); W.printBinaryBlock("SectionData", Data); } @@ -782,8 +797,7 @@ void COFFDumper::printRelocations() { for (const SectionRef &Section : Obj->sections()) { ++SectionNumber; StringRef Name; - if (error(Section.getName(Name))) - continue; + error(Section.getName(Name)); bool PrintedGroup = false; for (const RelocationRef &Reloc : Section.relocations()) { @@ -813,8 +827,7 @@ void COFFDumper::printRelocation(const SectionRef &Section, symbol_iterator Symbol = Reloc.getSymbol(); if (Symbol != Obj->symbol_end()) { ErrorOr SymbolNameOrErr = Symbol->getName(); - if (error(SymbolNameOrErr.getError())) - return; + error(SymbolNameOrErr.getError()); SymbolName = *SymbolNameOrErr; } @@ -893,8 +906,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { for (uint8_t I = 0; I < Symbol.getNumberOfAuxSymbols(); ++I) { if (Symbol.isFunctionDefinition()) { const coff_aux_function_definition *Aux; - if (error(getSymbolAuxData(Obj, Symbol, I, Aux))) - break; + error(getSymbolAuxData(Obj, Symbol, I, Aux)); DictScope AS(W, "AuxFunctionDef"); W.printNumber("TagIndex", Aux->TagIndex); @@ -904,8 +916,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { } else if (Symbol.isAnyUndefined()) { const coff_aux_weak_external *Aux; - if (error(getSymbolAuxData(Obj, Symbol, I, Aux))) - break; + error(getSymbolAuxData(Obj, Symbol, I, Aux)); ErrorOr Linked = Obj->getSymbol(Aux->TagIndex); StringRef LinkedName; @@ -922,8 +933,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { } else if (Symbol.isFileRecord()) { const char *FileName; - if (error(getSymbolAuxData(Obj, Symbol, I, FileName))) - break; + error(getSymbolAuxData(Obj, Symbol, I, FileName)); DictScope AS(W, "AuxFileRecord"); @@ -933,8 +943,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { break; } else if (Symbol.isSectionDefinition()) { const coff_aux_section_definition *Aux; - if (error(getSymbolAuxData(Obj, Symbol, I, Aux))) - break; + error(getSymbolAuxData(Obj, Symbol, I, Aux)); int32_t AuxNumber = Aux->getNumber(Symbol.isBigObj()); @@ -965,8 +974,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { } } else if (Symbol.isCLRToken()) { const coff_aux_clr_token *Aux; - if (error(getSymbolAuxData(Obj, Symbol, I, Aux))) - break; + error(getSymbolAuxData(Obj, Symbol, I, Aux)); ErrorOr ReferredSym = Obj->getSymbol(Aux->SymbolTableIndex); @@ -1019,9 +1027,9 @@ void COFFDumper::printImportedSymbols( iterator_range Range) { for (const ImportedSymbolRef &I : Range) { StringRef Sym; - if (error(I.getSymbolName(Sym))) return; + error(I.getSymbolName(Sym)); uint16_t Ordinal; - if (error(I.getOrdinal(Ordinal))) return; + error(I.getOrdinal(Ordinal)); W.printNumber("Symbol", Sym, Ordinal); } } @@ -1033,12 +1041,12 @@ void COFFDumper::printDelayImportedSymbols( for (const ImportedSymbolRef &S : Range) { DictScope Import(W, "Import"); StringRef Sym; - if (error(S.getSymbolName(Sym))) return; + error(S.getSymbolName(Sym)); uint16_t Ordinal; - if (error(S.getOrdinal(Ordinal))) return; + error(S.getOrdinal(Ordinal)); W.printNumber("Symbol", Sym, Ordinal); uint64_t Addr; - if (error(I.getImportAddress(Index++, Addr))) return; + error(I.getImportAddress(Index++, Addr)); W.printHex("Address", Addr); } } @@ -1048,12 +1056,12 @@ void COFFDumper::printCOFFImports() { for (const ImportDirectoryEntryRef &I : Obj->import_directories()) { DictScope Import(W, "Import"); StringRef Name; - if (error(I.getName(Name))) return; + error(I.getName(Name)); W.printString("Name", Name); uint32_t Addr; - if (error(I.getImportLookupTableRVA(Addr))) return; + error(I.getImportLookupTableRVA(Addr)); W.printHex("ImportLookupTableRVA", Addr); - if (error(I.getImportAddressTableRVA(Addr))) return; + error(I.getImportAddressTableRVA(Addr)); W.printHex("ImportAddressTableRVA", Addr); printImportedSymbols(I.imported_symbols()); } @@ -1062,10 +1070,10 @@ void COFFDumper::printCOFFImports() { for (const DelayImportDirectoryEntryRef &I : Obj->delay_import_directories()) { DictScope Import(W, "DelayImport"); StringRef Name; - if (error(I.getName(Name))) return; + error(I.getName(Name)); W.printString("Name", Name); const delay_import_directory_table_entry *Table; - if (error(I.getDelayImportTable(Table))) return; + error(I.getDelayImportTable(Table)); W.printHex("Attributes", Table->Attributes); W.printHex("ModuleHandle", Table->ModuleHandle); W.printHex("ImportAddressTable", Table->DelayImportAddressTable); @@ -1083,12 +1091,9 @@ void COFFDumper::printCOFFExports() { StringRef Name; uint32_t Ordinal, RVA; - if (error(E.getSymbolName(Name))) - continue; - if (error(E.getOrdinal(Ordinal))) - continue; - if (error(E.getExportRVA(RVA))) - continue; + error(E.getSymbolName(Name)); + error(E.getOrdinal(Ordinal)); + error(E.getExportRVA(RVA)); W.printNumber("Ordinal", Ordinal); W.printString("Name", Name); @@ -1101,13 +1106,11 @@ void COFFDumper::printCOFFDirectives() { StringRef Contents; StringRef Name; - if (error(Section.getName(Name))) - continue; + error(Section.getName(Name)); if (Name != ".drectve") continue; - if (error(Section.getContents(Contents))) - return; + error(Section.getContents(Contents)); W.printString("Directive(s)", Contents); } @@ -1131,10 +1134,8 @@ void COFFDumper::printCOFFBaseReloc() { for (const BaseRelocRef &I : Obj->base_relocs()) { uint8_t Type; uint32_t RVA; - if (error(I.getRVA(RVA))) - continue; - if (error(I.getType(Type))) - continue; + error(I.getRVA(RVA)); + error(I.getType(Type)); DictScope Import(W, "Entry"); W.printString("Type", getBaseRelocTypeName(Type)); W.printHex("Address", RVA);