Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -205,14 +205,28 @@ uint64_t Offset) { llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); }); + // Detect SectionIndex for specified section. + uint64_t SectionIndex = object::SectionedAddress::UndefSection; + ArrayRef Sections = S->File->getSections(); + for (uint64_t CurIndex = 0; CurIndex < Sections.size(); ++CurIndex) { + if (S == Sections[CurIndex]) { + SectionIndex = CurIndex; + break; + } + } + // Use fake address calcuated by adding section file offset and offset in // section. See comments for ObjectInfo class. DILineInfo Info; - for (const llvm::DWARFDebugLine::LineTable *LT : LineTables) + for (const llvm::DWARFDebugLine::LineTable *LT : LineTables) { + object::SectionedAddress Address = {S->getOffsetInFile() + Offset, + SectionIndex}; + if (LT->getFileLineInfoForAddress( - S->getOffsetInFile() + Offset, nullptr, + Address, nullptr, DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Info)) return Info; + } return None; } Index: llvm/include/llvm/DebugInfo/DIContext.h =================================================================== --- llvm/include/llvm/DebugInfo/DIContext.h +++ llvm/include/llvm/DebugInfo/DIContext.h @@ -203,11 +203,14 @@ return true; } - virtual DILineInfo getLineInfoForAddress(uint64_t Address, + virtual DILineInfo getLineInfoForAddress( + object::SectionedAddress Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; - virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address, - uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; - virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address, + virtual DILineInfoTable getLineInfoForAddressRange( + object::SectionedAddress Address, uint64_t Size, + DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; + virtual DIInliningInfo getInliningInfoForAddress( + object::SectionedAddress Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; private: Index: llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -317,13 +317,18 @@ /// Get the compilation unit, the function DIE and lexical block DIE for the /// given address where applicable. + /// TODO: change input parameter from "uint64_t Address" + /// into "SectionedAddress Address" DIEsForAddress getDIEsForAddress(uint64_t Address); - DILineInfo getLineInfoForAddress(uint64_t Address, + DILineInfo getLineInfoForAddress( + object::SectionedAddress Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; - DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, + DILineInfoTable getLineInfoForAddressRange( + object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; - DIInliningInfo getInliningInfoForAddress(uint64_t Address, + DIInliningInfo getInliningInfoForAddress( + object::SectionedAddress Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; bool isLittleEndian() const { return DObj->isLittleEndian(); } @@ -366,6 +371,8 @@ private: /// Return the compile unit which contains instruction with provided /// address. + /// TODO: change input parameter from "uint64_t Address" + /// into "SectionedAddress Address" DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); }; Index: llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -139,12 +139,16 @@ static void dumpTableHeader(raw_ostream &OS); static bool orderByAddress(const Row &LHS, const Row &RHS) { - return LHS.Address < RHS.Address; + return std::tie(LHS.Address.SectionIndex, LHS.Address.Address) < + std::tie(RHS.Address.SectionIndex, RHS.Address.Address); } /// The program-counter value corresponding to a machine instruction - /// generated by the compiler. - uint64_t Address; + /// generated by the compiler and section index pointing to the section + /// containg this PC. If relocation information is present then section + /// index is the index of the section which contains above address. + /// Otherwise this is object::SectionedAddress::Undef value. + object::SectionedAddress Address; /// An unsigned integer indicating a source line number. Lines are numbered /// beginning at 1. The compiler may emit the value 0 in cases where an /// instruction cannot be attributed to any source line. @@ -192,6 +196,10 @@ /// and is described by line table rows [FirstRowIndex, LastRowIndex). uint64_t LowPC; uint64_t HighPC; + /// If relocation information is present then this is the index of the + /// section which contains above addresses. Otherwise this is + /// object::SectionedAddress::Undef value. + uint64_t SectionIndex; unsigned FirstRowIndex; unsigned LastRowIndex; bool Empty; @@ -199,14 +207,18 @@ void reset(); static bool orderByLowPC(const Sequence &LHS, const Sequence &RHS) { - return LHS.LowPC < RHS.LowPC; + return std::tie(LHS.SectionIndex, LHS.LowPC) < + std::tie(RHS.SectionIndex, RHS.LowPC); } bool isValid() const { return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex); } - bool containsPC(uint64_t PC) const { return (LowPC <= PC && PC < HighPC); } + bool containsPC(object::SectionedAddress PC) const { + return SectionIndex == PC.SectionIndex && + (LowPC <= PC.Address && PC.Address < HighPC); + } }; struct LineTable { @@ -223,9 +235,9 @@ /// Returns the index of the row with file/line info for a given address, /// or UnknownRowIndex if there is no such row. - uint32_t lookupAddress(uint64_t Address) const; + uint32_t lookupAddress(object::SectionedAddress Address) const; - bool lookupAddressRange(uint64_t Address, uint64_t Size, + bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector &Result) const; bool hasFileAtIndex(uint64_t FileIndex) const; @@ -238,7 +250,8 @@ /// Fills the Result argument with the file and line information /// corresponding to Address. Returns true on success. - bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir, + bool getFileLineInfoForAddress(object::SectionedAddress Address, + const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const; @@ -263,10 +276,15 @@ private: uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq, - uint64_t Address) const; + object::SectionedAddress Address) const; Optional getSourceByIndex(uint64_t FileIndex, DILineInfoSpecifier::FileLineInfoKind Kind) const; + + uint32_t lookupAddressImpl(object::SectionedAddress Address) const; + + bool lookupAddressRangeImpl(object::SectionedAddress Address, uint64_t Size, + std::vector &Result) const; }; const LineTable *getLineTable(uint32_t Offset) const; Index: llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -76,7 +76,7 @@ /// list. Has to be passed base address of the compile unit referencing this /// range list. DWARFAddressRangesVector - getAbsoluteRanges(llvm::Optional BaseAddr) const; + getAbsoluteRanges(llvm::Optional BaseAddr) const; }; } // end namespace llvm Index: llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h @@ -37,7 +37,7 @@ Error extract(DWARFDataExtractor Data, uint32_t End, uint32_t *OffsetPtr); void dump(raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength, uint64_t &CurrentBase, DIDumpOptions DumpOpts, - llvm::function_ref(uint32_t)> + llvm::function_ref(uint32_t)> LookupPooledAddress) const; bool isSentinel() const { return EntryKind == dwarf::DW_RLE_end_of_list; } }; @@ -47,7 +47,7 @@ public: /// Build a DWARFAddressRangesVector from a rangelist. DWARFAddressRangesVector - getAbsoluteRanges(llvm::Optional BaseAddr, + getAbsoluteRanges(llvm::Optional BaseAddr, DWARFUnit &U) const; }; Index: llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -74,7 +74,7 @@ const DWARFUnit *getUnit() const { return U; } void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const; void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts, - SectionedAddress SA) const; + object::SectionedAddress SA) const; static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS, DIDumpOptions DumpOpts, uint64_t SectionIndex); @@ -103,7 +103,7 @@ Optional getAsSignedConstant() const; Optional getAsCString() const; Optional getAsAddress() const; - Optional getAsSectionedAddress() const; + Optional getAsSectionedAddress() const; Optional getAsSectionOffset() const; Optional> getAsBlock() const; Optional getAsCStringOffset() const; @@ -241,7 +241,7 @@ return None; } -inline Optional +inline Optional toSectionedAddress(const Optional &V) { if (V) return V->getAsSectionedAddress(); Index: llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h @@ -157,7 +157,7 @@ uint8_t getAddrSize() const { return Header.getAddrSize(); } void dump(raw_ostream &OS, - llvm::function_ref(uint32_t)> + llvm::function_ref(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts = {}) const; @@ -234,7 +234,7 @@ template void DWARFListTableBase::dump( raw_ostream &OS, - llvm::function_ref(uint32_t)> + llvm::function_ref(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts) const { Header.dump(OS, DumpOpts); Index: llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h @@ -22,11 +22,6 @@ bool IsNameUnique; }; -struct SectionedAddress { - uint64_t Address; - uint64_t SectionIndex; -}; - } // end namespace llvm #endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H Index: llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -217,7 +217,7 @@ Optional RngListTable; mutable const DWARFAbbreviationDeclarationSet *Abbrevs; - llvm::Optional BaseAddr; + llvm::Optional BaseAddr; /// The compile unit debug information entry items. std::vector DieArray; @@ -304,7 +304,8 @@ RangeSectionBase = Base; } - Optional getAddrOffsetSectionItem(uint32_t Index) const; + Optional + getAddrOffsetSectionItem(uint32_t Index) const; Optional getStringOffsetSectionItem(uint32_t Index) const; DWARFDataExtractor getDebugInfoExtractor() const; @@ -375,7 +376,7 @@ llvm_unreachable("Invalid UnitType."); } - llvm::Optional getBaseAddress(); + llvm::Optional getBaseAddress(); DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) { extractDIEsIfNeeded(ExtractUnitDIEOnly); Index: llvm/include/llvm/DebugInfo/PDB/PDBContext.h =================================================================== --- llvm/include/llvm/DebugInfo/PDB/PDBContext.h +++ llvm/include/llvm/DebugInfo/PDB/PDBContext.h @@ -43,13 +43,13 @@ void dump(raw_ostream &OS, DIDumpOptions DIDumpOpts) override; DILineInfo getLineInfoForAddress( - uint64_t Address, + object::SectionedAddress Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; DILineInfoTable getLineInfoForAddressRange( - uint64_t Address, uint64_t Size, + object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; DIInliningInfo getInliningInfoForAddress( - uint64_t Address, + object::SectionedAddress Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; private: Index: llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h =================================================================== --- llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h +++ llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h @@ -24,13 +24,14 @@ public: virtual ~SymbolizableModule() = default; - virtual DILineInfo symbolizeCode(uint64_t ModuleOffset, + virtual DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const = 0; - virtual DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset, - FunctionNameKind FNKind, - bool UseSymbolTable) const = 0; - virtual DIGlobal symbolizeData(uint64_t ModuleOffset) const = 0; + virtual DIInliningInfo + symbolizeInlinedCode(object::SectionedAddress ModuleOffset, + FunctionNameKind FNKind, bool UseSymbolTable) const = 0; + virtual DIGlobal + symbolizeData(object::SectionedAddress ModuleOffset) const = 0; // Return true if this is a 32-bit x86 PE COFF module. virtual bool isWin32Module() const = 0; Index: llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h =================================================================== --- llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -60,13 +60,14 @@ } Expected symbolizeCode(const std::string &ModuleName, - uint64_t ModuleOffset, + object::SectionedAddress ModuleOffset, StringRef DWPName = ""); - Expected symbolizeInlinedCode(const std::string &ModuleName, - uint64_t ModuleOffset, - StringRef DWPName = ""); + Expected + symbolizeInlinedCode(const std::string &ModuleName, + object::SectionedAddress ModuleOffset, + StringRef DWPName = ""); Expected symbolizeData(const std::string &ModuleName, - uint64_t ModuleOffset); + object::SectionedAddress ModuleOffset); void flush(); static std::string Index: llvm/include/llvm/Object/ObjectFile.h =================================================================== --- llvm/include/llvm/Object/ObjectFile.h +++ llvm/include/llvm/Object/ObjectFile.h @@ -135,6 +135,29 @@ const ObjectFile *getObject() const; }; +struct SectionedAddress { + SectionedAddress() {} + SectionedAddress(uint64_t Addr, uint64_t SectIdx) + : Address(Addr), SectionIndex(SectIdx) {} + + const static uint64_t UndefSection = UINT64_MAX; + + uint64_t Address = 0; + uint64_t SectionIndex = UndefSection; +}; + +static inline bool operator<(const SectionedAddress &LHS, + const SectionedAddress &RHS) { + return std::tie(LHS.SectionIndex, LHS.Address) < + std::tie(RHS.SectionIndex, RHS.Address); +} + +static inline bool operator==(const SectionedAddress &LHS, + const SectionedAddress &RHS) { + return std::tie(LHS.SectionIndex, LHS.Address) == + std::tie(RHS.SectionIndex, RHS.Address); +} + /// This is a value type class that represents a single symbol in the list of /// symbols in the object file. class SymbolRef : public BasicSymbolRef { Index: llvm/lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -268,11 +268,11 @@ } // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5). -static void -dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, - llvm::function_ref(uint32_t)> - LookupPooledAddress, - DIDumpOptions DumpOpts) { +static void dumpRnglistsSection( + raw_ostream &OS, DWARFDataExtractor &rnglistData, + llvm::function_ref(uint32_t)> + LookupPooledAddress, + DIDumpOptions DumpOpts) { uint32_t Offset = 0; while (rnglistData.isValidOffset(Offset)) { llvm::DWARFDebugRnglistTable Rnglists; @@ -938,6 +938,8 @@ return Result; } +/// TODO: change input parameter from "uint64_t Address" +/// into "SectionedAddress Address" static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, @@ -966,36 +968,37 @@ return FoundResult; } -DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, +DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Spec) { DILineInfo Result; - DWARFCompileUnit *CU = getCompileUnitForAddress(Address); + DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); if (!CU) return Result; - getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, - Result.FunctionName, - Result.StartLine); + + getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, + Result.FunctionName, Result.StartLine); if (Spec.FLIKind != FileLineInfoKind::None) { - if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) - LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), + if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) { + object::SectionedAddress Addr = {Address.Address, Address.SectionIndex}; + LineTable->getFileLineInfoForAddress(Addr, CU->getCompilationDir(), Spec.FLIKind, Result); + } } return Result; } -DILineInfoTable -DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, - DILineInfoSpecifier Spec) { +DILineInfoTable DWARFContext::getLineInfoForAddressRange( + object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) { DILineInfoTable Lines; - DWARFCompileUnit *CU = getCompileUnitForAddress(Address); + DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); if (!CU) return Lines; std::string FunctionName = ""; uint32_t StartLine = 0; - getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName, - StartLine); + getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, + FunctionName, StartLine); // If the Specifier says we don't need FileLineInfo, just // return the top-most function at the starting address. @@ -1003,7 +1006,7 @@ DILineInfo Result; Result.FunctionName = FunctionName; Result.StartLine = StartLine; - Lines.push_back(std::make_pair(Address, Result)); + Lines.push_back(std::make_pair(Address.Address, Result)); return Lines; } @@ -1011,8 +1014,10 @@ // Get the index of row we're looking for in the line table. std::vector RowVector; - if (!LineTable->lookupAddressRange(Address, Size, RowVector)) + SectionedAddress Addr = {Address.Address, Address.SectionIndex}; + if (!LineTable->lookupAddressRange(Addr, Size, RowVector)) { return Lines; + } for (uint32_t RowIndex : RowVector) { // Take file number and line/column from the row. @@ -1024,33 +1029,33 @@ Result.Line = Row.Line; Result.Column = Row.Column; Result.StartLine = StartLine; - Lines.push_back(std::make_pair(Row.Address, Result)); + Lines.push_back(std::make_pair(Row.Address.Address, Result)); } return Lines; } DIInliningInfo -DWARFContext::getInliningInfoForAddress(uint64_t Address, +DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Spec) { DIInliningInfo InliningInfo; - DWARFCompileUnit *CU = getCompileUnitForAddress(Address); + DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); if (!CU) return InliningInfo; const DWARFLineTable *LineTable = nullptr; SmallVector InlinedChain; - CU->getInlinedChainForAddress(Address, InlinedChain); + CU->getInlinedChainForAddress(Address.Address, InlinedChain); if (InlinedChain.size() == 0) { // If there is no DIE for address (e.g. it is in unavailable .dwo file), // try to at least get file/line info from symbol table. if (Spec.FLIKind != FileLineInfoKind::None) { DILineInfo Frame; LineTable = getLineTableForUnit(CU); - if (LineTable && - LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), - Spec.FLIKind, Frame)) + object::SectionedAddress Addr = {Address.Address, Address.SectionIndex}; + if (LineTable && LineTable->getFileLineInfoForAddress( + Addr, CU->getCompilationDir(), Spec.FLIKind, Frame)) InliningInfo.addFrame(Frame); } return InliningInfo; @@ -1070,9 +1075,11 @@ // For the topmost frame, initialize the line table of this // compile unit and fetch file/line info from it. LineTable = getLineTableForUnit(CU); + object::SectionedAddress Addr = {Address.Address, Address.SectionIndex}; + // For the topmost routine, get file/line info from line table. if (LineTable) - LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), + LineTable->getFileLineInfoForAddress(Addr, CU->getCompilationDir(), Spec.FLIKind, Frame); } else { // Otherwise, use call file, call line and call column from Index: llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @@ -15,7 +15,7 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, uint64_t *SecNdx) const { if (SecNdx) - *SecNdx = -1ULL; + *SecNdx = object::SectionedAddress::UndefSection; if (!Section) return getUnsigned(Off, Size); Optional Rel = Obj->find(*Section, *Off); Index: llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -353,7 +353,8 @@ } void DWARFDebugLine::Row::reset(bool DefaultIsStmt) { - Address = 0; + Address.Address = 0; + Address.SectionIndex = object::SectionedAddress::UndefSection; Line = 1; Column = 0; File = 1; @@ -373,7 +374,7 @@ } void DWARFDebugLine::Row::dump(raw_ostream &OS) const { - OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column) + OS << format("0x%16.16" PRIx64 " %6u %6u", Address.Address, Line, Column) << format(" %6u %3u %13u ", File, Isa, Discriminator) << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "") << (PrologueEnd ? " prologue_end" : "") @@ -386,6 +387,7 @@ void DWARFDebugLine::Sequence::reset() { LowPC = 0; HighPC = 0; + SectionIndex = object::SectionedAddress::UndefSection; FirstRowIndex = 0; LastRowIndex = 0; Empty = true; @@ -426,15 +428,16 @@ if (Sequence.Empty) { // Record the beginning of instruction sequence. Sequence.Empty = false; - Sequence.LowPC = Row.Address; + Sequence.LowPC = Row.Address.Address; Sequence.FirstRowIndex = RowNumber; } ++RowNumber; LineTable->appendRow(Row); if (Row.EndSequence) { // Record the end of instruction sequence. - Sequence.HighPC = Row.Address; + Sequence.HighPC = Row.Address.Address; Sequence.LastRowIndex = RowNumber; + Sequence.SectionIndex = Row.Address.SectionIndex; if (Sequence.isValid()) LineTable->appendSequence(Sequence); Sequence.reset(); @@ -565,9 +568,10 @@ ExtOffset, DebugLineData.getAddressSize(), Len - 1); } - State.Row.Address = DebugLineData.getRelocatedAddress(OffsetPtr); + State.Row.Address.Address = DebugLineData.getRelocatedAddress( + OffsetPtr, &State.Row.Address.SectionIndex); if (OS) - *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address); + *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address); break; case DW_LNE_define_file: @@ -654,7 +658,7 @@ { uint64_t AddrOffset = DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength; - State.Row.Address += AddrOffset; + State.Row.Address.Address += AddrOffset; if (OS) *OS << " (" << AddrOffset << ")"; } @@ -712,7 +716,7 @@ uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase; uint64_t AddrOffset = (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength; - State.Row.Address += AddrOffset; + State.Row.Address.Address += AddrOffset; if (OS) *OS << format(" (0x%16.16" PRIx64 ")", AddrOffset); @@ -731,7 +735,7 @@ // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. { uint16_t PCOffset = DebugLineData.getU16(OffsetPtr); - State.Row.Address += PCOffset; + State.Row.Address.Address += PCOffset; if (OS) *OS << format(" (0x%16.16" PRIx64 ")", PCOffset); @@ -814,7 +818,7 @@ int32_t LineOffset = Prologue.LineBase + (AdjustOpcode % Prologue.LineRange); State.Row.Line += LineOffset; - State.Row.Address += AddrOffset; + State.Row.Address.Address += AddrOffset; if (OS) { *OS << "address += " << AddrOffset << ", line += " << LineOffset @@ -850,11 +854,12 @@ return Error::success(); } -uint32_t -DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq, - uint64_t Address) const { +uint32_t DWARFDebugLine::LineTable::findRowInSeq( + const DWARFDebugLine::Sequence &Seq, + object::SectionedAddress Address) const { if (!Seq.containsPC(Address)) return UnknownRowIndex; + assert(Seq.SectionIndex == Address.SectionIndex); // Search for instruction address in the rows describing the sequence. // Rows are stored in a vector, so we may use arithmetical operations with // iterators. @@ -867,8 +872,9 @@ if (RowPos == LastRow) { return Seq.LastRowIndex - 1; } + assert(Seq.SectionIndex == RowPos->Address.SectionIndex); uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow); - if (RowPos->Address > Address) { + if (RowPos->Address.Address > Address.Address) { if (RowPos == FirstRow) return UnknownRowIndex; else @@ -877,42 +883,87 @@ return Index; } -uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const { +uint32_t DWARFDebugLine::LineTable::lookupAddress( + object::SectionedAddress Address) const { + + // Search for relocatable addresses + uint32_t Result = lookupAddressImpl(Address); + + if (Result == UnknownRowIndex) { + if (Address.SectionIndex != object::SectionedAddress::UndefSection) { + // Search for absolute addresses + Address.SectionIndex = object::SectionedAddress::UndefSection; + + Result = lookupAddressImpl(Address); + } + } + + return Result; +} + +uint32_t DWARFDebugLine::LineTable::lookupAddressImpl( + object::SectionedAddress Address) const { if (Sequences.empty()) return UnknownRowIndex; // First, find an instruction sequence containing the given address. DWARFDebugLine::Sequence Sequence; - Sequence.LowPC = Address; + Sequence.SectionIndex = Address.SectionIndex; + Sequence.LowPC = Address.Address; SequenceIter FirstSeq = Sequences.begin(); SequenceIter LastSeq = Sequences.end(); SequenceIter SeqPos = std::lower_bound( FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC); DWARFDebugLine::Sequence FoundSeq; + if (SeqPos == LastSeq) { FoundSeq = Sequences.back(); - } else if (SeqPos->LowPC == Address) { + } else if (SeqPos->LowPC == Address.Address && + SeqPos->SectionIndex == Address.SectionIndex) { FoundSeq = *SeqPos; } else { if (SeqPos == FirstSeq) return UnknownRowIndex; FoundSeq = *(SeqPos - 1); } + if (FoundSeq.SectionIndex != Address.SectionIndex) + return UnknownRowIndex; return findRowInSeq(FoundSeq, Address); } bool DWARFDebugLine::LineTable::lookupAddressRange( - uint64_t Address, uint64_t Size, std::vector &Result) const { + object::SectionedAddress Address, uint64_t Size, + std::vector &Result) const { + + // Search for relocatable addresses + bool AddressFound = lookupAddressRangeImpl(Address, Size, Result); + + if (!AddressFound) { + if (Address.SectionIndex != object::SectionedAddress::UndefSection) { + // Search for absolute addresses + Address.SectionIndex = object::SectionedAddress::UndefSection; + + AddressFound = lookupAddressRangeImpl(Address, Size, Result); + } + } + + return AddressFound; +} + +bool DWARFDebugLine::LineTable::lookupAddressRangeImpl( + object::SectionedAddress Address, uint64_t Size, + std::vector &Result) const { if (Sequences.empty()) return false; - uint64_t EndAddr = Address + Size; + uint64_t EndAddr = Address.Address + Size; // First, find an instruction sequence containing the given address. DWARFDebugLine::Sequence Sequence; - Sequence.LowPC = Address; + Sequence.SectionIndex = Address.SectionIndex; + Sequence.LowPC = Address.Address; SequenceIter FirstSeq = Sequences.begin(); SequenceIter LastSeq = Sequences.end(); SequenceIter SeqPos = std::lower_bound( FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC); - if (SeqPos == LastSeq || SeqPos->LowPC != Address) { + if (SeqPos == LastSeq || !SeqPos->containsPC(Address)) { if (SeqPos == FirstSeq) return false; SeqPos--; @@ -934,7 +985,8 @@ FirstRowIndex = findRowInSeq(CurSeq, Address); // Figure out the last row in the range. - uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1); + object::SectionedAddress LastAddress = {EndAddr - 1, Address.SectionIndex}; + uint32_t LastRowIndex = findRowInSeq(CurSeq, LastAddress); if (LastRowIndex == UnknownRowIndex) LastRowIndex = CurSeq.LastRowIndex - 1; @@ -1011,12 +1063,13 @@ } bool DWARFDebugLine::LineTable::getFileLineInfoForAddress( - uint64_t Address, const char *CompDir, FileLineInfoKind Kind, - DILineInfo &Result) const { + object::SectionedAddress Address, const char *CompDir, + FileLineInfoKind Kind, DILineInfo &Result) const { // Get the index of row we're looking for in the line table. uint32_t RowIndex = lookupAddress(Address); - if (RowIndex == -1U) + if (RowIndex == -1U) { return false; + } // Take file number and line/column from the row. const auto &Row = Rows[RowIndex]; if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName)) Index: llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -68,7 +68,7 @@ } DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( - llvm::Optional BaseAddr) const { + llvm::Optional BaseAddr) const { DWARFAddressRangesVector Res; for (const RangeListEntry &RLE : Entries) { if (RLE.isBaseAddressSelectionEntry(AddressSize)) { Index: llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp @@ -112,9 +112,8 @@ return Error::success(); } -DWARFAddressRangesVector -DWARFDebugRnglist::getAbsoluteRanges(llvm::Optional BaseAddr, - DWARFUnit &U) const { +DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( + llvm::Optional BaseAddr, DWARFUnit &U) const { DWARFAddressRangesVector Res; for (const RangeListEntry &RLE : Entries) { if (RLE.EntryKind == dwarf::DW_RLE_end_of_list) @@ -174,7 +173,7 @@ void RangeListEntry::dump( raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength, uint64_t &CurrentBase, DIDumpOptions DumpOpts, - llvm::function_ref(uint32_t)> + llvm::function_ref(uint32_t)> LookupPooledAddress) const { auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry, uint8_t AddrSize, DIDumpOptions DumpOpts) { Index: llvm/lib/DebugInfo/DWARF/DWARFDie.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -100,7 +100,7 @@ auto LL = DebugLoc.parseOneLocationList(Data, &Offset); if (LL) { uint64_t BaseAddr = 0; - if (Optional BA = U->getBaseAddress()) + if (Optional BA = U->getBaseAddress()) BaseAddr = BA->Address; LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, BaseAddr, Indent); @@ -125,7 +125,7 @@ Data, &Offset, UseLocLists ? U->getVersion() : 4); uint64_t BaseAddr = 0; - if (Optional BA = U->getBaseAddress()) + if (Optional BA = U->getBaseAddress()) BaseAddr = BA->Address; if (LL) Index: llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -332,7 +332,7 @@ void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts, - SectionedAddress SA) const { + object::SectionedAddress SA) const { OS << format("0x%016" PRIx64, SA.Address); dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts, SA.SectionIndex); @@ -369,7 +369,7 @@ case DW_FORM_addrx3: case DW_FORM_addrx4: case DW_FORM_GNU_addr_index: { - Optional A = U->getAddrOffsetSectionItem(UValue); + Optional A = U->getAddrOffsetSectionItem(UValue); if (!A || DumpOpts.Verbose) AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue); if (U == nullptr) @@ -590,14 +590,15 @@ return SA->Address; return None; } -Optional DWARFFormValue::getAsSectionedAddress() const { +Optional +DWARFFormValue::getAsSectionedAddress() const { if (!isFormClass(FC_Address)) return None; if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx) { uint32_t Index = Value.uval; if (!U) return None; - Optional SA = U->getAddrOffsetSectionItem(Index); + Optional SA = U->getAddrOffsetSectionItem(Index); if (!SA) return None; return SA; Index: llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -197,7 +197,7 @@ getAddressByteSize()); } -Optional +Optional DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const { if (IsDWO) { auto R = Context.info_section_units(); @@ -744,7 +744,7 @@ return Abbrevs; } -llvm::Optional DWARFUnit::getBaseAddress() { +llvm::Optional DWARFUnit::getBaseAddress() { if (BaseAddr) return BaseAddr; Index: llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -772,7 +772,7 @@ uint32_t RowIndex = 0; for (const auto &Row : LineTable->Rows) { // Verify row address. - if (Row.Address < PrevAddress) { + if (Row.Address.Address < PrevAddress) { ++NumDebugLineErrors; error() << ".debug_line[" << format("0x%08" PRIx64, @@ -802,7 +802,7 @@ if (Row.EndSequence) PrevAddress = 0; else - PrevAddress = Row.Address; + PrevAddress = Row.Address.Address; ++RowIndex; } } Index: llvm/lib/DebugInfo/PDB/PDBContext.cpp =================================================================== --- llvm/lib/DebugInfo/PDB/PDBContext.cpp +++ llvm/lib/DebugInfo/PDB/PDBContext.cpp @@ -30,14 +30,14 @@ void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){} -DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address, +DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier) { DILineInfo Result; - Result.FunctionName = getFunctionName(Address, Specifier.FNKind); + Result.FunctionName = getFunctionName(Address.Address, Specifier.FNKind); uint32_t Length = 1; std::unique_ptr Symbol = - Session->findSymbolByAddress(Address, PDB_SymType::None); + Session->findSymbolByAddress(Address.Address, PDB_SymType::None); if (auto Func = dyn_cast_or_null(Symbol.get())) { Length = Func->getLength(); } else if (auto Data = dyn_cast_or_null(Symbol.get())) { @@ -46,7 +46,7 @@ // If we couldn't find a symbol, then just assume 1 byte, so that we get // only the line number of the first instruction. - auto LineNumbers = Session->findLineNumbersByAddress(Address, Length); + auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Length); if (!LineNumbers || LineNumbers->getChildCount() == 0) return Result; @@ -63,26 +63,27 @@ } DILineInfoTable -PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, +PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address, + uint64_t Size, DILineInfoSpecifier Specifier) { if (Size == 0) return DILineInfoTable(); DILineInfoTable Table; - auto LineNumbers = Session->findLineNumbersByAddress(Address, Size); + auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Size); if (!LineNumbers || LineNumbers->getChildCount() == 0) return Table; while (auto LineInfo = LineNumbers->getNext()) { - DILineInfo LineEntry = - getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier); + DILineInfo LineEntry = getLineInfoForAddress( + {LineInfo->getVirtualAddress(), Address.SectionIndex}, Specifier); Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry)); } return Table; } DIInliningInfo -PDBContext::getInliningInfoForAddress(uint64_t Address, +PDBContext::getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier) { DIInliningInfo InlineInfo; DILineInfo Frame = getLineInfoForAddress(Address, Specifier); Index: llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h =================================================================== --- llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h +++ llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h @@ -33,12 +33,13 @@ static ErrorOr> create(object::ObjectFile *Obj, std::unique_ptr DICtx); - DILineInfo symbolizeCode(uint64_t ModuleOffset, FunctionNameKind FNKind, + DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset, + FunctionNameKind FNKind, bool UseSymbolTable) const override; - DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset, + DIInliningInfo symbolizeInlinedCode(object::SectionedAddress ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const override; - DIGlobal symbolizeData(uint64_t ModuleOffset) const override; + DIGlobal symbolizeData(object::SectionedAddress ModuleOffset) const override; // Return true if this is a 32-bit x86 PE COFF module. bool isWin32Module() const override; Index: llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp =================================================================== --- llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp +++ llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp @@ -217,9 +217,10 @@ isa(DebugInfoContext.get()); } -DILineInfo SymbolizableObjectFile::symbolizeCode(uint64_t ModuleOffset, - FunctionNameKind FNKind, - bool UseSymbolTable) const { +DILineInfo +SymbolizableObjectFile::symbolizeCode(object::SectionedAddress ModuleOffset, + FunctionNameKind FNKind, + bool UseSymbolTable) const { DILineInfo LineInfo; if (DebugInfoContext) { LineInfo = DebugInfoContext->getLineInfoForAddress( @@ -229,7 +230,7 @@ if (shouldOverrideWithSymbolTable(FNKind, UseSymbolTable)) { std::string FunctionName; uint64_t Start, Size; - if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, + if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address, FunctionName, Start, Size)) { LineInfo.FunctionName = FunctionName; } @@ -238,7 +239,8 @@ } DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode( - uint64_t ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const { + object::SectionedAddress ModuleOffset, FunctionNameKind FNKind, + bool UseSymbolTable) const { DIInliningInfo InlinedContext; if (DebugInfoContext) @@ -252,7 +254,7 @@ if (shouldOverrideWithSymbolTable(FNKind, UseSymbolTable)) { std::string FunctionName; uint64_t Start, Size; - if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, + if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address, FunctionName, Start, Size)) { InlinedContext.getMutableFrame(InlinedContext.getNumberOfFrames() - 1) ->FunctionName = FunctionName; @@ -262,9 +264,10 @@ return InlinedContext; } -DIGlobal SymbolizableObjectFile::symbolizeData(uint64_t ModuleOffset) const { +DIGlobal SymbolizableObjectFile::symbolizeData( + object::SectionedAddress ModuleOffset) const { DIGlobal Res; - getNameFromSymbolTable(SymbolRef::ST_Data, ModuleOffset, Res.Name, Res.Start, - Res.Size); + getNameFromSymbolTable(SymbolRef::ST_Data, ModuleOffset.Address, Res.Name, + Res.Start, Res.Size); return Res; } Index: llvm/lib/DebugInfo/Symbolize/Symbolize.cpp =================================================================== --- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -52,7 +52,8 @@ Expected LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, - uint64_t ModuleOffset, StringRef DWPName) { + object::SectionedAddress ModuleOffset, + StringRef DWPName) { SymbolizableModule *Info; if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName)) Info = InfoOrErr.get(); @@ -67,7 +68,7 @@ // If the user is giving us relative addresses, add the preferred base of the // object to the offset before we do the query. It's what DIContext expects. if (Opts.RelativeAddresses) - ModuleOffset += Info->getModulePreferredBase(); + ModuleOffset.Address += Info->getModulePreferredBase(); DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts.PrintFunctions, Opts.UseSymbolTable); @@ -78,7 +79,8 @@ Expected LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName, - uint64_t ModuleOffset, StringRef DWPName) { + object::SectionedAddress ModuleOffset, + StringRef DWPName) { SymbolizableModule *Info; if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName)) Info = InfoOrErr.get(); @@ -93,7 +95,7 @@ // If the user is giving us relative addresses, add the preferred base of the // object to the offset before we do the query. It's what DIContext expects. if (Opts.RelativeAddresses) - ModuleOffset += Info->getModulePreferredBase(); + ModuleOffset.Address += Info->getModulePreferredBase(); DIInliningInfo InlinedContext = Info->symbolizeInlinedCode( ModuleOffset, Opts.PrintFunctions, Opts.UseSymbolTable); @@ -106,8 +108,9 @@ return InlinedContext; } -Expected LLVMSymbolizer::symbolizeData(const std::string &ModuleName, - uint64_t ModuleOffset) { +Expected +LLVMSymbolizer::symbolizeData(const std::string &ModuleName, + object::SectionedAddress ModuleOffset) { SymbolizableModule *Info; if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName)) Info = InfoOrErr.get(); @@ -123,7 +126,7 @@ // the object to the offset before we do the query. It's what DIContext // expects. if (Opts.RelativeAddresses) - ModuleOffset += Info->getModulePreferredBase(); + ModuleOffset.Address += Info->getModulePreferredBase(); DIGlobal Global = Info->symbolizeData(ModuleOffset); if (Opts.Demangle) Index: llvm/test/tools/llvm-objdump/Inputs/function-sections-line-numbers.cpp =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objdump/Inputs/function-sections-line-numbers.cpp @@ -0,0 +1,2 @@ +void f1() {} +void f2() {} Index: llvm/test/tools/llvm-objdump/function-sections-line-numbers.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objdump/function-sections-line-numbers.test @@ -0,0 +1,10 @@ +# RUN: clang -ffunction-sections -gdwarf-5 -O -c %p/Inputs/function-sections-line-numbers.cpp -o %t.o +# RUN: llvm-objdump -disassemble -line-numbers -r -s -section-headers -t %t.o | FileCheck %s + + +# CHECK: 0000000000000000 _Z2f1v +# CHECK-NOT: function-sections-line-numbers.cpp:2 +# CHECK: function-sections-line-numbers.cpp:1 +# CHECK-NOT: function-sections-line-numbers.cpp:2 +# CHECK: 0000000000000000 _Z2f2v +# CHECK: function-sections-line-numbers.cpp:2 Index: llvm/tools/dsymutil/DwarfLinker.cpp =================================================================== --- llvm/tools/dsymutil/DwarfLinker.cpp +++ llvm/tools/dsymutil/DwarfLinker.cpp @@ -1734,17 +1734,17 @@ // it is marked as end_sequence in the input (because in that // case, the relocation offset is accurate and that entry won't // serve as the start of another function). - if (CurrRange == InvalidRange || Row.Address < CurrRange.start() || - Row.Address > CurrRange.stop() || - (Row.Address == CurrRange.stop() && !Row.EndSequence)) { + if (CurrRange == InvalidRange || Row.Address.Address < CurrRange.start() || + Row.Address.Address > CurrRange.stop() || + (Row.Address.Address == CurrRange.stop() && !Row.EndSequence)) { // We just stepped out of a known range. Insert a end_sequence // corresponding to the end of the range. uint64_t StopAddress = CurrRange != InvalidRange ? CurrRange.stop() + CurrRange.value() : -1ULL; - CurrRange = FunctionRanges.find(Row.Address); + CurrRange = FunctionRanges.find(Row.Address.Address); bool CurrRangeValid = - CurrRange != InvalidRange && CurrRange.start() <= Row.Address; + CurrRange != InvalidRange && CurrRange.start() <= Row.Address.Address; if (!CurrRangeValid) { CurrRange = InvalidRange; if (StopAddress != -1ULL) { @@ -1754,13 +1754,13 @@ // for now do as dsymutil. // FIXME: Understand exactly what cases this addresses and // potentially remove it along with the Ranges map. - auto Range = Ranges.lower_bound(Row.Address); + auto Range = Ranges.lower_bound(Row.Address.Address); if (Range != Ranges.begin() && Range != Ranges.end()) --Range; - if (Range != Ranges.end() && Range->first <= Row.Address && - Range->second.HighPC >= Row.Address) { - StopAddress = Row.Address + Range->second.Offset; + if (Range != Ranges.end() && Range->first <= Row.Address.Address && + Range->second.HighPC >= Row.Address.Address) { + StopAddress = Row.Address.Address + Range->second.Offset; } } } @@ -1768,7 +1768,7 @@ // Insert end sequence row with the computed end address, but // the same line as the previous one. auto NextLine = Seq.back(); - NextLine.Address = StopAddress; + NextLine.Address.Address = StopAddress; NextLine.EndSequence = 1; NextLine.PrologueEnd = 0; NextLine.BasicBlock = 0; @@ -1786,7 +1786,7 @@ continue; // Relocate row address and add it to the current sequence. - Row.Address += CurrRange.value(); + Row.Address.Address += CurrRange.value(); Seq.emplace_back(Row); if (Row.EndSequence) Index: llvm/tools/dsymutil/DwarfStreamer.cpp =================================================================== --- llvm/tools/dsymutil/DwarfStreamer.cpp +++ llvm/tools/dsymutil/DwarfStreamer.cpp @@ -480,11 +480,11 @@ MS->EmitIntValue(dwarf::DW_LNS_extended_op, 1); MS->EmitULEB128IntValue(PointerSize + 1); MS->EmitIntValue(dwarf::DW_LNE_set_address, 1); - MS->EmitIntValue(Row.Address, PointerSize); + MS->EmitIntValue(Row.Address.Address, PointerSize); LineSectionSize += 2 + PointerSize + getULEB128Size(PointerSize + 1); AddressDelta = 0; } else { - AddressDelta = (Row.Address - Address) / MinInstLength; + AddressDelta = (Row.Address.Address - Address) / MinInstLength; } // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable. @@ -540,7 +540,7 @@ MS->EmitBytes(EncodingOS.str()); LineSectionSize += EncodingBuffer.size(); EncodingBuffer.resize(0); - Address = Row.Address; + Address = Row.Address.Address; LastLine = Row.Line; RowsSinceLastSequence++; } else { Index: llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h =================================================================== --- llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h +++ llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h @@ -139,14 +139,15 @@ bool usesRegisterOperand(const Instr &InstrMeta) const; // Returns the list of indirect instructions. - const std::set &getIndirectInstructions() const; + const std::set &getIndirectInstructions() const; const MCRegisterInfo *getRegisterInfo() const; const MCInstrInfo *getMCInstrInfo() const; const MCInstrAnalysis *getMCInstrAnalysis() const; // Returns the inlining information for the provided address. - Expected symbolizeInlinedCode(uint64_t Address); + Expected + symbolizeInlinedCode(object::SectionedAddress Address); // Returns whether the provided Graph represents a protected indirect control // flow instruction in this file. @@ -178,7 +179,7 @@ // Disassemble and parse the provided bytes into this object. Instruction // address calculation is done relative to the provided SectionAddress. void parseSectionContents(ArrayRef SectionBytes, - uint64_t SectionAddress); + uint64_t SectionIndex, uint64_t SectionAddress); // Constructs and initialises members required for disassembly. Error initialiseDisassemblyMembers(); @@ -225,7 +226,7 @@ DenseMap> StaticBranchTargetings; // A list of addresses of indirect control flow instructions. - std::set IndirectInstructions; + std::set IndirectInstructions; // The addresses of functions that will trap on CFI violations. SmallSet TrapOnFailFunctionAddresses; Index: llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp =================================================================== --- llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp +++ llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp @@ -254,7 +254,8 @@ return CFCrossReferences; } -const std::set &FileAnalysis::getIndirectInstructions() const { +const std::set & +FileAnalysis::getIndirectInstructions() const { return IndirectInstructions; } @@ -268,8 +269,10 @@ return MIA.get(); } -Expected FileAnalysis::symbolizeInlinedCode(uint64_t Address) { +Expected +FileAnalysis::symbolizeInlinedCode(object::SectionedAddress Address) { assert(Symbolizer != nullptr && "Symbolizer is invalid."); + return Symbolizer->symbolizeInlinedCode(Object->getFileName(), Address); } @@ -457,12 +460,14 @@ ArrayRef SectionBytes((const uint8_t *)SectionContents.data(), Section.getSize()); - parseSectionContents(SectionBytes, Section.getAddress()); + parseSectionContents(SectionBytes, Section.getIndex(), + Section.getAddress()); } return Error::success(); } void FileAnalysis::parseSectionContents(ArrayRef SectionBytes, + uint64_t SectionIndex, uint64_t SectionAddress) { assert(Symbolizer && "Symbolizer is uninitialised."); MCInst Instruction; @@ -509,8 +514,9 @@ // Check if this instruction exists in the range of the DWARF metadata. if (!IgnoreDWARFFlag) { + object::SectionedAddress ModuleAddress = {VMAddress, SectionIndex}; auto LineInfo = - Symbolizer->symbolizeCode(Object->getFileName(), VMAddress); + Symbolizer->symbolizeCode(Object->getFileName(), ModuleAddress); if (!LineInfo) { handleAllErrors(LineInfo.takeError(), [](const ErrorInfoBase &E) { errs() << "Symbolizer failed to get line: " << E.message() << "\n"; @@ -522,7 +528,9 @@ continue; } - IndirectInstructions.insert(VMAddress); + object::SectionedAddress Address = {VMAddress, SectionIndex}; + + IndirectInstructions.insert(Address); } } Index: llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h =================================================================== --- llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h +++ llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h @@ -102,7 +102,7 @@ // (i.e. the upwards traversal did not make it to a branch node) flows to the // provided node in GraphResult::OrphanedNodes. static GraphResult buildFlowGraph(const FileAnalysis &Analysis, - uint64_t Address); + object::SectionedAddress Address); private: // Implementation function that actually builds the flow graph. Retrieves a Index: llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp =================================================================== --- llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp +++ llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp @@ -93,17 +93,19 @@ } GraphResult GraphBuilder::buildFlowGraph(const FileAnalysis &Analysis, - uint64_t Address) { + object::SectionedAddress Address) { GraphResult Result; - Result.BaseAddress = Address; + Result.BaseAddress = Address.Address; DenseSet OpenedNodes; const auto &IndirectInstructions = Analysis.getIndirectInstructions(); - if (IndirectInstructions.find(Address) == IndirectInstructions.end()) + // check that IndirectInstructions contains specified Address + if (IndirectInstructions.find(Address) == IndirectInstructions.end()) { return Result; + } - buildFlowGraphImpl(Analysis, OpenedNodes, Result, Address, 0); + buildFlowGraphImpl(Analysis, OpenedNodes, Result, Address.Address, 0); return Result; } Index: llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp =================================================================== --- llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp +++ llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp @@ -130,8 +130,8 @@ std::map BlameCounter; - for (uint64_t Address : Analysis.getIndirectInstructions()) { - const auto &InstrMeta = Analysis.getInstructionOrDie(Address); + for (object::SectionedAddress Address : Analysis.getIndirectInstructions()) { + const auto &InstrMeta = Analysis.getInstructionOrDie(Address.Address); GraphResult Graph = GraphBuilder::buildFlowGraph(Analysis, Address); CFIProtectionStatus ProtectionStatus = @@ -153,7 +153,7 @@ auto InliningInfo = Analysis.symbolizeInlinedCode(Address); if (!InliningInfo || InliningInfo->getNumberOfFrames() == 0) { - errs() << "Failed to symbolise " << format_hex(Address, 2) + errs() << "Failed to symbolise " << format_hex(Address.Address, 2) << " with line tables from " << InputFilename << "\n"; exit(EXIT_FAILURE); } @@ -164,9 +164,9 @@ if (!Summarize) { for (uint32_t i = 0; i < InliningInfo->getNumberOfFrames(); ++i) { const auto &Line = InliningInfo->getFrame(i); - outs() << " " << format_hex(Address, 2) << " = " << Line.FileName - << ":" << Line.Line << ":" << Line.Column << " (" - << Line.FunctionName << ")\n"; + outs() << " " << format_hex(Address.Address, 2) << " = " + << Line.FileName << ":" << Line.Line << ":" << Line.Column + << " (" << Line.FunctionName << ")\n"; } } Index: llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp =================================================================== --- llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -379,7 +379,12 @@ /// Handle the --lookup option and dump the DIEs and line info for the given /// address. -static bool lookup(DWARFContext &DICtx, uint64_t Address, raw_ostream &OS) { +/// TODO: specified Address for --lookup option could relate for several +/// different sections(in case not-linked object file). llvm-dwarfdump +/// need to do something with this: extend lookup option with section +/// information or probably display all matched entries, or something else... +static bool lookup(ObjectFile &Obj, DWARFContext &DICtx, uint64_t Address, + raw_ostream &OS) { auto DIEsForAddr = DICtx.getDIEsForAddress(Lookup); if (!DIEsForAddr) @@ -394,7 +399,10 @@ DIEsForAddr.BlockDIE.dump(OS, 4, DumpOpts); } - if (DILineInfo LineInfo = DICtx.getLineInfoForAddress(Lookup)) + // TODO: it is neccessary to set proper SectionIndex here. + object::SectionedAddress ModuleAddress = { + Lookup, object::SectionedAddress::UndefSection}; + if (DILineInfo LineInfo = DICtx.getLineInfoForAddress(ModuleAddress)) LineInfo.dump(OS); return true; @@ -413,7 +421,7 @@ // Handle the --lookup option. if (Lookup) - return lookup(DICtx, Lookup, OS); + return lookup(Obj, DICtx, Lookup, OS); // Handle the --name option. if (!Name.empty()) { Index: llvm/tools/llvm-objdump/MachODump.cpp =================================================================== --- llvm/tools/llvm-objdump/MachODump.cpp +++ llvm/tools/llvm-objdump/MachODump.cpp @@ -7500,7 +7500,7 @@ // Print debug info. if (diContext) { - DILineInfo dli = diContext->getLineInfoForAddress(PC); + DILineInfo dli = diContext->getLineInfoForAddress({PC, SectIdx}); // Print valid line info if it changed. if (dli != lastLine && dli.Line != 0) outs() << "\t## " << dli.FileName << ':' << dli.Line << ':' Index: llvm/tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- llvm/tools/llvm-objdump/llvm-objdump.cpp +++ llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -491,7 +491,8 @@ Symbolizer.reset(new symbolize::LLVMSymbolizer(SymbolizerOpts)); } virtual ~SourcePrinter() = default; - virtual void printSourceLine(raw_ostream &OS, uint64_t Address, + virtual void printSourceLine(raw_ostream &OS, + object::SectionedAddress Address, StringRef Delimiter = "; "); }; @@ -521,7 +522,8 @@ return true; } -void SourcePrinter::printSourceLine(raw_ostream &OS, uint64_t Address, +void SourcePrinter::printSourceLine(raw_ostream &OS, + object::SectionedAddress Address, StringRef Delimiter) { if (!Symbolizer) return; @@ -582,14 +584,15 @@ public: virtual ~PrettyPrinter() = default; virtual void printInst(MCInstPrinter &IP, const MCInst *MI, - ArrayRef Bytes, uint64_t Address, - raw_ostream &OS, StringRef Annot, - MCSubtargetInfo const &STI, SourcePrinter *SP, + ArrayRef Bytes, + object::SectionedAddress Address, raw_ostream &OS, + StringRef Annot, MCSubtargetInfo const &STI, + SourcePrinter *SP, std::vector *Rels = nullptr) { if (SP && (PrintSource || PrintLines)) SP->printSourceLine(OS, Address); if (!NoLeadingAddr) - OS << format("%8" PRIx64 ":", Address); + OS << format("%8" PRIx64 ":", Address.Address); if (!NoShowRawInsn) { OS << "\t"; dumpBytes(Bytes, OS); @@ -616,13 +619,13 @@ } } void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef Bytes, - uint64_t Address, raw_ostream &OS, StringRef Annot, - MCSubtargetInfo const &STI, SourcePrinter *SP, + object::SectionedAddress Address, raw_ostream &OS, + StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP, std::vector *Rels) override { if (SP && (PrintSource || PrintLines)) SP->printSourceLine(OS, Address, ""); if (!MI) { - printLead(Bytes, Address, OS); + printLead(Bytes, Address.Address, OS); OS << " "; return; } @@ -644,9 +647,9 @@ std::vector::const_iterator RelCur = Rels->begin(); std::vector::const_iterator RelEnd = Rels->end(); auto PrintReloc = [&]() -> void { - while ((RelCur != RelEnd) && (RelCur->getOffset() <= Address)) { - if (RelCur->getOffset() == Address) { - printRelocation(*RelCur, Address, 4); + while ((RelCur != RelEnd) && (RelCur->getOffset() <= Address.Address)) { + if (RelCur->getOffset() == Address.Address) { + printRelocation(*RelCur, Address.Address, 4); return; } ++RelCur; @@ -658,7 +661,7 @@ Separator = "\n"; if (SP && (PrintSource || PrintLines)) SP->printSourceLine(OS, Address, ""); - printLead(Bytes, Address, OS); + printLead(Bytes, Address.Address, OS); OS << Preamble; Preamble = " "; StringRef Inst; @@ -676,7 +679,7 @@ OS << " } " << PacketBundle.second; PrintReloc(); Bytes = Bytes.slice(4); - Address += 4; + Address.Address += 4; } } }; @@ -685,8 +688,8 @@ class AMDGCNPrettyPrinter : public PrettyPrinter { public: void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef Bytes, - uint64_t Address, raw_ostream &OS, StringRef Annot, - MCSubtargetInfo const &STI, SourcePrinter *SP, + object::SectionedAddress Address, raw_ostream &OS, + StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP, std::vector *Rels) override { if (SP && (PrintSource || PrintLines)) SP->printSourceLine(OS, Address); @@ -716,7 +719,7 @@ } } - OS << format("// %012" PRIX64 ": ", Address); + OS << format("// %012" PRIX64 ": ", Address.Address); if (Bytes.size() >=4) { for (auto D : makeArrayRef(reinterpret_cast(Bytes.data()), Bytes.size() / sizeof(U32))) @@ -737,13 +740,13 @@ class BPFPrettyPrinter : public PrettyPrinter { public: void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef Bytes, - uint64_t Address, raw_ostream &OS, StringRef Annot, - MCSubtargetInfo const &STI, SourcePrinter *SP, + object::SectionedAddress Address, raw_ostream &OS, + StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP, std::vector *Rels) override { if (SP && (PrintSource || PrintLines)) SP->printSourceLine(OS, Address); if (!NoLeadingAddr) - OS << format("%8" PRId64 ":", Address / 8); + OS << format("%8" PRId64 ":", Address.Address / 8); if (!NoShowRawInsn) { OS << "\t"; dumpBytes(Bytes, OS); @@ -1300,9 +1303,10 @@ if (Size == 0) Size = 1; - PIP.printInst( - *IP, Disassembled ? &Inst : nullptr, Bytes.slice(Index, Size), - SectionAddr + Index + VMAAdjustment, outs(), "", *STI, &SP, &Rels); + PIP.printInst(*IP, Disassembled ? &Inst : nullptr, + Bytes.slice(Index, Size), + {SectionAddr + Index + VMAAdjustment, Section.getIndex()}, + outs(), "", *STI, &SP, &Rels); outs() << CommentStream.str(); Comments.clear(); Index: llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp =================================================================== --- llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -367,6 +367,8 @@ } uint64_t Addr = *AddrOrErr; + object::SectionedAddress Address; + uint64_t Size = P.second; // If we're not using the debug object, compute the address of the // symbol in memory (rather than that in the unrelocated object file) @@ -381,16 +383,22 @@ object::section_iterator Sec = *SecOrErr; StringRef SecName; Sec->getName(SecName); + Address.SectionIndex = Sec->getIndex(); uint64_t SectionLoadAddress = LoadedObjInfo->getSectionLoadAddress(*Sec); if (SectionLoadAddress != 0) Addr += SectionLoadAddress - Sec->getAddress(); + } else { + if (auto SecOrErr = Sym.getSection()) + Address.SectionIndex = SecOrErr.get()->getIndex(); } outs() << "Function: " << *Name << ", Size = " << Size << ", Addr = " << Addr << "\n"; - DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); + Address.Address = Addr; + DILineInfoTable Lines = + Context->getLineInfoForAddressRange(Address, Size); for (auto &D : Lines) { outs() << " Line info @ " << D.first - Addr << ": " << D.second.FileName << ", line:" << D.second.Line << "\n"; Index: llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp =================================================================== --- llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -194,23 +194,54 @@ return !StringRef(pos, offset_length).getAsInteger(0, ModuleOffset); } +// This routine returns section index for an address. +// Assumption: would work ambiguously for object files which have sections not +// assigned to an address(since the same address could belong to various +// sections). +static uint64_t getModuleSectionIndexForAddress(const std::string &ModuleName, + uint64_t Address) { + + Expected> BinaryOrErr = createBinary(ModuleName); + + if (error(BinaryOrErr)) + return object::SectionedAddress::UndefSection; + + Binary &Binary = *BinaryOrErr.get().getBinary(); + + if (ObjectFile *O = dyn_cast(&Binary)) { + for (SectionRef Sec : O->sections()) { + if (!Sec.isText() || Sec.isVirtual()) + continue; + + if (Address >= Sec.getAddress() && + Address <= Sec.getAddress() + Sec.getSize()) { + return Sec.getIndex(); + } + } + } + + return object::SectionedAddress::UndefSection; +} + static void symbolizeInput(StringRef InputString, LLVMSymbolizer &Symbolizer, DIPrinter &Printer) { bool IsData = false; std::string ModuleName; - uint64_t ModuleOffset = 0; - if (!parseCommand(StringRef(InputString), IsData, ModuleName, ModuleOffset)) { + uint64_t Offset = 0; + if (!parseCommand(StringRef(InputString), IsData, ModuleName, Offset)) { outs() << InputString; return; } if (ClPrintAddress) { outs() << "0x"; - outs().write_hex(ModuleOffset); + outs().write_hex(Offset); StringRef Delimiter = ClPrettyPrint ? ": " : "\n"; outs() << Delimiter; } - ModuleOffset -= ClAdjustVMA; + Offset -= ClAdjustVMA; + object::SectionedAddress ModuleOffset = { + Offset, getModuleSectionIndexForAddress(ModuleName, Offset)}; if (IsData) { auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset); Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get()); Index: llvm/tools/llvm-xray/func-id-helper.cpp =================================================================== --- llvm/tools/llvm-xray/func-id-helper.cpp +++ llvm/tools/llvm-xray/func-id-helper.cpp @@ -29,7 +29,11 @@ return F.str(); } - if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, It->second)) { + object::SectionedAddress ModuleAddress; + ModuleAddress.Address = It->second; + // TODO: set proper section index here + ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; + if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress)) { auto &DI = *ResOrErr; if (DI.FunctionName == "") F << "@(" << std::hex << It->second << ")"; @@ -51,7 +55,11 @@ return "(unknown)"; std::ostringstream F; - auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, It->second); + object::SectionedAddress ModuleAddress; + ModuleAddress.Address = It->second; + // TODO: set proper section index here + ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; + auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress); if (!ResOrErr) { consumeError(ResOrErr.takeError()); return "(unknown)"; Index: llvm/tools/sancov/sancov.cpp =================================================================== --- llvm/tools/sancov/sancov.cpp +++ llvm/tools/sancov/sancov.cpp @@ -621,10 +621,15 @@ std::set CoveredFiles; if (ClSkipDeadFiles) { for (auto Addr : CoveredAddrs) { - auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr); + // TODO: it would be neccessary to set proper section index here + object::SectionedAddress ModuleAddress = { + Addr, object::SectionedAddress::UndefSection}; + + auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, ModuleAddress); failIfError(LineInfo); CoveredFiles.insert(LineInfo->FileName); - auto InliningInfo = Symbolizer->symbolizeInlinedCode(ObjectFile, Addr); + auto InliningInfo = + Symbolizer->symbolizeInlinedCode(ObjectFile, ModuleAddress); failIfError(InliningInfo); for (uint32_t I = 0; I < InliningInfo->getNumberOfFrames(); ++I) { auto FrameInfo = InliningInfo->getFrame(I); @@ -636,7 +641,11 @@ for (auto Addr : Addrs) { std::set Infos; // deduplicate debug info. - auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr); + // TODO: it would be neccessary to set proper section index here + object::SectionedAddress ModuleAddress = { + Addr, object::SectionedAddress::UndefSection}; + + auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, ModuleAddress); failIfError(LineInfo); if (ClSkipDeadFiles && CoveredFiles.find(LineInfo->FileName) == CoveredFiles.end()) @@ -650,7 +659,8 @@ Infos.insert(*LineInfo); Point.Locs.push_back(*LineInfo); - auto InliningInfo = Symbolizer->symbolizeInlinedCode(ObjectFile, Addr); + auto InliningInfo = + Symbolizer->symbolizeInlinedCode(ObjectFile, ModuleAddress); failIfError(InliningInfo); for (uint32_t I = 0; I < InliningInfo->getNumberOfFrames(); ++I) { auto FrameInfo = InliningInfo->getFrame(I); @@ -957,7 +967,11 @@ auto Symbolizer(createSymbolizer()); for (uint64_t Addr : *Data.Addrs) { - auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr); + // TODO: it would be neccessary to set proper section index here + object::SectionedAddress ModuleAddress = { + Addr, object::SectionedAddress::UndefSection}; + + auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, ModuleAddress); failIfError(LineInfo); if (B.isBlacklisted(*LineInfo)) continue; Index: llvm/tools/sanstats/sanstats.cpp =================================================================== --- llvm/tools/sanstats/sanstats.cpp +++ llvm/tools/sanstats/sanstats.cpp @@ -81,11 +81,15 @@ if (Begin == End) return nullptr; + object::SectionedAddress ModuleAddress; + ModuleAddress.Address = Addr - 1; + ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; + // As the instrumentation tracks the return address and not // the address of the call to `__sanitizer_stat_report` we // remove one from the address to get the correct DI. if (Expected LineInfo = - Symbolizer.symbolizeCode(Filename, Addr - 1)) { + Symbolizer.symbolizeCode(Filename, ModuleAddress)) { llvm::outs() << format_hex(Addr - 1, 18) << ' ' << LineInfo->FileName << ':' << LineInfo->Line << ' ' << LineInfo->FunctionName << ' '; Index: llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp =================================================================== --- llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp +++ llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp @@ -51,8 +51,9 @@ // Expose this method publicly for testing. void parseSectionContents(ArrayRef SectionBytes, - uint64_t SectionAddress) { - FileAnalysis::parseSectionContents(SectionBytes, SectionAddress); + uint64_t SectionIndex, uint64_t SectionAddress) { + FileAnalysis::parseSectionContents(SectionBytes, SectionIndex, + SectionAddress); } Error initialiseDisassemblyMembers() { @@ -106,7 +107,7 @@ 0x41, 0x0e, // 21: rex.B (bad) 0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1} }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); EXPECT_EQ(nullptr, Analysis.getInstruction(0x0)); EXPECT_EQ(nullptr, Analysis.getInstruction(0x1000)); @@ -210,7 +211,7 @@ 0x2f, // 1: (bad) 0x90 // 2: nop }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); const auto &BadInstrMeta = Analysis.getInstructionOrDie(0xDEADBEEF + 1); const auto *GoodInstrMeta = Analysis.getPrevInstructionSequential(BadInstrMeta); @@ -240,7 +241,7 @@ 0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1} 0x0f, 0x0b // 28: ud2 }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); EXPECT_FALSE(Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF))); EXPECT_FALSE( @@ -275,7 +276,7 @@ 0x75, 0x00, // 17: jne +0 0xc3, // 19: retq }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); EXPECT_TRUE( Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF))); @@ -322,7 +323,7 @@ 0xeb, 0xdd, // 36: jmp 3 [-35] 0xeb, 0xdc, // 38: jmp 4 [-36] }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); const auto *Current = Analysis.getInstruction(0xDEADBEEF); const auto *Next = Analysis.getDefiniteNextInstruction(*Current); @@ -412,7 +413,7 @@ 0xeb, 0xdd, // 36: jmp 3 [-35] 0xeb, 0xdc, // 38: jmp 4 [-36] }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); const auto *InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF); std::set XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); @@ -503,17 +504,18 @@ 0x0f, 0x0b, // 1: ud2 0x75, 0x00, // 3: jne 5 [+0] }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF, Analysis.validateCFIProtection(Result)); - Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1); + Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF, Analysis.validateCFIProtection(Result)); - Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3); + Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF, Analysis.validateCFIProtection(Result)); - Result = GraphBuilder::buildFlowGraph(Analysis, 0x12345678); + Result = GraphBuilder::buildFlowGraph(Analysis, {0x12345678, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_INVALID_INSTRUCTION, Analysis.validateCFIProtection(Result)); } @@ -527,8 +529,9 @@ 0x0f, 0x0b, // 2: ud2 0xff, 0x10, // 4: callq *(%rax) }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -542,8 +545,9 @@ 0xff, 0x10, // 2: callq *(%rax) 0x0f, 0x0b, // 4: ud2 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -560,8 +564,9 @@ 0x75, 0xf9, // 7: jne 2 [-7] 0x0f, 0x0b, // 9: ud2 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -577,8 +582,9 @@ 0x75, 0xfb, // 5: jne 2 [-5] 0x0f, 0x0b, // 7: ud2 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -596,12 +602,13 @@ 0xff, 0x10, // 6: callq *(%rax) 0x0f, 0x0b, // 8: ud2 }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); uint64_t PrevSearchLengthForConditionalBranch = SearchLengthForConditionalBranch; SearchLengthForConditionalBranch = 2; - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS, Analysis.validateCFIProtection(Result)); @@ -621,11 +628,12 @@ 0x90, // 7: nop 0x0f, 0x0b, // 8: ud2 }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; SearchLengthForUndef = 2; - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH, Analysis.validateCFIProtection(Result)); @@ -642,8 +650,9 @@ 0xff, 0x10, // 4: callq *(%rax) 0x0f, 0x0b, // 6: ud2 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS, Analysis.validateCFIProtection(Result)); } @@ -658,8 +667,9 @@ 0xff, 0x10, // 4: callq *(%rax) 0x0f, 0x0b, // 6: ud2 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -685,10 +695,11 @@ 0x90, // 21: nop 0x0f, 0x0b, // 22: ud2 }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; SearchLengthForUndef = 5; - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS, Analysis.validateCFIProtection(Result)); SearchLengthForUndef = PrevSearchLengthForUndef; @@ -704,10 +715,10 @@ 0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130 0x0f, 0x0b, // 0x688127: ud2 }, - 0x688118); + 0x0, 0x688118); uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; SearchLengthForUndef = 1; - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x68811d); + GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x68811d, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); SearchLengthForUndef = PrevSearchLengthForUndef; @@ -719,7 +730,7 @@ 0x74, 0x73, // 0x7759eb: je 0x775a60 0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e }, - 0x7759eb); + 0x0, 0x7759eb); Analysis.parseSectionContents( { @@ -729,24 +740,24 @@ 0x48, 0x89, 0xde, // 0x775a65: mov %rbx,%rsi 0xff, 0xd1, // 0x775a68: callq *%rcx }, - 0x775a56); + 0x0, 0x775a56); Analysis.parseSectionContents( { 0x0f, 0x0b, // 0x775e0e: ud2 }, - 0x775e0e); + 0x0, 0x775e0e); uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; SearchLengthForUndef = 1; - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68); + GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH, Analysis.validateCFIProtection(Result)); SearchLengthForUndef = 2; - Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68); + Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); SearchLengthForUndef = 3; - Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68); + Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); SearchLengthForUndef = PrevSearchLengthForUndef; @@ -762,8 +773,9 @@ 0x48, 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %rax 0xff, 0x10, // 10: callq *(%rax) }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 10); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 10, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } @@ -778,8 +790,9 @@ 0x48, 0x83, 0xc0, 0x00, // 4: add $0x0, %rax 0xff, 0x10, // 8: callq *(%rax) }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } @@ -794,8 +807,9 @@ 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %eax 0xff, 0x10, // 9: callq *(%rax) }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } @@ -812,8 +826,9 @@ 0x75, 0xf9, // 8: jne 2 [-7] 0x0f, 0x0b, // 10: ud2 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } @@ -825,8 +840,9 @@ { 0x00, 0x01, 0x3f, 0xd6, // 0: blr x8 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS, Analysis.validateCFIProtection(Result)); } @@ -840,8 +856,9 @@ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1 0x00, 0x01, 0x3f, 0xd6, // 8: blr x8 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -856,8 +873,9 @@ 0x08, 0x05, 0x00, 0x91, // 8: add x8, x8, #1 0x00, 0x01, 0x3f, 0xd6, // 12: blr x8 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } @@ -872,8 +890,9 @@ 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16] 0x20, 0x00, 0x1f, 0xd6, // 12: br x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -889,8 +908,9 @@ 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16] 0x20, 0x00, 0x1f, 0xd6, // 16: br x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -906,8 +926,9 @@ 0x21, 0x04, 0x00, 0x91, // 12: add x1, x1, #1 0x20, 0x00, 0x1f, 0xd6, // 16: br x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } @@ -923,8 +944,9 @@ 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16] 0x20, 0x00, 0x1f, 0xd6, // 16: br x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } @@ -940,8 +962,9 @@ 0x21, 0x08, 0x40, 0xf9, // 12: ldr x1, [x1,#16] 0x20, 0x00, 0x1f, 0xd6, // 16: br x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } @@ -957,8 +980,9 @@ 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16] 0x20, 0x00, 0x1f, 0xd6, // 16: br x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -974,8 +998,9 @@ 0x22, 0x08, 0x40, 0xf9, // 12: ldr x2, [x1,#16] 0x20, 0x00, 0x1f, 0xd6, // 16: br x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -990,8 +1015,9 @@ 0x20, 0x00, 0x20, 0xd4, // 8: brk #0x1 0x20, 0x00, 0x1f, 0xd6, // 12: br x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS, Analysis.validateCFIProtection(Result)); } @@ -1009,8 +1035,9 @@ 0x20, 0x00, 0x1f, 0xd6, // 20: br x1 0x20, 0x00, 0x20, 0xd4, // 24: brk #0x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 20); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 20, 0x0}); EXPECT_EQ(CFIProtectionStatus::PROTECTED, Analysis.validateCFIProtection(Result)); } @@ -1029,8 +1056,9 @@ 0x20, 0x00, 0x1f, 0xd6, // 24: br x1 0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } @@ -1049,8 +1077,9 @@ 0x20, 0x00, 0x1f, 0xd6, // 24: br x1 0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0}); EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, Analysis.validateCFIProtection(Result)); } Index: llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp =================================================================== --- llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp +++ llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp @@ -113,8 +113,9 @@ // Expose this method publicly for testing. void parseSectionContents(ArrayRef SectionBytes, - uint64_t SectionAddress) { - FileAnalysis::parseSectionContents(SectionBytes, SectionAddress); + uint64_t SectionIndex, uint64_t SectionAddress) { + FileAnalysis::parseSectionContents(SectionBytes, SectionIndex, + SectionAddress); } Error initialiseDisassemblyMembers() { @@ -156,8 +157,9 @@ 0x0f, 0x0b, // 2: ud2 0xff, 0x10, // 4: callq *(%rax) }, - 0xDEADBEEF); - const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); + 0x0, 0xDEADBEEF); + const auto Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1)); @@ -182,8 +184,9 @@ 0xff, 0x10, // 2: callq *(%rax) 0x0f, 0x0b, // 4: ud2 }, - 0xDEADBEEF); - const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2); + 0x0, 0xDEADBEEF); + const auto Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1)); @@ -211,8 +214,9 @@ 0x75, 0xf9, // 7: jne 2 [-7] 0x0f, 0x0b, // 9: ud2 }, - 0xDEADBEEF); - const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3); + 0x0, 0xDEADBEEF); + const auto Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2)); @@ -249,8 +253,9 @@ 0x75, 0xfb, // 5: jne 2 [-5] 0x0f, 0x0b, // 7: ud2 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2)); @@ -284,16 +289,17 @@ 0x90, // 0: nop 0x75, 0xfe, // 1: jne 1 [-2] }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty()); - Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1); + Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty()); - Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADC0DE); + Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADC0DE, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty()); } @@ -306,8 +312,9 @@ 0xeb, 0xfe, // 0: jmp 0 [-2] 0xff, 0x10, // 2: callq *(%rax) }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0}); EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty()); EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 2)); EXPECT_THAT(Result.IntermediateNodes, IsEmpty()); @@ -321,8 +328,9 @@ 0x75, 0xfe, // 0: jne 0 [-2] 0xff, 0x10, // 2: callq *(%rax) }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1)); EXPECT_THAT( @@ -344,8 +352,9 @@ 0xeb, 0xfc, // 2: jmp 0 [-4] 0xff, 0x10, // 4: callq *(%rax) }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1)); EXPECT_THAT( @@ -368,8 +377,9 @@ 0xeb, 0xfc, // 2: jmp 0 [-4] 0xff, 0x10, // 4: callq *(%rax) }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0}); EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 4)); EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty()); } @@ -387,12 +397,13 @@ 0xff, 0x10, // 6: callq *(%rax) 0x0f, 0x0b, // 8: ud2 }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); uint64_t PrevSearchLengthForConditionalBranch = SearchLengthForConditionalBranch; SearchLengthForConditionalBranch = 2; - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0}); EXPECT_THAT(Result.OrphanedNodes, SizeIs(1)); EXPECT_THAT(Result.OrphanedNodes, Each(HasPath(Result, ElementsAre(0xDEADBEEF + 4, 0xDEADBEEF + 5, @@ -416,11 +427,12 @@ 0x90, // 7: nop 0x0f, 0x0b, // 8: ud2 }, - 0xDEADBEEF); + 0x0, 0xDEADBEEF); uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; SearchLengthForUndef = 2; - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT( Result.ConditionalBranchNodes, @@ -450,8 +462,9 @@ 0x75, 0xfb, // 5: jne 2 [-5] 0x0f, 0x0b, // 7: ud2 }, - 0xDEADBEEF); - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3); + 0x0, 0xDEADBEEF); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0}); EXPECT_THAT(Result.OrphanedNodes, IsEmpty()); EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2)); EXPECT_THAT( @@ -529,11 +542,12 @@ 0x90, // 21: nop 0x0f, 0x0b, // 22: ud2 }, - 0x1000); + 0x0, 0x1000); uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; SearchLengthForUndef = 5; - GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x1000 + 9); + GraphResult Result = + GraphBuilder::buildFlowGraph(Analysis, {0x1000 + 9, 0x0}); EXPECT_THAT(Result.OrphanedNodes, SizeIs(1)); EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(3));