diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -70,10 +70,14 @@
 
 public:
   /// Parse a unit header from \p debug_info starting at \p offset_ptr.
+  /// Note that \p SectionKind is used as a hint to guess the unit type
+  /// for DWARF formats prior to DWARFv5. In DWARFv5 the unit type is
+  /// explicitly defined in the header and the hint is ignored.
   bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info,
-               uint64_t *offset_ptr, DWARFSectionKind Kind = DW_SECT_INFO,
-               const DWARFUnitIndex *Index = nullptr,
-               const DWARFUnitIndex::Entry *Entry = nullptr);
+               uint64_t *offset_ptr, DWARFSectionKind SectionKind);
+  // For units in DWARF Package File, remember the index entry and update
+  // the abbreviation offset read by extract().
+  bool applyIndexEntry(const DWARFUnitIndex::Entry *Entry);
   uint64_t getOffset() const { return Offset; }
   const dwarf::FormParams &getFormParams() const { return FormParams; }
   uint16_t getVersion() const { return FormParams.Version; }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -73,12 +73,15 @@
       DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
       if (!Data.isValidOffset(Offset))
         return nullptr;
-      const DWARFUnitIndex *Index = nullptr;
-      if (IsDWO)
-        Index = &getDWARFUnitIndex(Context, SectionKind);
       DWARFUnitHeader Header;
-      if (!Header.extract(Context, Data, &Offset, SectionKind, Index,
-                          IndexEntry))
+      if (!Header.extract(Context, Data, &Offset, SectionKind))
+        return nullptr;
+      if (!IndexEntry && IsDWO) {
+        const DWARFUnitIndex &Index = getDWARFUnitIndex(
+            Context, Header.isTypeUnit() ? DW_SECT_EXT_TYPES : DW_SECT_INFO);
+        IndexEntry = Index.getFromOffset(Header.getOffset());
+      }
+      if (IndexEntry && !Header.applyIndexEntry(IndexEntry))
         return nullptr;
       std::unique_ptr<DWARFUnit> U;
       if (Header.isTypeUnit())
@@ -251,14 +254,10 @@
 bool DWARFUnitHeader::extract(DWARFContext &Context,
                               const DWARFDataExtractor &debug_info,
                               uint64_t *offset_ptr,
-                              DWARFSectionKind SectionKind,
-                              const DWARFUnitIndex *Index,
-                              const DWARFUnitIndex::Entry *Entry) {
+                              DWARFSectionKind SectionKind) {
   Offset = *offset_ptr;
   Error Err = Error::success();
-  IndexEntry = Entry;
-  if (!IndexEntry && Index)
-    IndexEntry = Index->getFromOffset(*offset_ptr);
+  IndexEntry = nullptr;
   std::tie(Length, FormParams.Format) =
       debug_info.getInitialLength(offset_ptr, &Err);
   FormParams.Version = debug_info.getU16(offset_ptr, &Err);
@@ -288,19 +287,6 @@
   if (errorToBool(std::move(Err)))
     return false;
 
-  if (IndexEntry) {
-    if (AbbrOffset)
-      return false;
-    auto *UnitContrib = IndexEntry->getContribution();
-    if (!UnitContrib ||
-        UnitContrib->Length != (Length + getUnitLengthFieldByteSize()))
-      return false;
-    auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
-    if (!AbbrEntry)
-      return false;
-    AbbrOffset = AbbrEntry->Offset;
-  }
-
   // Header fields all parsed, capture the size of this unit header.
   assert(*offset_ptr - Offset <= 255 && "unexpected header size");
   Size = uint8_t(*offset_ptr - Offset);
@@ -324,6 +310,23 @@
   return true;
 }
 
+bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
+  assert(Entry);
+  assert(!IndexEntry);
+  IndexEntry = Entry;
+  if (AbbrOffset)
+    return false;
+  auto *UnitContrib = IndexEntry->getContribution();
+  if (!UnitContrib ||
+      UnitContrib->Length != (getLength() + getUnitLengthFieldByteSize()))
+    return false;
+  auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
+  if (!AbbrEntry)
+    return false;
+  AbbrOffset = AbbrEntry->Offset;
+  return true;
+}
+
 // Parse the rangelist table header, including the optional array of offsets
 // following it (DWARF v5 and later).
 template<typename ListTableType>
diff --git a/llvm/test/DebugInfo/X86/dwp-v5-tu.s b/llvm/test/DebugInfo/X86/dwp-v5-tu.s
new file mode 100644
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/dwp-v5-tu.s
@@ -0,0 +1,76 @@
+## The test checks that we can read DWARFv5 type units in DWP files.
+
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN:   llvm-dwarfdump -debug-info - | \
+# RUN:   FileCheck %s
+
+# CHECK:      .debug_info.dwo contents:
+# CHECK:      Type Unit:
+# CHECK:      DW_TAG_type_unit
+# CHECK-NEXT:   DW_AT_visibility (DW_VIS_local)
+# CHECK:      DW_TAG_structure_type
+# CHECK-NEXT:   DW_AT_name ("foo")
+
+    .section .debug_abbrev.dwo, "e", @progbits
+## Reserve some space in the section so that the abbreviation table for the type
+## unit does not start at the beginning of the section and thus the base offset
+## from the index section should be added to find the correct offset.
+    .space 16
+.LAbbrevBegin:
+    .uleb128 1                              # Abbrev code
+    .uleb128 0x41                           # DW_TAG_type_unit
+    .byte 1                                 # DW_CHILDREN_yes
+    .uleb128 0x17                           # DW_AT_visibility
+    .uleb128 0x0b                           # DW_FORM_data1
+    .byte 0                                 # EOM(1)
+    .byte 0                                 # EOM(2)
+    .uleb128 2                              # Abbrev code
+    .uleb128 0x13                           # DW_TAG_structure_type
+    .byte 0                                 # DW_CHILDREN_no
+    .uleb128 0x03                           # DW_AT_name
+    .uleb128 0x08                           # DW_FORM_string
+    .byte 0                                 # EOM(1)
+    .byte 0                                 # EOM(2)
+    .byte 0                                 # EOM(3)
+.LAbbrevEnd:
+
+    .section .debug_info.dwo, "e", @progbits
+.LTUBegin:
+    .long .LTUEnd-.LTUVersion               # Length of Unit
+.LTUVersion:
+    .short 5                                # DWARF version number
+    .byte 6                                 # DW_UT_split_type
+    .byte 8                                 # Address Size (in bytes)
+    .long 0                                 # Offset Into Abbrev. Section
+    .quad 0x1100001122222222                # Type Signature
+    .long .LTUType-.LTUBegin                # Type offset
+    .uleb128 1                              # Abbrev [1] DW_TAG_type_unit
+    .byte 1                                 # DW_AT_visibility
+.LTUType:
+    .uleb128 2                              # Abbrev [2] DW_TAG_structure_type
+    .asciz "foo"                            # DW_AT_name
+.LTUEnd:
+
+    .section .debug_tu_index, "", @progbits
+## Header:
+    .short 5                                # Version
+    .space 2                                # Padding
+    .long 2                                 # Section count
+    .long 1                                 # Unit count
+    .long 2                                 # Slot count
+## Hash Table of Signatures:
+    .quad 0x1100001122222222
+    .quad 0
+## Parallel Table of Indexes:
+    .long 1
+    .long 0
+## Table of Section Offsets:
+## Row 0:
+    .long 1                                 # DW_SECT_INFO
+    .long 3                                 # DW_SECT_ABBREV
+## Row 1:
+    .long 0                                 # Offset in .debug_info.dwo
+    .long .LAbbrevBegin-.debug_abbrev.dwo   # Offset in .debug_abbrev.dwo
+## Table of Section Sizes:
+    .long .LTUEnd-.LTUBegin                 # Size in .debug_info.dwo
+    .long .LAbbrevEnd-.LAbbrevBegin         # Size in .debug_abbrev.dwo
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
--- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
@@ -3166,7 +3166,7 @@
     DWARFDataExtractor Data(Obj, Sec, /* IsLittleEndian = */ true,
                             /* AddressSize = */ 4);
     uint64_t Offset = 0;
-    EXPECT_FALSE(Header.extract(*Context, Data, &Offset));
+    EXPECT_FALSE(Header.extract(*Context, Data, &Offset, DW_SECT_INFO));
     // Header.extract() returns false because there is not enough space
     // in the section for the declared length. Anyway, we can check that
     // the properties are read correctly.