]> granicus.if.org Git - llvm/commitdiff
Recommit r303978 "[DWARF] - Make collectAddressRanges() return section index in addit...
authorGeorge Rimar <grimar@accesssoftek.com>
Fri, 26 May 2017 13:13:50 +0000 (13:13 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Fri, 26 May 2017 13:13:50 +0000 (13:13 +0000)
With fix of test compilation.

Initial commit message:

This change is intended to use for LLD in D33183.
Problem we have in LLD when building .gdb_index is that we need to know section
which address range belongs to.

Previously it was solved on LLD side by providing fake section addresses
with use of llvm::LoadedObjectInfo interface. We assigned file offsets as addressed.
Then after obtaining ranges lists, for each range we had to find section ID's.
That not only was slow, but also complicated implementation and was the reason
of incorrect behavior when
sections share the same offsets, like D33176 shows.

This patch makes DWARF parsers to return section index as well.
That solves problem mentioned above.

Differential revision: https://reviews.llvm.org/D33184

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

18 files changed:
include/llvm/DebugInfo/DWARF/DWARFContext.h
include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
include/llvm/DebugInfo/DWARF/DWARFDie.h
include/llvm/DebugInfo/DWARF/DWARFFormValue.h
include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
include/llvm/Object/COFF.h
include/llvm/Object/ELFObjectFile.h
include/llvm/Object/MachO.h
include/llvm/Object/ObjectFile.h
include/llvm/Object/Wasm.h
lib/DebugInfo/DWARF/DWARFContext.cpp
lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
lib/DebugInfo/DWARF/DWARFDie.cpp
lib/DebugInfo/DWARF/DWARFFormValue.cpp
lib/Object/COFFObjectFile.cpp
lib/Object/MachOObjectFile.cpp
lib/Object/WasmObjectFile.cpp
unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp

index 42883967a9e8d442576fd698f614530ace2e9a7b..7fa68f3f2314e085e8cc579cc0f5b6b36d561fca 100644 (file)
@@ -46,7 +46,8 @@ class raw_ostream;
 /// Reads a value from data extractor and applies a relocation to the result if
 /// one exists for the given offset.
 uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size,
-                           uint32_t *Off, const RelocAddrMap *Relocs);
+                           uint32_t *Off, const RelocAddrMap *Relocs,
+                           uint64_t *SecNdx = nullptr);
 
 /// DWARFContext
 /// This data structure is the top level entity that deals with dwarf debug
index 95ec1be62a79090bef3bcf0c82a582f2e6eb3455..b436711ae6ed7f2e4862aa5c758bcc7e680fc487 100644 (file)
@@ -25,6 +25,7 @@ class raw_ostream;
 struct DWARFAddressRange {
   uint64_t LowPC;
   uint64_t HighPC;
+  uint64_t SectionIndex;
 };
 
 /// DWARFAddressRangesVector - represents a set of absolute address ranges.
@@ -44,6 +45,8 @@ public:
     /// address past the end of the address range. The ending address must
     /// be greater than or equal to the beginning address.
     uint64_t EndAddress;
+    /// A section index this range belongs to.
+    uint64_t SectionIndex;
 
     /// The end of any given range list is marked by an end of list entry,
     /// which consists of a 0 for the beginning address offset
index ca94a90fabfc89d401a19635c6b25e1e037f7979..fa41b9e293c0b3e13da28a5536ca85a295241438 100644 (file)
@@ -195,7 +195,8 @@ public:
 
   /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
   /// Returns true if both attributes are present.
-  bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const;
+  bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
+                       uint64_t &SectionIndex) const;
 
   /// Get the address ranges for this DIE.
   ///
index a30e0be9c3c359361be5eb6a6a49cc2d433e9e6f..3a781dde8929ae1de8274ce678950db9dc8bf488 100644 (file)
@@ -47,6 +47,7 @@ private:
       const char *cstr;
     };
     const uint8_t *data = nullptr;
+    uint64_t SectionIndex;      /// Section index for reference forms.
   };
 
   dwarf::Form Form;             /// Form for this value.
@@ -58,6 +59,7 @@ public:
 
   dwarf::Form getForm() const { return Form; }
   uint64_t getRawUValue() const { return Value.uval; }
+  uint64_t getSectionIndex() const { return Value.SectionIndex; }
   void setForm(dwarf::Form F) { Form = F; }
   void setUValue(uint64_t V) { Value.uval = V; }
   void setSValue(int64_t V) { Value.sval = V; }
index fabacc0abcea910ef216711bb9557a092beef726..c50f617d98eb1c5ae52f7f0fa133ba710658d746 100644 (file)
@@ -17,6 +17,7 @@
 namespace llvm {
 
 struct RelocAddrEntry {
+  uint64_t SectionIndex;
   uint64_t Value;
 };
 
index 8b9b4973717057c3179eb2df7d350a2a5ceff903..dafd1a43cb595933cebf41e5cc6337b8b825ae0f 100644 (file)
@@ -782,6 +782,7 @@ protected:
   std::error_code getSectionName(DataRefImpl Sec,
                                  StringRef &Res) const override;
   uint64_t getSectionAddress(DataRefImpl Sec) const override;
+  uint64_t getSectionIndex(DataRefImpl Sec) const override;
   uint64_t getSectionSize(DataRefImpl Sec) const override;
   std::error_code getSectionContents(DataRefImpl Sec,
                                      StringRef &Res) const override;
index d8b58b8079fa0e1ffa2dca8259f51c62d2f1d56b..ef2abd8c52ceec7f8298601c7b49844a52e5c017 100644 (file)
@@ -235,6 +235,7 @@ protected:
   std::error_code getSectionName(DataRefImpl Sec,
                                  StringRef &Res) const override;
   uint64_t getSectionAddress(DataRefImpl Sec) const override;
+  uint64_t getSectionIndex(DataRefImpl Sec) const override;
   uint64_t getSectionSize(DataRefImpl Sec) const override;
   std::error_code getSectionContents(DataRefImpl Sec,
                                      StringRef &Res) const override;
@@ -645,6 +646,17 @@ uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
   return getSection(Sec)->sh_addr;
 }
 
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const {
+  auto SectionsOrErr = EF.sections();
+  handleAllErrors(std::move(SectionsOrErr.takeError()),
+                  [](const ErrorInfoBase &) {
+                    llvm_unreachable("unable to get section index");
+                  });
+  const Elf_Shdr *First = SectionsOrErr->begin();
+  return getSection(Sec) - First;
+}
+
 template <class ELFT>
 uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
   return getSection(Sec)->sh_size;
index 29553558f72f50327a26213879991174f0063383..a4356d5977b20aca899509f7eb2bca7d578e3be8 100644 (file)
@@ -290,6 +290,7 @@ public:
   std::error_code getSectionName(DataRefImpl Sec,
                                  StringRef &Res) const override;
   uint64_t getSectionAddress(DataRefImpl Sec) const override;
+  uint64_t getSectionIndex(DataRefImpl Sec) const override;
   uint64_t getSectionSize(DataRefImpl Sec) const override;
   std::error_code getSectionContents(DataRefImpl Sec,
                                      StringRef &Res) const override;
index 9a7bc618ffd0acf318643f48db36787418d0261a..ea6a9049bc1b319869eba97f07145f7e5244ec0c 100644 (file)
@@ -95,6 +95,7 @@ public:
 
   std::error_code getName(StringRef &Result) const;
   uint64_t getAddress() const;
+  uint64_t getIndex() const;
   uint64_t getSize() const;
   std::error_code getContents(StringRef &Result) const;
 
@@ -222,6 +223,7 @@ protected:
   virtual std::error_code getSectionName(DataRefImpl Sec,
                                          StringRef &Res) const = 0;
   virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
+  virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
   virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
   virtual std::error_code getSectionContents(DataRefImpl Sec,
                                              StringRef &Res) const = 0;
@@ -393,6 +395,10 @@ inline uint64_t SectionRef::getAddress() const {
   return OwningObject->getSectionAddress(SectionPimpl);
 }
 
+inline uint64_t SectionRef::getIndex() const {
+  return OwningObject->getSectionIndex(SectionPimpl);
+}
+
 inline uint64_t SectionRef::getSize() const {
   return OwningObject->getSectionSize(SectionPimpl);
 }
index d200d4a148e3551ece34de2dc79e9304e78b1112..de54a4928cce73dfd29c6b3218633884614e8acf 100644 (file)
@@ -119,6 +119,7 @@ public:
   std::error_code getSectionName(DataRefImpl Sec,
                                  StringRef &Res) const override;
   uint64_t getSectionAddress(DataRefImpl Sec) const override;
+  uint64_t getSectionIndex(DataRefImpl Sec) const override;
   uint64_t getSectionSize(DataRefImpl Sec) const override;
   std::error_code getSectionContents(DataRefImpl Sec,
                                      StringRef &Res) const override;
index 896837c85473818e81f78e791dc5294773c80e82..c326f39fbdea15d79b41393ae5472770444fb5ae 100644 (file)
@@ -60,12 +60,15 @@ typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
 
 uint64_t llvm::getRelocatedValue(const DataExtractor &Data, uint32_t Size,
-                                 uint32_t *Off, const RelocAddrMap *Relocs) {
+                                 uint32_t *Off, const RelocAddrMap *Relocs,
+                                 uint64_t *SectionIndex) {
   if (!Relocs)
     return Data.getUnsigned(Off, Size);
   RelocAddrMap::const_iterator AI = Relocs->find(*Off);
   if (AI == Relocs->end())
     return Data.getUnsigned(Off, Size);
+  if (SectionIndex)
+    *SectionIndex = AI->second.SectionIndex;
   return Data.getUnsigned(Off, Size) + AI->second.Value;
 }
 
@@ -958,23 +961,27 @@ static Error createError(const Twine &Reason, llvm::Error E) {
                                  inconvertibleErrorCode());
 }
 
-/// Returns the address of symbol relocation used against. Used for futher
-/// relocations computation. Symbol's section load address is taken in account if
-/// LoadedObjectInfo interface is provided.
-static Expected<uint64_t>
-getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc,
-                 const LoadedObjectInfo *L,
-                 std::map<SymbolRef, uint64_t> &Cache) {
-  uint64_t Ret = 0;
+struct SymInfo {
+  uint64_t Address;
+  uint64_t SectionIndex;
+};
+
+/// Returns the address of symbol relocation used against and a section index.
+/// Used for futher relocations computation. Symbol's section load address is
+static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj,
+                                       const RelocationRef &Reloc,
+                                       const LoadedObjectInfo *L,
+                                       std::map<SymbolRef, SymInfo> &Cache) {
+  SymInfo Ret;
   object::section_iterator RSec = Obj.section_end();
   object::symbol_iterator Sym = Reloc.getSymbol();
 
-  std::map<SymbolRef, uint64_t>::iterator CacheIt = Cache.end();
+  std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
   // First calculate the address of the symbol or section as it appears
   // in the object file
   if (Sym != Obj.symbol_end()) {
     bool New;
-    std::tie(CacheIt, New) = Cache.insert({*Sym, 0});
+    std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
     if (!New)
       return CacheIt->second;
 
@@ -990,12 +997,14 @@ getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc,
                          SectOrErr.takeError());
 
     RSec = *SectOrErr;
-    Ret = *SymAddrOrErr;
+    Ret.Address = *SymAddrOrErr;
   } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
     RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
-    Ret = RSec->getAddress();
+    Ret.Address = RSec->getAddress();
   }
 
+  Ret.SectionIndex = RSec->getIndex();
+
   // If we are given load addresses for the sections, we need to adjust:
   // SymAddr = (Address of Symbol Or Section in File) -
   //           (Address of Section in File) +
@@ -1005,7 +1014,7 @@ getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc,
   // we need to perform the same computation.
   if (L && RSec != Obj.section_end())
     if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
-      Ret += SectionLoadAddress - RSec->getAddress();
+      Ret.Address += SectionLoadAddress - RSec->getAddress();
 
   if (CacheIt != Cache.end())
     CacheIt->second = Ret;
@@ -1064,7 +1073,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
     // Try to obtain an already relocated version of this section.
     // Else use the unrelocated section from the object file. We'll have to
     // apply relocations ourselves later.
-    if (!L || !L->getLoadedSectionContents(*RelocatedSection,data))
+    if (!L || !L->getLoadedSectionContents(*RelocatedSection, data))
       Section.getContents(data);
 
     if (auto Err = maybeDecompress(Section, name, data)) {
@@ -1103,7 +1112,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
     // If the section we're relocating was relocated already by the JIT,
     // then we used the relocated version above, so we do not need to process
     // relocations for it now.
-    if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData))
+    if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
       continue;
 
     // In Mach-o files, the relocations do not need to be applied if
@@ -1147,29 +1156,30 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
     if (Section.relocation_begin() == Section.relocation_end())
       continue;
 
-    std::map<SymbolRef, uint64_t> AddrCache;
+    // Symbol to [address, section index] cache mapping.
+    std::map<SymbolRef, SymInfo> AddrCache;
     for (const RelocationRef &Reloc : Section.relocations()) {
       // FIXME: it's not clear how to correctly handle scattered
       // relocations.
       if (isRelocScattered(Obj, Reloc))
         continue;
 
-      Expected<uint64_t> SymAddrOrErr =
-          getSymbolAddress(Obj, Reloc, L, AddrCache);
-      if (!SymAddrOrErr) {
-        errs() << toString(SymAddrOrErr.takeError()) << '\n';
+      Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache);
+      if (!SymInfoOrErr) {
+        errs() << toString(SymInfoOrErr.takeError()) << '\n';
         continue;
       }
 
       object::RelocVisitor V(Obj);
-      uint64_t Val = V.visit(Reloc.getType(), Reloc, *SymAddrOrErr);
+      uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
       if (V.error()) {
         SmallString<32> Name;
         Reloc.getTypeName(Name);
         errs() << "error: failed to compute relocation: " << Name << "\n";
         continue;
       }
-      Map->insert({Reloc.getOffset(), {Val}});
+      llvm::RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
+      Map->insert({Reloc.getOffset(), Rel});
     }
   }
 }
index 8da797750abd4c3ef36d8101a64717ea9b5456f7..6b5e1d3c931b968b8537f5528632cab51a059890 100644 (file)
@@ -35,8 +35,8 @@ bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr,
   while (true) {
     RangeListEntry entry;
     uint32_t prev_offset = *offset_ptr;
-    entry.StartAddress =
-        getRelocatedValue(data, AddressSize, offset_ptr, &Relocs);
+    entry.StartAddress = getRelocatedValue(data, AddressSize, offset_ptr,
+                                           &Relocs, &entry.SectionIndex);
     entry.EndAddress =
         getRelocatedValue(data, AddressSize, offset_ptr, &Relocs);
 
@@ -69,8 +69,8 @@ DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
     if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
       BaseAddress = RLE.EndAddress;
     } else {
-      Res.push_back(
-          {BaseAddress + RLE.StartAddress, BaseAddress + RLE.EndAddress});
+      Res.push_back({BaseAddress + RLE.StartAddress,
+                     BaseAddress + RLE.EndAddress, RLE.SectionIndex});
     }
   }
   return Res;
index e3bd759ba94bc6017299ac9b5fc6b5cd00d98996..fd45c77d3745dc3a5d4a8c8e471ac0e185a0b738 100644 (file)
@@ -211,13 +211,16 @@ Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
   return None;
 }
 
-bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const {
-  auto LowPcAddr = toAddress(find(DW_AT_low_pc));
+bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
+                               uint64_t &SectionIndex) const {
+  auto F = find(DW_AT_low_pc);
+  auto LowPcAddr = toAddress(F);
   if (!LowPcAddr)
     return false;
   if (auto HighPcAddr = getHighPC(*LowPcAddr)) {
     LowPC = *LowPcAddr;
     HighPC = *HighPcAddr;
+    SectionIndex = F->getSectionIndex();
     return true;
   }
   return false;
@@ -228,9 +231,9 @@ DWARFDie::getAddressRanges() const {
   if (isNULL())
     return DWARFAddressRangesVector();
   // Single range specified by low/high PC.
-  uint64_t LowPC, HighPC;
-  if (getLowAndHighPC(LowPC, HighPC))
-    return {{LowPC, HighPC}};
+  uint64_t LowPC, HighPC, Index;
+  if (getLowAndHighPC(LowPC, HighPC, Index))
+    return {{LowPC, HighPC, Index}};
 
   // Multiple ranges from .debug_ranges section.
   auto RangesOffset = toSectionOffset(find(DW_AT_ranges));
index 1cbd3ea2c869c63cd60cff20f2cd0fadac3b0804..0963d7bfd7135e46bd4a78e7909c713f10d9a3ca 100644 (file)
@@ -333,8 +333,8 @@ bool DWARFFormValue::extractValue(const DataExtractor &Data,
         return false;
       uint16_t AddrSize = (Form == DW_FORM_addr) ? U->getAddressByteSize()
                                                  : U->getRefAddrByteSize();
-      Value.uval =
-          getRelocatedValue(Data, AddrSize, OffsetPtr, U->getRelocMap());
+      Value.uval = getRelocatedValue(Data, AddrSize, OffsetPtr,
+                                     U->getRelocMap(), &Value.SectionIndex);
       break;
     }
     case DW_FORM_exprloc:
index 28531feccfe1a893f59c0af333393881ca593937..7372f24cb9a8e39d99646bf238a59c6a61a7ee10 100644 (file)
@@ -293,6 +293,10 @@ uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const {
   return Result;
 }
 
+uint64_t COFFObjectFile::getSectionIndex(DataRefImpl Sec) const {
+  return toSec(Sec) - SectionTable;
+}
+
 uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
   return getSectionSize(toSec(Ref));
 }
index 3d3fa07db3f48af07205aa626796a8fd763641b7..bfb8875f47d4a232367cc602172c8485f4180f33 100644 (file)
@@ -1820,6 +1820,10 @@ uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
   return getSection(Sec).addr;
 }
 
+uint64_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
+  return Sec.d.a;
+}
+
 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
   // In the case if a malformed Mach-O file where the section offset is past
   // the end of the file or some part of the section size is past the end of
index 058686e4db9e936799ccf539ed7a914277da9d87..f565d7a33e55d6d84434a6fd773e76ea8b2253b6 100644 (file)
@@ -743,6 +743,10 @@ std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec,
 
 uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; }
 
+uint64_t WasmObjectFile::getSectionIndex(DataRefImpl Sec) const {
+  return Sec.d.a;
+}
+
 uint64_t WasmObjectFile::getSectionSize(DataRefImpl Sec) const {
   const WasmSection &S = Sections[Sec.d.a];
   return S.Content.size();
index 56d7f350e8ed1908756b5db84258873c5a59a9d0..9e846674648cbfa7b649af116389bd5e685bb158 100644 (file)
@@ -853,8 +853,8 @@ template <uint16_t Version, class AddrType> void TestAddresses() {
   // Get the compile unit DIE is valid.
   auto DieDG = U->getUnitDIE(false);
   EXPECT_TRUE(DieDG.isValid());
-  
-  uint64_t LowPC, HighPC;
+
+  uint64_t LowPC, HighPC, SectionIndex;
   Optional<uint64_t> OptU64;
   // Verify the that our subprogram with no PC value fails appropriately when
   // asked for any PC values.
@@ -865,14 +865,14 @@ template <uint16_t Version, class AddrType> void TestAddresses() {
   EXPECT_FALSE((bool)OptU64);
   OptU64 = toAddress(SubprogramDieNoPC.find(DW_AT_high_pc));
   EXPECT_FALSE((bool)OptU64);
-  EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC));
+  EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
   OptU64 = toAddress(SubprogramDieNoPC.find(DW_AT_high_pc));
   EXPECT_FALSE((bool)OptU64);
   OptU64 = toUnsigned(SubprogramDieNoPC.find(DW_AT_high_pc));
   EXPECT_FALSE((bool)OptU64);
   OptU64 = SubprogramDieNoPC.getHighPC(ActualLowPC);
   EXPECT_FALSE((bool)OptU64);
-  EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC));
+  EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
  
   // Verify the that our subprogram with only a low PC value succeeds when
   // we ask for the Low PC, but fails appropriately when asked for the high PC
@@ -889,7 +889,7 @@ template <uint16_t Version, class AddrType> void TestAddresses() {
   EXPECT_FALSE((bool)OptU64);
   OptU64 = SubprogramDieLowPC.getHighPC(ActualLowPC);
   EXPECT_FALSE((bool)OptU64);
-  EXPECT_FALSE(SubprogramDieLowPC.getLowAndHighPC(LowPC, HighPC));
+  EXPECT_FALSE(SubprogramDieLowPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
 
   // Verify the that our subprogram with only a low PC value succeeds when
   // we ask for the Low PC, but fails appropriately when asked for the high PC
@@ -923,7 +923,7 @@ template <uint16_t Version, class AddrType> void TestAddresses() {
   EXPECT_TRUE((bool)OptU64);
   EXPECT_EQ(OptU64.getValue(), ActualHighPC);
 
-  EXPECT_TRUE(SubprogramDieLowHighPC.getLowAndHighPC(LowPC, HighPC));
+  EXPECT_TRUE(SubprogramDieLowHighPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
   EXPECT_EQ(LowPC, ActualLowPC);
   EXPECT_EQ(HighPC, ActualHighPC);
 }