1//===- InjectedSourceStream.cpp - PDB Headerblock Stream Access -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/DebugInfo/PDB/Native/InjectedSourceStream.h"
10
11#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
12#include "llvm/DebugInfo/PDB/Native/HashTable.h"
13#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
14#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
15#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
16#include "llvm/Support/BinaryStreamReader.h"
17
18using namespace llvm;
19using namespace llvm::msf;
20using namespace llvm::support;
21using namespace llvm::pdb;
22
23InjectedSourceStream::InjectedSourceStream(
24    std::unique_ptr<MappedBlockStream> Stream)
25    : Stream(std::move(Stream)) {}
26
27Error InjectedSourceStream::reload(const PDBStringTable &Strings) {
28  BinaryStreamReader Reader(*Stream);
29
30  if (auto EC = Reader.readObject(Header))
31    return EC;
32
33  if (Header->Version !=
34      static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne))
35    return make_error<RawError>(raw_error_code::corrupt_file,
36                                "Invalid headerblock header version");
37
38  if (auto EC = InjectedSourceTable.load(Reader))
39    return EC;
40
41  for (const auto& Entry : *this) {
42    if (Entry.second.Size != sizeof(SrcHeaderBlockEntry))
43      return make_error<RawError>(raw_error_code::corrupt_file,
44                                  "Invalid headerbock entry size");
45    if (Entry.second.Version !=
46        static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne))
47      return make_error<RawError>(raw_error_code::corrupt_file,
48                                  "Invalid headerbock entry version");
49
50    // Check that all name references are valid.
51    auto Name = Strings.getStringForID(Entry.second.FileNI);
52    if (!Name)
53      return Name.takeError();
54    auto ObjName = Strings.getStringForID(Entry.second.ObjNI);
55    if (!ObjName)
56      return ObjName.takeError();
57    auto VName = Strings.getStringForID(Entry.second.VFileNI);
58    if (!VName)
59      return VName.takeError();
60  }
61
62  assert(Reader.bytesRemaining() == 0);
63  return Error::success();
64}
65