]> granicus.if.org Git - llvm/commitdiff
[DebugInfo] add SectionedAddress to DebugInfo interfaces.
authorAlexey Lapshin <a.v.lapshin@mail.ru>
Wed, 27 Feb 2019 13:17:36 +0000 (13:17 +0000)
committerAlexey Lapshin <a.v.lapshin@mail.ru>
Wed, 27 Feb 2019 13:17:36 +0000 (13:17 +0000)
      That patch is the fix for https://bugs.llvm.org/show_bug.cgi?id=40703
   "wrong line number info for obj file compiled with -ffunction-sections"
   bug. The problem happened with only .o files. If object file contains
   several .text sections then line number information showed incorrectly.
   The reason for this is that DwarfLineTable could not detect section which
   corresponds to specified address(because address is the local to the
   section). And as the result it could not select proper sequence in the
   line table. The fix is to pass SectionIndex with the address. So that it
   would be possible to differentiate addresses from various sections. With
   this fix llvm-objdump shows correct line numbers for disassembled code.

   Differential review: https://reviews.llvm.org/D58194

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354972 91177308-0d34-0410-b5e6-96231b3b80d8

44 files changed:
include/llvm/DebugInfo/DIContext.h
include/llvm/DebugInfo/DWARF/DWARFContext.h
include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
include/llvm/DebugInfo/DWARF/DWARFFormValue.h
include/llvm/DebugInfo/DWARF/DWARFListTable.h
include/llvm/DebugInfo/DWARF/DWARFSection.h
include/llvm/DebugInfo/DWARF/DWARFUnit.h
include/llvm/DebugInfo/PDB/PDBContext.h
include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
include/llvm/DebugInfo/Symbolize/Symbolize.h
include/llvm/Object/ObjectFile.h
lib/DebugInfo/DWARF/DWARFContext.cpp
lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
lib/DebugInfo/DWARF/DWARFDebugLine.cpp
lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
lib/DebugInfo/DWARF/DWARFDie.cpp
lib/DebugInfo/DWARF/DWARFFormValue.cpp
lib/DebugInfo/DWARF/DWARFUnit.cpp
lib/DebugInfo/DWARF/DWARFVerifier.cpp
lib/DebugInfo/PDB/PDBContext.cpp
lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
lib/DebugInfo/Symbolize/Symbolize.cpp
test/tools/llvm-objdump/X86/function-sections-line-numbers.s [new file with mode: 0644]
tools/dsymutil/DwarfLinker.cpp
tools/dsymutil/DwarfStreamer.cpp
tools/llvm-cfi-verify/lib/FileAnalysis.cpp
tools/llvm-cfi-verify/lib/FileAnalysis.h
tools/llvm-cfi-verify/lib/GraphBuilder.cpp
tools/llvm-cfi-verify/lib/GraphBuilder.h
tools/llvm-cfi-verify/llvm-cfi-verify.cpp
tools/llvm-dwarfdump/llvm-dwarfdump.cpp
tools/llvm-objdump/MachODump.cpp
tools/llvm-objdump/llvm-objdump.cpp
tools/llvm-rtdyld/llvm-rtdyld.cpp
tools/llvm-symbolizer/llvm-symbolizer.cpp
tools/llvm-xray/func-id-helper.cpp
tools/sancov/sancov.cpp
tools/sanstats/sanstats.cpp
unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
unittests/tools/llvm-cfi-verify/GraphBuilder.cpp

index a41ab21412d0ac14d1c44bfc743d76e636541a2b..87c47dcf106bdd7abdc0533e44fb0d09881d1228 100644 (file)
@@ -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:
index e41592783b17c1c9d102a99b5eccc62b35a0f736..5d243da7e5872e63951f5ac845695add0457b601 100644 (file)
@@ -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);
 };
 
index 9e40c8444661d5a5bf40b7b4c88e4828c6e356d8..1f36e0daed0c553c59b09c77edaca0a51324ee0b 100644 (file)
@@ -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;
index c1c0f420f61570fb1d10c79f65c0c14ff7ccb471..a66f6029234358b1c1f86352aed7b3877d27f63d 100644 (file)
@@ -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
index c6661a8bfa0bc8a15973d666c2a99b87734bf8db..167ddde3ec3dca54ce7e7643d3e800388a073a4e 100644 (file)
@@ -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;
 };
 
index 050329464e71722c11f6d0357b1326f460762823..8107624f8a85695cd46ca0109c6dbb9a267d7382 100644 (file)
@@ -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();
index 6c13db3d87c0d247090e8d1df672cd2f56631567..a1ea69b040f0f2586a955ceac49ec9b62088b158 100644 (file)
@@ -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);
index bb0004615d75970fef5313885a212ff733664dbe..054524d368ed575cd66a24931f744ba23336abf2 100644 (file)
@@ -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
index e82ce8ed6c2823723c2cc087021bbbef38aa98e0..86add50150847a18011eca36539cf1d65fc39557 100644 (file)
@@ -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);
index e404e07f7583e2f28c09890d7fc3c6b5f7c666a7..89a7efef7e9c44025481e31361a8044cd469b52b 100644 (file)
@@ -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:
index f0862d0b85d2b74e83695c5b2ce46250ded1ee20..2bdfb0942a87121340655d8d29bc40c142e41bcb 100644 (file)
@@ -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;
index 4e57fe43847811f2012f07558ad06470f3a20176..3e194ef1a2b4a717f84f7a82696cd35e51cbf7a7 100644 (file)
@@ -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
index f13775c914df808ecdfd4454158e1f3011f8bba4..019b5cb5a8cd5c5af5493417a434823da15d07ed 100644 (file)
@@ -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 {
index d06b737b810202646bb89781273ff437d6190905..dc0539f4634c426ee36f3044cee726392f5f5cbc 100644 (file)
@@ -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.
index 73663f868f048333404abe6ae05378e578496591..bd8c23765e4ad8706e47f7e14a2a6491d76e9e12 100644 (file)
@@ -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);
index 406c342cd5892ad0e08c133a892d472e23902456..a2c25248618427031dc762a3d11a325c395ed9db 100644 (file)
@@ -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)
index 31193b563a54699b8103960182fe6fb4dda52d6b..d8df81a0aa0b41ae147b12fa1b04ea97f657238a 100644 (file)
@@ -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)) {
index 2e4babac6c7f4fce7ffce67ab7e3ef6b5c6774d3..af1924a496682c72c6cba77eec26d494a2c14e43 100644 (file)
@@ -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) {
index 32546fd7613b8890c615089c2bc8d3fea1332d8a..d139688764535a81f4e0fb1f7014a2e9905b45d4 100644 (file)
@@ -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)
index 9a76f9e0e0e37e6b643c9bfcf6c6cae91829539c..7ddc8820fc625f6d173f214c629852537aca6af9 100644 (file)
@@ -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;
index 78543c53acc579e82dbfe60bf082e167e1c1ceea..e3440818ebb7da827d03fc0c279e46655128da8e 100644 (file)
@@ -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;
 
index 2447708465a013e1faca4ea5587f4aea88f8fc4b..2ad33a3e1432f51dffd4fcabe2b9b667d0f614c3 100644 (file)
@@ -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;
     }
   }
index 6d030d4aedab3c4871b32c4312c80abdb597d871..89c20e674138e5368ff6c3fd43607a4f18c4f755 100644 (file)
@@ -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);
index 4f528f750a6674dcd87c8ad6f6b9576842cf432e..f0a97827c036f34b1bfab2b8fb49427334233906 100644 (file)
@@ -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;
 }
index 69da0f3e1450234709290944f4cf21b2ff055aa0..a49ab0001316e4b3bb350d856996dbb56e6d0be7 100644 (file)
@@ -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;
index 73fe9780f522da1698c9da4dc5748768eb14cb82..43c65c43c74889c8550c8cbeab0840ac326b6e4a 100644 (file)
@@ -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/test/tools/llvm-objdump/X86/function-sections-line-numbers.s b/test/tools/llvm-objdump/X86/function-sections-line-numbers.s
new file mode 100644 (file)
index 0000000..b932a5d
--- /dev/null
@@ -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:
index 3fe018a6f2619fd5d072ccf31886c56ba619268b..f3ffff9304635af5758c5be976db74358ec28186 100644 (file)
@@ -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)
index 2814167400152f96fffc6844afe98333963a083b..2b2c94a389999cbfcc60f79e8b7943e45d4ab556 100644 (file)
@@ -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 {
index a3750a2735d53d6e9d4a0fa813badb1fccaeb509..ff2ce46a01db168f486794b318c46d708419f6b8 100644 (file)
@@ -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});
   }
 }
 
index d8031ed5f7da68b3637b7f0e5449f24594aa650c..27135c0debbac8c53fc6d203e091eb7f833d86b8 100644 (file)
@@ -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;
index 1f8fccb32ff95d528aac8da31b2e8bc01636dcee..b621836b270fdd703cce9e6595afd2a9fac8e7bc 100644 (file)
@@ -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;
 }
 
index c76e89a37ecc928d379579b19facd093c8a4bb1b..dc96e0b25016dedf39fa21e694c30820f884e9c0 100644 (file)
@@ -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
index 9fff1a5ec38fc1accf9e6f7fb90f35b4c9a915d3..c54e5383248247302173ff8f2e664acf44954280 100644 (file)
@@ -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";
       }
     }
 
index de2221b1392421aa4119cb8ac678a2cd677d7432..4580688811b30943975821e85add38d22c8115e2 100644 (file)
@@ -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()) {
index 72a8a01c114ef81c31ac3404f42db240045e2edf..dc60ee1f0c6f1fe269a2599500bcf78dcc3e5679 100644 (file)
@@ -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 << ':'
index 914789f18f828692456555da31615e2d124f4429..8ff1667d8a338ddfa850c03c601cc47cce936b70 100644 (file)
@@ -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();
 
index e792b7257ea5e877b19c50f98a640c0ef668ef54..69d70e948081e39e6b9fc7d7e51ff870ca8aa38a 100644 (file)
@@ -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";
index 8ff7a22a71aa6102f53c7773c8fc57c89b6aecf8..63f9693562b3ffd418472f7862ce04476442ad78 100644 (file)
@@ -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());
index 987eb43b73242a76fb8ea0b20a537017bf101c5f..dc821a420c677f099a548fa6e402f8a1ac52f7bf 100644 (file)
@@ -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)";
index ea8240fa3c0a6ed968339ea8d70704000381114f..cd149a5b03f1adf6c3bbed574d513b8c969a9616 100644 (file)
@@ -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;
index 0b4b2b8196bbad155ee4d9f65caa432c127e2d5c..d470a5b501389f23d0e6158aea3085846a9d66dc 100644 (file)
@@ -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
                    << ' ';
index 58fdbe5c7ad502c84934b5d13e85ae97f0fe5a05..e38ac9264c8dfa18124e94d29f20f62ae52fe330 100644 (file)
@@ -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));
 }
index 9775c5bd8ec3c542f44bf22af5ec3139e8ced6f2..a57958d60e68b89e68345c4bb5cdb70e72ce7928 100644 (file)
@@ -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));