summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/InputFiles.cpp15
-rw-r--r--llvm/include/llvm/DebugInfo/DIContext.h11
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h13
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h36
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h2
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h4
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h6
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h4
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h5
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h7
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/PDBContext.h6
-rw-r--r--llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h11
-rw-r--r--llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h11
-rw-r--r--llvm/include/llvm/Object/ObjectFile.h24
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp66
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp94
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp7
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp4
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp9
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp4
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBContext.cpp19
-rw-r--r--llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp21
-rw-r--r--llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h7
-rw-r--r--llvm/lib/DebugInfo/Symbolize/Symbolize.cpp17
-rw-r--r--llvm/test/tools/llvm-objdump/X86/function-sections-line-numbers.s221
-rw-r--r--llvm/tools/dsymutil/DwarfLinker.cpp22
-rw-r--r--llvm/tools/dsymutil/DwarfStreamer.cpp6
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp20
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h9
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp10
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h2
-rw-r--r--llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp12
-rw-r--r--llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp14
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp2
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp50
-rw-r--r--llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp10
-rw-r--r--llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp39
-rw-r--r--llvm/tools/llvm-xray/func-id-helper.cpp14
-rw-r--r--llvm/tools/sancov/sancov.cpp26
-rw-r--r--llvm/tools/sanstats/sanstats.cpp6
-rw-r--r--llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp178
-rw-r--r--llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp73
45 files changed, 796 insertions, 329 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 2f0b5df965b..ed7d0e98e82 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -205,14 +205,25 @@ Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *S,
uint64_t Offset) {
llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); });
+ // Detect SectionIndex for specified section.
+ uint64_t SectionIndex = object::SectionedAddress::UndefSection;
+ ArrayRef<InputSectionBase *> 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) {
if (LT->getFileLineInfoForAddress(
- S->getOffsetInFile() + Offset, nullptr,
+ {S->getOffsetInFile() + Offset, SectionIndex}, nullptr,
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Info))
return Info;
+ }
return None;
}
diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index a41ab21412d..87c47dcf106 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -203,11 +203,14 @@ public:
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:
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index e41592783b1..5d243da7e58 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -317,13 +317,18 @@ public:
/// 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 @@ public:
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);
};
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index 9e40c844466..1f36e0daed0 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -139,12 +139,16 @@ public:
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 @@ public:
/// 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 @@ public:
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 @@ public:
/// 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<uint32_t> &Result) const;
bool hasFileAtIndex(uint64_t FileIndex) const;
@@ -238,7 +250,8 @@ public:
/// 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 @@ public:
private:
uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq,
- uint64_t Address) const;
+ object::SectionedAddress Address) const;
Optional<StringRef>
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<uint32_t> &Result) const;
};
const LineTable *getLineTable(uint32_t Offset) const;
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
index c1c0f420f61..a66f6029234 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
@@ -76,7 +76,7 @@ public:
/// list. Has to be passed base address of the compile unit referencing this
/// range list.
DWARFAddressRangesVector
- getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const;
+ getAbsoluteRanges(llvm::Optional<object::SectionedAddress> BaseAddr) const;
};
} // end namespace llvm
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
index c6661a8bfa0..167ddde3ec3 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
@@ -37,7 +37,7 @@ struct RangeListEntry : public DWARFListEntryBase {
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<Optional<SectionedAddress>(uint32_t)>
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress) const;
bool isSentinel() const { return EntryKind == dwarf::DW_RLE_end_of_list; }
};
@@ -47,7 +47,7 @@ class DWARFDebugRnglist : public DWARFListType<RangeListEntry> {
public:
/// Build a DWARFAddressRangesVector from a rangelist.
DWARFAddressRangesVector
- getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr,
+ getAbsoluteRanges(llvm::Optional<object::SectionedAddress> BaseAddr,
DWARFUnit &U) const;
};
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index 050329464e7..8107624f8a8 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -79,7 +79,7 @@ public:
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);
@@ -108,7 +108,7 @@ public:
Optional<int64_t> getAsSignedConstant() const;
Optional<const char *> getAsCString() const;
Optional<uint64_t> getAsAddress() const;
- Optional<SectionedAddress> getAsSectionedAddress() const;
+ Optional<object::SectionedAddress> getAsSectionedAddress() const;
Optional<uint64_t> getAsSectionOffset() const;
Optional<ArrayRef<uint8_t>> getAsBlock() const;
Optional<uint64_t> getAsCStringOffset() const;
@@ -246,7 +246,7 @@ inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) {
return None;
}
-inline Optional<SectionedAddress>
+inline Optional<object::SectionedAddress>
toSectionedAddress(const Optional<DWARFFormValue> &V) {
if (V)
return V->getAsSectionedAddress();
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
index 6c13db3d87c..a1ea69b040f 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
@@ -157,7 +157,7 @@ public:
uint8_t getAddrSize() const { return Header.getAddrSize(); }
void dump(raw_ostream &OS,
- llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress,
DIDumpOptions DumpOpts = {}) const;
@@ -234,7 +234,7 @@ Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data,
template <typename DWARFListType>
void DWARFListTableBase<DWARFListType>::dump(
raw_ostream &OS,
- llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress,
DIDumpOptions DumpOpts) const {
Header.dump(OS, DumpOpts);
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
index bb0004615d7..054524d368e 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
@@ -22,11 +22,6 @@ struct SectionName {
bool IsNameUnique;
};
-struct SectionedAddress {
- uint64_t Address;
- uint64_t SectionIndex;
-};
-
} // end namespace llvm
#endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index e82ce8ed6c2..86add501508 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -217,7 +217,7 @@ class DWARFUnit {
Optional<DWARFDebugRnglistTable> RngListTable;
mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
- llvm::Optional<SectionedAddress> BaseAddr;
+ llvm::Optional<object::SectionedAddress> BaseAddr;
/// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntry> DieArray;
@@ -304,7 +304,8 @@ public:
RangeSectionBase = Base;
}
- Optional<SectionedAddress> getAddrOffsetSectionItem(uint32_t Index) const;
+ Optional<object::SectionedAddress>
+ getAddrOffsetSectionItem(uint32_t Index) const;
Optional<uint64_t> getStringOffsetSectionItem(uint32_t Index) const;
DWARFDataExtractor getDebugInfoExtractor() const;
@@ -375,7 +376,7 @@ public:
llvm_unreachable("Invalid UnitType.");
}
- llvm::Optional<SectionedAddress> getBaseAddress();
+ llvm::Optional<object::SectionedAddress> getBaseAddress();
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
extractDIEsIfNeeded(ExtractUnitDIEOnly);
diff --git a/llvm/include/llvm/DebugInfo/PDB/PDBContext.h b/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
index e404e07f758..89a7efef7e9 100644
--- a/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
+++ b/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
@@ -43,13 +43,13 @@ namespace pdb {
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:
diff --git a/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h b/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
index f0862d0b85d..2bdfb0942a8 100644
--- a/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
+++ b/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
@@ -24,13 +24,14 @@ class SymbolizableModule {
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;
diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
index 4e57fe43847..3e194ef1a2b 100644
--- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -60,13 +60,14 @@ public:
}
Expected<DILineInfo> symbolizeCode(const std::string &ModuleName,
- uint64_t ModuleOffset,
+ object::SectionedAddress ModuleOffset,
StringRef DWPName = "");
- Expected<DIInliningInfo> symbolizeInlinedCode(const std::string &ModuleName,
- uint64_t ModuleOffset,
- StringRef DWPName = "");
+ Expected<DIInliningInfo>
+ symbolizeInlinedCode(const std::string &ModuleName,
+ object::SectionedAddress ModuleOffset,
+ StringRef DWPName = "");
Expected<DIGlobal> symbolizeData(const std::string &ModuleName,
- uint64_t ModuleOffset);
+ object::SectionedAddress ModuleOffset);
void flush();
static std::string
diff --git a/llvm/include/llvm/Object/ObjectFile.h b/llvm/include/llvm/Object/ObjectFile.h
index f13775c914d..019b5cb5a8c 100644
--- a/llvm/include/llvm/Object/ObjectFile.h
+++ b/llvm/include/llvm/Object/ObjectFile.h
@@ -135,6 +135,30 @@ public:
const ObjectFile *getObject() const;
};
+struct SectionedAddress {
+ // TODO: constructors could be removed when C++14 would be adopted.
+ 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;
+};
+
+inline bool operator<(const SectionedAddress &LHS,
+ const SectionedAddress &RHS) {
+ return std::tie(LHS.SectionIndex, LHS.Address) <
+ std::tie(RHS.SectionIndex, RHS.Address);
+}
+
+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 {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index d06b737b810..dc0539f4634 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -268,11 +268,11 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
}
// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
-static void
-dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData,
- llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
- LookupPooledAddress,
- DIDumpOptions DumpOpts) {
+static void dumpRnglistsSection(
+ raw_ostream &OS, DWARFDataExtractor &rnglistData,
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
+ LookupPooledAddress,
+ DIDumpOptions DumpOpts) {
uint32_t Offset = 0;
while (rnglistData.isValidOffset(Offset)) {
llvm::DWARFDebugRnglistTable Rnglists;
@@ -938,6 +938,8 @@ DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
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 @@ static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
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(),
- Spec.FLIKind, Result);
+ if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
+ LineTable->getFileLineInfoForAddress(
+ {Address.Address, Address.SectionIndex}, 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 = "<invalid>";
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 @@ DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
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 @@ DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
// Get the index of row we're looking for in the line table.
std::vector<uint32_t> RowVector;
- if (!LineTable->lookupAddressRange(Address, Size, RowVector))
+ if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},
+ Size, RowVector)) {
return Lines;
+ }
for (uint32_t RowIndex : RowVector) {
// Take file number and line/column from the row.
@@ -1024,33 +1029,33 @@ DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
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<DWARFDie, 4> 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))
+ if (LineTable && LineTable->getFileLineInfoForAddress(
+ {Address.Address, Address.SectionIndex},
+ CU->getCompilationDir(), Spec.FLIKind, Frame))
InliningInfo.addFrame(Frame);
}
return InliningInfo;
@@ -1072,8 +1077,9 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
LineTable = getLineTableForUnit(CU);
// For the topmost routine, get file/line info from line table.
if (LineTable)
- LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
- Spec.FLIKind, Frame);
+ LineTable->getFileLineInfoForAddress(
+ {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
+ Spec.FLIKind, Frame);
} else {
// Otherwise, use call file, call line and call column from
// previous DIE in inlined chain.
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index 73663f868f0..bd8c23765e4 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -15,7 +15,7 @@ using namespace llvm;
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<RelocAddrEntry> Rel = Obj->find(*Section, *Off);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 406c342cd58..a2c25248618 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -353,7 +353,8 @@ void DWARFDebugLine::Row::postAppend() {
}
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::dumpTableHeader(raw_ostream &OS) {
}
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 @@ DWARFDebugLine::Sequence::Sequence() { reset(); }
void DWARFDebugLine::Sequence::reset() {
LowPC = 0;
HighPC = 0;
+ SectionIndex = object::SectionedAddress::UndefSection;
FirstRowIndex = 0;
LastRowIndex = 0;
Empty = true;
@@ -426,15 +428,16 @@ void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t Offset) {
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 @@ Error DWARFDebugLine::LineTable::parse(
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 @@ Error DWARFDebugLine::LineTable::parse(
{
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 @@ Error DWARFDebugLine::LineTable::parse(
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 @@ Error DWARFDebugLine::LineTable::parse(
// 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 @@ Error DWARFDebugLine::LineTable::parse(
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 @@ Error DWARFDebugLine::LineTable::parse(
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 @@ DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq,
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,81 @@ DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq,
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 ||
+ Address.SectionIndex == object::SectionedAddress::UndefSection)
+ return Result;
+
+ // Search for absolute addresses
+ Address.SectionIndex = object::SectionedAddress::UndefSection;
+ return lookupAddressImpl(Address);
+}
+
+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<uint32_t> &Result) const {
+ object::SectionedAddress Address, uint64_t Size,
+ std::vector<uint32_t> &Result) const {
+
+ // Search for relocatable addresses
+ if (lookupAddressRangeImpl(Address, Size, Result))
+ return true;
+
+ if (Address.SectionIndex == object::SectionedAddress::UndefSection)
+ return false;
+
+ // Search for absolute addresses
+ Address.SectionIndex = object::SectionedAddress::UndefSection;
+ return lookupAddressRangeImpl(Address, Size, Result);
+}
+
+bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
+ object::SectionedAddress Address, uint64_t Size,
+ std::vector<uint32_t> &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 +979,8 @@ bool DWARFDebugLine::LineTable::lookupAddressRange(
FirstRowIndex = findRowInSeq(CurSeq, Address);
// Figure out the last row in the range.
- uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1);
+ uint32_t LastRowIndex =
+ findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex});
if (LastRowIndex == UnknownRowIndex)
LastRowIndex = CurSeq.LastRowIndex - 1;
@@ -1011,8 +1057,8 @@ bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
}
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)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index 31193b563a5..d8df81a0aa0 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -68,7 +68,7 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const {
}
DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
- llvm::Optional<SectionedAddress> BaseAddr) const {
+ llvm::Optional<object::SectionedAddress> BaseAddr) const {
DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 2e4babac6c7..af1924a4966 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -112,9 +112,8 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
return Error::success();
}
-DWARFAddressRangesVector
-DWARFDebugRnglist::getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr,
- DWARFUnit &U) const {
+DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
+ llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const {
DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
@@ -174,7 +173,7 @@ DWARFDebugRnglist::getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr,
void RangeListEntry::dump(
raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
uint64_t &CurrentBase, DIDumpOptions DumpOpts,
- llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress) const {
auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry,
uint8_t AddrSize, DIDumpOptions DumpOpts) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 32546fd7613..d1396887645 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -100,7 +100,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
if (LL) {
uint64_t BaseAddr = 0;
- if (Optional<SectionedAddress> BA = U->getBaseAddress())
+ if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
BaseAddr = BA->Address;
LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U,
BaseAddr, Indent);
@@ -125,7 +125,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
Data, &Offset, UseLocLists ? U->getVersion() : 4);
uint64_t BaseAddr = 0;
- if (Optional<SectionedAddress> BA = U->getBaseAddress())
+ if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
BaseAddr = BA->Address;
if (LL)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 9a76f9e0e0e..7ddc8820fc6 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -360,7 +360,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
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);
@@ -397,7 +397,7 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
case DW_FORM_addrx3:
case DW_FORM_addrx4:
case DW_FORM_GNU_addr_index: {
- Optional<SectionedAddress> A = U->getAddrOffsetSectionItem(UValue);
+ Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(UValue);
if (!A || DumpOpts.Verbose)
AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue);
if (U == nullptr)
@@ -618,14 +618,15 @@ Optional<uint64_t> DWARFFormValue::getAsAddress() const {
return SA->Address;
return None;
}
-Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const {
+Optional<object::SectionedAddress>
+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<SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
+ Optional<object::SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
if (!SA)
return None;
return SA;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 78543c53acc..e3440818ebb 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -197,7 +197,7 @@ DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
getAddressByteSize());
}
-Optional<SectionedAddress>
+Optional<object::SectionedAddress>
DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
if (IsDWO) {
auto R = Context.info_section_units();
@@ -744,7 +744,7 @@ const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
return Abbrevs;
}
-llvm::Optional<SectionedAddress> DWARFUnit::getBaseAddress() {
+llvm::Optional<object::SectionedAddress> DWARFUnit::getBaseAddress() {
if (BaseAddr)
return BaseAddr;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 2447708465a..2ad33a3e143 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -772,7 +772,7 @@ void DWARFVerifier::verifyDebugLineRows() {
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 @@ void DWARFVerifier::verifyDebugLineRows() {
if (Row.EndSequence)
PrevAddress = 0;
else
- PrevAddress = Row.Address;
+ PrevAddress = Row.Address.Address;
++RowIndex;
}
}
diff --git a/llvm/lib/DebugInfo/PDB/PDBContext.cpp b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
index 6d030d4aeda..89c20e67413 100644
--- a/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
@@ -30,14 +30,14 @@ PDBContext::PDBContext(const COFFObjectFile &Object,
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<PDBSymbol> Symbol =
- Session->findSymbolByAddress(Address, PDB_SymType::None);
+ Session->findSymbolByAddress(Address.Address, PDB_SymType::None);
if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
Length = Func->getLength();
} else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
@@ -46,7 +46,7 @@ DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
// 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 @@ DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
}
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);
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index 4f528f750a6..f0a97827c03 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -222,9 +222,10 @@ bool SymbolizableObjectFile::shouldOverrideWithSymbolTable(
isa<DWARFContext>(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(
@@ -234,7 +235,7 @@ DILineInfo SymbolizableObjectFile::symbolizeCode(uint64_t ModuleOffset,
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;
}
@@ -243,7 +244,8 @@ DILineInfo SymbolizableObjectFile::symbolizeCode(uint64_t ModuleOffset,
}
DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode(
- uint64_t ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const {
+ object::SectionedAddress ModuleOffset, FunctionNameKind FNKind,
+ bool UseSymbolTable) const {
DIInliningInfo InlinedContext;
if (DebugInfoContext)
@@ -257,7 +259,7 @@ DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode(
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;
@@ -267,9 +269,10 @@ DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode(
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;
}
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
index 69da0f3e145..a49ab000131 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
@@ -33,12 +33,13 @@ public:
static ErrorOr<std::unique_ptr<SymbolizableObjectFile>>
create(object::ObjectFile *Obj, std::unique_ptr<DIContext> 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;
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 73fe9780f52..43c65c43c74 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -52,7 +52,8 @@ namespace symbolize {
Expected<DILineInfo>
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 @@ LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
// 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 @@ LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
Expected<DIInliningInfo>
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 @@ LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
// 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 @@ LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
return InlinedContext;
}
-Expected<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
- uint64_t ModuleOffset) {
+Expected<DIGlobal>
+LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
+ object::SectionedAddress ModuleOffset) {
SymbolizableModule *Info;
if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
Info = InfoOrErr.get();
@@ -123,7 +126,7 @@ Expected<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
// 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)
diff --git a/llvm/test/tools/llvm-objdump/X86/function-sections-line-numbers.s b/llvm/test/tools/llvm-objdump/X86/function-sections-line-numbers.s
new file mode 100644
index 00000000000..b932a5d3f32
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/X86/function-sections-line-numbers.s
@@ -0,0 +1,221 @@
+# The code below is the reduced version of the output
+# from the following invocation and source:
+#
+# // test.cpp:
+#void f1() {}
+#void f2() {}
+#
+# clang -gdwarf-5 -ffunction-sections test.cpp -o test.s -S
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -dwarf-version=5 %s -o %t.o
+# RUN: llvm-objdump -disassemble -line-numbers -r -s -section-headers -t %t.o | FileCheck %s
+
+
+# CHECK: 0000000000000000 _Z2f1v
+# CHECK-NOT: test.cpp:2
+# CHECK: test.cpp:1
+# CHECK-NOT: test.cpp:2
+# CHECK: 0000000000000000 _Z2f2v
+# CHECK-NOT: test.cpp:1
+# CHECK: test.cpp:2
+# CHECK-NOT: test.cpp:1
+
+
+ .text
+ .file "test.cpp"
+ .section .text._Z2f1v,"ax",@progbits
+ .globl _Z2f1v # -- Begin function _Z2f1v
+ .p2align 4, 0x90
+ .type _Z2f1v,@function
+_Z2f1v: # @_Z2f1v
+.Lfunc_begin0:
+ .file 0 "/home/avl" "test.cpp" md5 0xefae234cc05b45384d782316d3a5d338
+ .file 1 "test.cpp" md5 0xefae234cc05b45384d782316d3a5d338
+ .loc 1 1 0 # test.cpp:1:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+.Ltmp0:
+ .loc 1 1 12 prologue_end # test.cpp:1:12
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size _Z2f1v, .Lfunc_end0-_Z2f1v
+ .cfi_endproc
+ # -- End function
+ .section .text._Z2f2v,"ax",@progbits
+ .globl _Z2f2v # -- Begin function _Z2f2v
+ .p2align 4, 0x90
+ .type _Z2f2v,@function
+_Z2f2v: # @_Z2f2v
+.Lfunc_begin1:
+ .loc 1 2 0 # test.cpp:2:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+.Ltmp2:
+ .loc 1 2 12 prologue_end # test.cpp:2:12
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp3:
+.Lfunc_end1:
+ .size _Z2f2v, .Lfunc_end1-_Z2f2v
+ .cfi_endproc
+ # -- End function
+ .section .debug_str_offsets,"",@progbits
+ .long 32
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "clang version 9.0.0 (https://github.com/llvm/llvm-project.git ebfc1e5af7a65381d858612517e6414ef58df482)" # string offset=0
+.Linfo_string1:
+ .asciz "test.cpp" # string offset=104
+.Linfo_string2:
+ .asciz "/home/avl" # string offset=113
+.Linfo_string3:
+ .asciz "_Z2f1v" # string offset=123
+.Linfo_string4:
+ .asciz "f1" # string offset=130
+.Linfo_string5:
+ .asciz "_Z2f2v" # string offset=133
+.Linfo_string6:
+ .asciz "f2" # string offset=140
+ .section .debug_str_offsets,"",@progbits
+ .long .Linfo_string0
+ .long .Linfo_string1
+ .long .Linfo_string2
+ .long .Linfo_string3
+ .long .Linfo_string4
+ .long .Linfo_string5
+ .long .Linfo_string6
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 85 # DW_AT_ranges
+ .byte 35 # DW_FORM_rnglistx
+ .byte 116 # DW_AT_rnglists_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x38 DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 4 # DW_AT_language
+ .byte 1 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .quad 0 # DW_AT_low_pc
+ .byte 0 # DW_AT_ranges
+ .long .Lrnglists_table_base0 # DW_AT_rnglists_base
+ .byte 2 # Abbrev [2] 0x2b:0xc DW_TAG_subprogram
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 3 # DW_AT_linkage_name
+ .byte 4 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ # DW_AT_external
+ .byte 2 # Abbrev [2] 0x37:0xc DW_TAG_subprogram
+ .byte 1 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 5 # DW_AT_linkage_name
+ .byte 6 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ # DW_AT_external
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_rnglists,"",@progbits
+ .long .Ldebug_rnglist_table_end0-.Ldebug_rnglist_table_start0 # Length
+.Ldebug_rnglist_table_start0:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 1 # Offset entry count
+.Lrnglists_table_base0:
+ .long .Ldebug_ranges0-.Lrnglists_table_base0
+.Ldebug_ranges0:
+ .byte 3 # DW_RLE_startx_length
+ .byte 0 # start index
+ .uleb128 .Lfunc_end0-.Lfunc_begin0 # length
+ .byte 3 # DW_RLE_startx_length
+ .byte 1 # start index
+ .uleb128 .Lfunc_end1-.Lfunc_begin1 # length
+ .byte 0 # DW_RLE_end_of_list
+.Ldebug_rnglist_table_end0:
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
+ .quad .Lfunc_begin1
+.Ldebug_addr_end0:
+
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp
index 3fe018a6f26..f3ffff93046 100644
--- a/llvm/tools/dsymutil/DwarfLinker.cpp
+++ b/llvm/tools/dsymutil/DwarfLinker.cpp
@@ -1734,17 +1734,17 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
// 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 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
// 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 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
// 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 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
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)
diff --git a/llvm/tools/dsymutil/DwarfStreamer.cpp b/llvm/tools/dsymutil/DwarfStreamer.cpp
index 28141674001..2b2c94a3899 100644
--- a/llvm/tools/dsymutil/DwarfStreamer.cpp
+++ b/llvm/tools/dsymutil/DwarfStreamer.cpp
@@ -480,11 +480,11 @@ void DwarfStreamer::emitLineTableForUnit(MCDwarfLineTableParams Params,
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 @@ void DwarfStreamer::emitLineTableForUnit(MCDwarfLineTableParams Params,
MS->EmitBytes(EncodingOS.str());
LineSectionSize += EncodingBuffer.size();
EncodingBuffer.resize(0);
- Address = Row.Address;
+ Address = Row.Address.Address;
LastLine = Row.Line;
RowsSinceLastSequence++;
} else {
diff --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
index a3750a2735d..ff2ce46a01d 100644
--- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
@@ -254,7 +254,8 @@ FileAnalysis::getDirectControlFlowXRefs(const Instr &InstrMeta) const {
return CFCrossReferences;
}
-const std::set<uint64_t> &FileAnalysis::getIndirectInstructions() const {
+const std::set<object::SectionedAddress> &
+FileAnalysis::getIndirectInstructions() const {
return IndirectInstructions;
}
@@ -268,8 +269,10 @@ const MCInstrAnalysis *FileAnalysis::getMCInstrAnalysis() const {
return MIA.get();
}
-Expected<DIInliningInfo> FileAnalysis::symbolizeInlinedCode(uint64_t Address) {
+Expected<DIInliningInfo>
+FileAnalysis::symbolizeInlinedCode(object::SectionedAddress Address) {
assert(Symbolizer != nullptr && "Symbolizer is invalid.");
+
return Symbolizer->symbolizeInlinedCode(Object->getFileName(), Address);
}
@@ -457,13 +460,14 @@ Error FileAnalysis::parseCodeSections() {
ArrayRef<uint8_t> SectionBytes((const uint8_t *)SectionContents.data(),
Section.getSize());
- parseSectionContents(SectionBytes, Section.getAddress());
+ parseSectionContents(SectionBytes,
+ {Section.getAddress(), Section.getIndex()});
}
return Error::success();
}
void FileAnalysis::parseSectionContents(ArrayRef<uint8_t> SectionBytes,
- uint64_t SectionAddress) {
+ object::SectionedAddress Address) {
assert(Symbolizer && "Symbolizer is uninitialised.");
MCInst Instruction;
Instr InstrMeta;
@@ -477,7 +481,7 @@ void FileAnalysis::parseSectionContents(ArrayRef<uint8_t> SectionBytes,
Byte += InstructionSize;
- uint64_t VMAddress = SectionAddress + Byte - InstructionSize;
+ uint64_t VMAddress = Address.Address + Byte - InstructionSize;
InstrMeta.Instruction = Instruction;
InstrMeta.VMAddress = VMAddress;
InstrMeta.InstructionSize = InstructionSize;
@@ -509,8 +513,8 @@ void FileAnalysis::parseSectionContents(ArrayRef<uint8_t> SectionBytes,
// Check if this instruction exists in the range of the DWARF metadata.
if (!IgnoreDWARFFlag) {
- auto LineInfo =
- Symbolizer->symbolizeCode(Object->getFileName(), VMAddress);
+ auto LineInfo = Symbolizer->symbolizeCode(
+ Object->getFileName(), {VMAddress, Address.SectionIndex});
if (!LineInfo) {
handleAllErrors(LineInfo.takeError(), [](const ErrorInfoBase &E) {
errs() << "Symbolizer failed to get line: " << E.message() << "\n";
@@ -522,7 +526,7 @@ void FileAnalysis::parseSectionContents(ArrayRef<uint8_t> SectionBytes,
continue;
}
- IndirectInstructions.insert(VMAddress);
+ IndirectInstructions.insert({VMAddress, Address.SectionIndex});
}
}
diff --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h
index d8031ed5f7d..27135c0debb 100644
--- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h
+++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h
@@ -139,14 +139,15 @@ public:
bool usesRegisterOperand(const Instr &InstrMeta) const;
// Returns the list of indirect instructions.
- const std::set<uint64_t> &getIndirectInstructions() const;
+ const std::set<object::SectionedAddress> &getIndirectInstructions() const;
const MCRegisterInfo *getRegisterInfo() const;
const MCInstrInfo *getMCInstrInfo() const;
const MCInstrAnalysis *getMCInstrAnalysis() const;
// Returns the inlining information for the provided address.
- Expected<DIInliningInfo> symbolizeInlinedCode(uint64_t Address);
+ Expected<DIInliningInfo>
+ symbolizeInlinedCode(object::SectionedAddress Address);
// Returns whether the provided Graph represents a protected indirect control
// flow instruction in this file.
@@ -178,7 +179,7 @@ protected:
// Disassemble and parse the provided bytes into this object. Instruction
// address calculation is done relative to the provided SectionAddress.
void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
- uint64_t SectionAddress);
+ object::SectionedAddress Address);
// Constructs and initialises members required for disassembly.
Error initialiseDisassemblyMembers();
@@ -225,7 +226,7 @@ private:
DenseMap<uint64_t, std::vector<uint64_t>> StaticBranchTargetings;
// A list of addresses of indirect control flow instructions.
- std::set<uint64_t> IndirectInstructions;
+ std::set<object::SectionedAddress> IndirectInstructions;
// The addresses of functions that will trap on CFI violations.
SmallSet<uint64_t, 4> TrapOnFailFunctionAddresses;
diff --git a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
index 1f8fccb32ff..b621836b270 100644
--- a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
@@ -93,17 +93,19 @@ void GraphResult::printToDOT(const FileAnalysis &Analysis,
}
GraphResult GraphBuilder::buildFlowGraph(const FileAnalysis &Analysis,
- uint64_t Address) {
+ object::SectionedAddress Address) {
GraphResult Result;
- Result.BaseAddress = Address;
+ Result.BaseAddress = Address.Address;
DenseSet<uint64_t> 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;
}
diff --git a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h
index c76e89a37ec..dc96e0b2501 100644
--- a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h
+++ b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h
@@ -102,7 +102,7 @@ public:
// (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
diff --git a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
index 9fff1a5ec38..c54e5383248 100644
--- a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
+++ b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
@@ -130,8 +130,8 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
std::map<unsigned, uint64_t> 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 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
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 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
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";
}
}
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index de2221b1392..4580688811b 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -379,7 +379,12 @@ static void filterByAccelName(ArrayRef<std::string> Names, DWARFContext &DICtx,
/// 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 @@ static bool lookup(DWARFContext &DICtx, uint64_t Address, raw_ostream &OS) {
DIEsForAddr.BlockDIE.dump(OS, 4, DumpOpts);
}
- if (DILineInfo LineInfo = DICtx.getLineInfoForAddress(Lookup))
+ // TODO: it is neccessary to set proper SectionIndex here.
+ // object::SectionedAddress::UndefSection works for only absolute addresses.
+ if (DILineInfo LineInfo = DICtx.getLineInfoForAddress(
+ {Lookup, object::SectionedAddress::UndefSection}))
LineInfo.dump(OS);
return true;
@@ -413,7 +421,7 @@ static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
// Handle the --lookup option.
if (Lookup)
- return lookup(DICtx, Lookup, OS);
+ return lookup(Obj, DICtx, Lookup, OS);
// Handle the --name option.
if (!Name.empty()) {
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 72a8a01c114..dc60ee1f0c6 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -7500,7 +7500,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
// 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 << ':'
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 914789f18f8..8ff1667d8a3 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -508,7 +508,8 @@ public:
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 = "; ");
};
@@ -538,7 +539,8 @@ bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) {
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;
@@ -599,14 +601,15 @@ class PrettyPrinter {
public:
virtual ~PrettyPrinter() = default;
virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
- ArrayRef<uint8_t> Bytes, uint64_t Address,
- raw_ostream &OS, StringRef Annot,
- MCSubtargetInfo const &STI, SourcePrinter *SP,
+ ArrayRef<uint8_t> Bytes,
+ object::SectionedAddress Address, raw_ostream &OS,
+ StringRef Annot, MCSubtargetInfo const &STI,
+ SourcePrinter *SP,
std::vector<RelocationRef> *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);
@@ -633,13 +636,13 @@ public:
}
}
void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> 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<RelocationRef> *Rels) override {
if (SP && (PrintSource || PrintLines))
SP->printSourceLine(OS, Address, "");
if (!MI) {
- printLead(Bytes, Address, OS);
+ printLead(Bytes, Address.Address, OS);
OS << " <unknown>";
return;
}
@@ -661,9 +664,9 @@ public:
std::vector<RelocationRef>::const_iterator RelCur = Rels->begin();
std::vector<RelocationRef>::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;
@@ -675,7 +678,7 @@ public:
Separator = "\n";
if (SP && (PrintSource || PrintLines))
SP->printSourceLine(OS, Address, "");
- printLead(Bytes, Address, OS);
+ printLead(Bytes, Address.Address, OS);
OS << Preamble;
Preamble = " ";
StringRef Inst;
@@ -693,7 +696,7 @@ public:
OS << " } " << PacketBundle.second;
PrintReloc();
Bytes = Bytes.slice(4);
- Address += 4;
+ Address.Address += 4;
}
}
};
@@ -702,8 +705,8 @@ HexagonPrettyPrinter HexagonPrettyPrinterInst;
class AMDGCNPrettyPrinter : public PrettyPrinter {
public:
void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> 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<RelocationRef> *Rels) override {
if (SP && (PrintSource || PrintLines))
SP->printSourceLine(OS, Address);
@@ -733,7 +736,7 @@ public:
}
}
- OS << format("// %012" PRIX64 ": ", Address);
+ OS << format("// %012" PRIX64 ": ", Address.Address);
if (Bytes.size() >=4) {
for (auto D : makeArrayRef(reinterpret_cast<const U32*>(Bytes.data()),
Bytes.size() / sizeof(U32)))
@@ -754,13 +757,13 @@ AMDGCNPrettyPrinter AMDGCNPrettyPrinterInst;
class BPFPrettyPrinter : public PrettyPrinter {
public:
void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> 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<RelocationRef> *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);
@@ -1323,9 +1326,10 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
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();
diff --git a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
index e792b7257ea..69d70e94808 100644
--- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -367,6 +367,8 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
}
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,20 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
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";
diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
index 8ff7a22a71a..63f9693562b 100644
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -194,23 +194,54 @@ static bool parseCommand(StringRef InputString, bool &IsData,
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<OwningBinary<Binary>> BinaryOrErr = createBinary(ModuleName);
+
+ if (error(BinaryOrErr))
+ return object::SectionedAddress::UndefSection;
+
+ Binary &Binary = *BinaryOrErr->getBinary();
+
+ if (ObjectFile *O = dyn_cast<ObjectFile>(&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());
diff --git a/llvm/tools/llvm-xray/func-id-helper.cpp b/llvm/tools/llvm-xray/func-id-helper.cpp
index 987eb43b732..dc821a420c6 100644
--- a/llvm/tools/llvm-xray/func-id-helper.cpp
+++ b/llvm/tools/llvm-xray/func-id-helper.cpp
@@ -29,7 +29,12 @@ std::string FuncIdConversionHelper::SymbolOrNumber(int32_t FuncId) const {
return F.str();
}
- if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, It->second)) {
+ object::SectionedAddress ModuleAddress;
+ ModuleAddress.Address = It->second;
+ // TODO: set proper section index here.
+ // object::SectionedAddress::UndefSection works for only absolute addresses.
+ ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection;
+ if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress)) {
auto &DI = *ResOrErr;
if (DI.FunctionName == "<invalid>")
F << "@(" << std::hex << It->second << ")";
@@ -51,7 +56,12 @@ std::string FuncIdConversionHelper::FileLineAndColumn(int32_t FuncId) const {
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.
+ // object::SectionedAddress::UndefSection works for only absolute addresses.
+ ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection;
+ auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress);
if (!ResOrErr) {
consumeError(ResOrErr.takeError());
return "(unknown)";
diff --git a/llvm/tools/sancov/sancov.cpp b/llvm/tools/sancov/sancov.cpp
index ea8240fa3c0..cd149a5b03f 100644
--- a/llvm/tools/sancov/sancov.cpp
+++ b/llvm/tools/sancov/sancov.cpp
@@ -621,10 +621,17 @@ getCoveragePoints(const std::string &ObjectFile,
std::set<std::string> 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::UndefSection works for only absolute
+ // addresses.
+ 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 +643,12 @@ getCoveragePoints(const std::string &ObjectFile,
for (auto Addr : Addrs) {
std::set<DILineInfo> Infos; // deduplicate debug info.
- auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr);
+ // TODO: it would be neccessary to set proper section index here.
+ // object::SectionedAddress::UndefSection works for only absolute addresses.
+ 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 +662,8 @@ getCoveragePoints(const std::string &ObjectFile,
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 +970,10 @@ symbolize(const RawCoverage &Data, const std::string ObjectFile) {
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::UndefSection works for only absolute addresses.
+ auto LineInfo = Symbolizer->symbolizeCode(
+ ObjectFile, {Addr, object::SectionedAddress::UndefSection});
failIfError(LineInfo);
if (B.isBlacklisted(*LineInfo))
continue;
diff --git a/llvm/tools/sanstats/sanstats.cpp b/llvm/tools/sanstats/sanstats.cpp
index 0b4b2b8196b..d470a5b5013 100644
--- a/llvm/tools/sanstats/sanstats.cpp
+++ b/llvm/tools/sanstats/sanstats.cpp
@@ -84,8 +84,10 @@ const char *ReadModule(char SizeofPtr, const char *Begin, const char *End) {
// 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<DILineInfo> LineInfo =
- Symbolizer.symbolizeCode(Filename, Addr - 1)) {
+ // TODO: it would be neccessary to set proper section index here.
+ // object::SectionedAddress::UndefSection works for only absolute addresses.
+ if (Expected<DILineInfo> LineInfo = Symbolizer.symbolizeCode(
+ Filename, {Addr - 1, object::SectionedAddress::UndefSection})) {
llvm::outs() << format_hex(Addr - 1, 18) << ' ' << LineInfo->FileName
<< ':' << LineInfo->Line << ' ' << LineInfo->FunctionName
<< ' ';
diff --git a/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp b/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
index 58fdbe5c7ad..e38ac9264c8 100644
--- a/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
+++ b/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
@@ -51,8 +51,8 @@ public:
// Expose this method publicly for testing.
void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
- uint64_t SectionAddress) {
- FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
+ object::SectionedAddress Address) {
+ FileAnalysis::parseSectionContents(SectionBytes, Address);
}
Error initialiseDisassemblyMembers() {
@@ -106,7 +106,7 @@ TEST_F(BasicX86FileAnalysisTest, BasicDisassemblyTraversalTest) {
0x41, 0x0e, // 21: rex.B (bad)
0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
EXPECT_EQ(nullptr, Analysis.getInstruction(0x0));
EXPECT_EQ(nullptr, Analysis.getInstruction(0x1000));
@@ -210,7 +210,7 @@ TEST_F(BasicX86FileAnalysisTest, PrevAndNextFromBadInst) {
0x2f, // 1: (bad)
0x90 // 2: nop
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
const auto &BadInstrMeta = Analysis.getInstructionOrDie(0xDEADBEEF + 1);
const auto *GoodInstrMeta =
Analysis.getPrevInstructionSequential(BadInstrMeta);
@@ -240,7 +240,7 @@ TEST_F(BasicX86FileAnalysisTest, CFITrapTest) {
0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
0x0f, 0x0b // 28: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
EXPECT_FALSE(Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF)));
EXPECT_FALSE(
@@ -275,7 +275,7 @@ TEST_F(BasicX86FileAnalysisTest, FallThroughTest) {
0x75, 0x00, // 17: jne +0
0xc3, // 19: retq
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
EXPECT_TRUE(
Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF)));
@@ -322,7 +322,7 @@ TEST_F(BasicX86FileAnalysisTest, DefiniteNextInstructionTest) {
0xeb, 0xdd, // 36: jmp 3 [-35]
0xeb, 0xdc, // 38: jmp 4 [-36]
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
const auto *Current = Analysis.getInstruction(0xDEADBEEF);
const auto *Next = Analysis.getDefiniteNextInstruction(*Current);
@@ -412,7 +412,7 @@ TEST_F(BasicX86FileAnalysisTest, ControlFlowXRefsTest) {
0xeb, 0xdd, // 36: jmp 3 [-35]
0xeb, 0xdc, // 38: jmp 4 [-36]
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
const auto *InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF);
std::set<const Instr *> XRefs =
Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
@@ -503,17 +503,18 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionInvalidTargets) {
0x0f, 0x0b, // 1: ud2
0x75, 0x00, // 3: jne 5 [+0]
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
+ 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 +528,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionBasicFallthroughToUd2) {
0x0f, 0x0b, // 2: ud2
0xff, 0x10, // 4: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -542,8 +544,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionBasicJumpToUd2) {
0xff, 0x10, // 2: callq *(%rax)
0x0f, 0x0b, // 4: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -560,8 +563,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualPathUd2) {
0x75, 0xf9, // 7: jne 2 [-7]
0x0f, 0x0b, // 9: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -577,8 +581,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualPathSingleUd2) {
0x75, 0xfb, // 5: jne 2 [-5]
0x0f, 0x0b, // 7: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -596,12 +601,13 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualFailLimitUpwards) {
0xff, 0x10, // 6: callq *(%rax)
0x0f, 0x0b, // 8: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
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 +627,12 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualFailLimitDownwards) {
0x90, // 7: nop
0x0f, 0x0b, // 8: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
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 +649,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionGoodAndBadPaths) {
0xff, 0x10, // 4: callq *(%rax)
0x0f, 0x0b, // 6: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
Analysis.validateCFIProtection(Result));
}
@@ -658,8 +666,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionWithUnconditionalJumpInFallthrough
0xff, 0x10, // 4: callq *(%rax)
0x0f, 0x0b, // 6: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -685,10 +694,11 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionComplexExample) {
0x90, // 21: nop
0x0f, 0x0b, // 22: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
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 +714,10 @@ TEST_F(BasicX86FileAnalysisTest, UndefSearchLengthOneTest) {
0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130
0x0f, 0x0b, // 0x688127: ud2
},
- 0x688118);
+ {0x688118, 0x0});
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 +729,7 @@ TEST_F(BasicX86FileAnalysisTest, UndefSearchLengthOneTestFarAway) {
0x74, 0x73, // 0x7759eb: je 0x775a60
0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e
},
- 0x7759eb);
+ {0x7759eb, 0x0});
Analysis.parseSectionContents(
{
@@ -729,24 +739,24 @@ TEST_F(BasicX86FileAnalysisTest, UndefSearchLengthOneTestFarAway) {
0x48, 0x89, 0xde, // 0x775a65: mov %rbx,%rsi
0xff, 0xd1, // 0x775a68: callq *%rcx
},
- 0x775a56);
+ {0x775a56, 0x0});
Analysis.parseSectionContents(
{
0x0f, 0x0b, // 0x775e0e: ud2
},
- 0x775e0e);
+ {0x775e0e, 0x0});
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 +772,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathExplicit) {
0x48, 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %rax
0xff, 0x10, // 10: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 10);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 10, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -778,8 +789,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathExplicit2) {
0x48, 0x83, 0xc0, 0x00, // 4: add $0x0, %rax
0xff, 0x10, // 8: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -794,8 +806,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathImplicit) {
0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %eax
0xff, 0x10, // 9: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -812,8 +825,9 @@ TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberDualPathImplicit) {
0x75, 0xf9, // 8: jne 2 [-7]
0x0f, 0x0b, // 10: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -825,8 +839,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64BasicUnprotected) {
{
0x00, 0x01, 0x3f, 0xd6, // 0: blr x8
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
Analysis.validateCFIProtection(Result));
}
@@ -840,8 +855,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64BasicProtected) {
0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
0x00, 0x01, 0x3f, 0xd6, // 8: blr x8
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -856,8 +872,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberBasic) {
0x08, 0x05, 0x00, 0x91, // 8: add x8, x8, #1
0x00, 0x01, 0x3f, 0xd6, // 12: blr x8
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -872,8 +889,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberOneLoad) {
0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
0x20, 0x00, 0x1f, 0xd6, // 12: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -889,8 +907,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddGood) {
0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -906,8 +925,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddBad) {
0x21, 0x04, 0x00, 0x91, // 12: add x1, x1, #1
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -923,8 +943,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddBad2) {
0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -940,8 +961,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberTwoLoads) {
0x21, 0x08, 0x40, 0xf9, // 12: ldr x1, [x1,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -957,8 +979,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberUnrelatedSecondLoad) {
0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -974,8 +997,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberUnrelatedLoads) {
0x22, 0x08, 0x40, 0xf9, // 12: ldr x2, [x1,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -990,8 +1014,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64GoodAndBadPaths) {
0x20, 0x00, 0x20, 0xd4, // 8: brk #0x1
0x20, 0x00, 0x1f, 0xd6, // 12: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
Analysis.validateCFIProtection(Result));
}
@@ -1009,8 +1034,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPaths) {
0x20, 0x00, 0x1f, 0xd6, // 20: br x1
0x20, 0x00, 0x20, 0xd4, // 24: brk #0x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 20);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 20, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -1029,8 +1055,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPathsBadLoad1) {
0x20, 0x00, 0x1f, 0xd6, // 24: br x1
0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -1049,8 +1076,9 @@ TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPathsBadLoad2) {
0x20, 0x00, 0x1f, 0xd6, // 24: br x1
0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
diff --git a/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp b/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp
index 9775c5bd8ec..a57958d60e6 100644
--- a/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp
+++ b/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp
@@ -113,8 +113,8 @@ public:
// Expose this method publicly for testing.
void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
- uint64_t SectionAddress) {
- FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
+ object::SectionedAddress Address) {
+ FileAnalysis::parseSectionContents(SectionBytes, Address);
}
Error initialiseDisassemblyMembers() {
@@ -156,8 +156,9 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestSinglePathFallthroughUd2) {
0x0f, 0x0b, // 2: ud2
0xff, 0x10, // 4: callq *(%rax)
},
- 0xDEADBEEF);
- const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ const auto Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
@@ -182,8 +183,9 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestSinglePathJumpUd2) {
0xff, 0x10, // 2: callq *(%rax)
0x0f, 0x0b, // 4: ud2
},
- 0xDEADBEEF);
- const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ {0xDEADBEEF, 0x0});
+ const auto Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
@@ -211,8 +213,9 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestDualPathDualUd2) {
0x75, 0xf9, // 7: jne 2 [-7]
0x0f, 0x0b, // 9: ud2
},
- 0xDEADBEEF);
- const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ const auto Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
@@ -249,8 +252,9 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestDualPathSingleUd2) {
0x75, 0xfb, // 5: jne 2 [-5]
0x0f, 0x0b, // 7: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
@@ -284,16 +288,17 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphFailures) {
0x90, // 0: nop
0x75, 0xfe, // 1: jne 1 [-2]
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
+ 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 +311,9 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphNoXrefs) {
0xeb, 0xfe, // 0: jmp 0 [-2]
0xff, 0x10, // 2: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ {0xDEADBEEF, 0x0});
+ 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 +327,9 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphConditionalInfiniteLoop) {
0x75, 0xfe, // 0: jne 0 [-2]
0xff, 0x10, // 2: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
EXPECT_THAT(
@@ -344,8 +351,9 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphUnconditionalInfiniteLoop) {
0xeb, 0xfc, // 2: jmp 0 [-4]
0xff, 0x10, // 4: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
EXPECT_THAT(
@@ -368,8 +376,9 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphNoFlowsToIndirection) {
0xeb, 0xfc, // 2: jmp 0 [-4]
0xff, 0x10, // 4: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 4));
EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
}
@@ -387,12 +396,13 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphLengthExceededUpwards) {
0xff, 0x10, // 6: callq *(%rax)
0x0f, 0x0b, // 8: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
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 +426,12 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphLengthExceededDownwards) {
0x90, // 7: nop
0x0f, 0x0b, // 8: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
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 +461,9 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphWithRepeatedWork) {
0x75, 0xfb, // 5: jne 2 [-5]
0x0f, 0x0b, // 7: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
EXPECT_THAT(
@@ -529,11 +541,12 @@ TEST_F(BasicGraphBuilderTest, BuildFlowGraphComplexExample) {
0x90, // 21: nop
0x0f, 0x0b, // 22: ud2
},
- 0x1000);
+ {0x1000, 0x0});
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));
OpenPOWER on IntegriCloud