16b6b8c4fSAdrian McCarthy //===- PublicsStream.cpp - PDB Public Symbol Stream -----------------------===//
26b6b8c4fSAdrian McCarthy //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66b6b8c4fSAdrian McCarthy //
76b6b8c4fSAdrian McCarthy //===----------------------------------------------------------------------===//
86b6b8c4fSAdrian McCarthy //
96b6b8c4fSAdrian McCarthy // The data structures defined in this file are based on the reference
106b6b8c4fSAdrian McCarthy // implementation which is available at
116b6b8c4fSAdrian McCarthy // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
126b6b8c4fSAdrian McCarthy //
136b6b8c4fSAdrian McCarthy // When you are reading the reference source code, you'd find the
146b6b8c4fSAdrian McCarthy // information below useful.
156b6b8c4fSAdrian McCarthy //
166b6b8c4fSAdrian McCarthy // - ppdb1->m_fMinimalDbgInfo seems to be always true.
176b6b8c4fSAdrian McCarthy // - SMALLBUCKETS macro is defined.
186b6b8c4fSAdrian McCarthy //
196b6b8c4fSAdrian McCarthy // The reference doesn't compile, so I learned just by reading code.
206b6b8c4fSAdrian McCarthy // It's not guaranteed to be correct.
216b6b8c4fSAdrian McCarthy //
226b6b8c4fSAdrian McCarthy //===----------------------------------------------------------------------===//
236b6b8c4fSAdrian McCarthy
246b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
256b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
266b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/RawError.h"
27*ed98c1b3Sserge-sans-paille #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
28d9dc2829SZachary Turner #include "llvm/Support/BinaryStreamReader.h"
296b6b8c4fSAdrian McCarthy #include "llvm/Support/Endian.h"
306b6b8c4fSAdrian McCarthy #include "llvm/Support/Error.h"
316b6b8c4fSAdrian McCarthy #include <cstdint>
326b6b8c4fSAdrian McCarthy
336b6b8c4fSAdrian McCarthy using namespace llvm;
346b6b8c4fSAdrian McCarthy using namespace llvm::msf;
356b6b8c4fSAdrian McCarthy using namespace llvm::support;
366b6b8c4fSAdrian McCarthy using namespace llvm::pdb;
376b6b8c4fSAdrian McCarthy
PublicsStream(std::unique_ptr<MappedBlockStream> Stream)3814d90fd0SReid Kleckner PublicsStream::PublicsStream(std::unique_ptr<MappedBlockStream> Stream)
3914d90fd0SReid Kleckner : Stream(std::move(Stream)) {}
406b6b8c4fSAdrian McCarthy
416b6b8c4fSAdrian McCarthy PublicsStream::~PublicsStream() = default;
426b6b8c4fSAdrian McCarthy
getSymHash() const436b6b8c4fSAdrian McCarthy uint32_t PublicsStream::getSymHash() const { return Header->SymHash; }
getThunkTableSection() const445448dabbSZachary Turner uint16_t PublicsStream::getThunkTableSection() const {
455448dabbSZachary Turner return Header->ISectThunkTable;
465448dabbSZachary Turner }
getThunkTableOffset() const475448dabbSZachary Turner uint32_t PublicsStream::getThunkTableOffset() const {
485448dabbSZachary Turner return Header->OffThunkTable;
495448dabbSZachary Turner }
506b6b8c4fSAdrian McCarthy
516b6b8c4fSAdrian McCarthy // Publics stream contains fixed-size headers and a serialized hash table.
526b6b8c4fSAdrian McCarthy // This implementation is not complete yet. It reads till the end of the
536b6b8c4fSAdrian McCarthy // stream so that we verify the stream is at least not corrupted. However,
546b6b8c4fSAdrian McCarthy // we skip over the hash table which we believe contains information about
556b6b8c4fSAdrian McCarthy // public symbols.
reload()566b6b8c4fSAdrian McCarthy Error PublicsStream::reload() {
57120faca4SZachary Turner BinaryStreamReader Reader(*Stream);
586b6b8c4fSAdrian McCarthy
596b6b8c4fSAdrian McCarthy // Check stream size.
607eaf1d96SZachary Turner if (Reader.bytesRemaining() <
617eaf1d96SZachary Turner sizeof(PublicsStreamHeader) + sizeof(GSIHashHeader))
626b6b8c4fSAdrian McCarthy return make_error<RawError>(raw_error_code::corrupt_file,
636b6b8c4fSAdrian McCarthy "Publics Stream does not contain a header.");
646b6b8c4fSAdrian McCarthy
6514d90fd0SReid Kleckner // Read PSGSIHDR struct.
666b6b8c4fSAdrian McCarthy if (Reader.readObject(Header))
676b6b8c4fSAdrian McCarthy return make_error<RawError>(raw_error_code::corrupt_file,
686b6b8c4fSAdrian McCarthy "Publics Stream does not contain a header.");
696b6b8c4fSAdrian McCarthy
7014d90fd0SReid Kleckner // Read the hash table.
7114d90fd0SReid Kleckner if (auto E = PublicsTable.read(Reader))
7214d90fd0SReid Kleckner return E;
736b6b8c4fSAdrian McCarthy
746b6b8c4fSAdrian McCarthy // Something called "address map" follows.
756b6b8c4fSAdrian McCarthy uint32_t NumAddressMapEntries = Header->AddrMap / sizeof(uint32_t);
766b6b8c4fSAdrian McCarthy if (auto EC = Reader.readArray(AddressMap, NumAddressMapEntries))
776b6b8c4fSAdrian McCarthy return joinErrors(std::move(EC),
786b6b8c4fSAdrian McCarthy make_error<RawError>(raw_error_code::corrupt_file,
796b6b8c4fSAdrian McCarthy "Could not read an address map."));
806b6b8c4fSAdrian McCarthy
816b6b8c4fSAdrian McCarthy // Something called "thunk map" follows.
826b6b8c4fSAdrian McCarthy if (auto EC = Reader.readArray(ThunkMap, Header->NumThunks))
836b6b8c4fSAdrian McCarthy return joinErrors(std::move(EC),
846b6b8c4fSAdrian McCarthy make_error<RawError>(raw_error_code::corrupt_file,
856b6b8c4fSAdrian McCarthy "Could not read a thunk map."));
866b6b8c4fSAdrian McCarthy
876b6b8c4fSAdrian McCarthy // Something called "section map" follows.
88349c18f8SZachary Turner if (Reader.bytesRemaining() > 0) {
896b6b8c4fSAdrian McCarthy if (auto EC = Reader.readArray(SectionOffsets, Header->NumSections))
906b6b8c4fSAdrian McCarthy return joinErrors(std::move(EC),
916b6b8c4fSAdrian McCarthy make_error<RawError>(raw_error_code::corrupt_file,
926b6b8c4fSAdrian McCarthy "Could not read a section map."));
93349c18f8SZachary Turner }
946b6b8c4fSAdrian McCarthy
956b6b8c4fSAdrian McCarthy if (Reader.bytesRemaining() > 0)
966b6b8c4fSAdrian McCarthy return make_error<RawError>(raw_error_code::corrupt_file,
976b6b8c4fSAdrian McCarthy "Corrupted publics stream.");
986b6b8c4fSAdrian McCarthy return Error::success();
996b6b8c4fSAdrian McCarthy }
100