blob: adf5412e8cac1a1bc08eaba93750e1e01e579340 [file] [log] [blame]
//===- SymbolStream.cpp - PDB Symbol Stream Access ------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Raw/SymbolStream.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
using namespace llvm::support;
using namespace llvm::pdb;
// Symbol stream is an array of symbol records. Each record starts with
// length and type fields followed by type-specfic fields.
namespace {
struct SymbolHeader {
ulittle16_t Len; // Record length
ulittle16_t Type;
};
// For S_PUB32 symbol type.
struct DataSym32 {
ulittle32_t TypIndex; // Type index, or Metadata token if a managed symbol
ulittle32_t off;
ulittle16_t seg;
char name[1];
};
// For S_PROCREF symbol type.
struct RefSym {
ulittle32_t SumName; // SUC of the name (?)
ulittle32_t SymOffset; // Offset of actual symbol in $$Symbols
ulittle16_t Mod; // Module containing the actual symbol
char name[1];
};
}
SymbolStream::SymbolStream(PDBFile &File, uint32_t StreamNum)
: Stream(StreamNum, File) {}
SymbolStream::~SymbolStream() {}
Error SymbolStream::reload() { return Error::success(); }
static StringRef makeStringRef(char *p) { return {p, strlen(p)}; }
Expected<std::string> SymbolStream::getSymbolName(uint32_t Off) const {
StreamReader Reader(Stream);
Reader.setOffset(Off);
// Read length field.
SymbolHeader Hdr;
if (Reader.readObject(&Hdr))
return make_error<RawError>(raw_error_code::corrupt_file,
"Corrupted symbol stream.");
// Read the entire record.
std::vector<uint8_t> Buf(Hdr.Len - sizeof(Hdr.Type));
if (Reader.readBytes(Buf))
return make_error<RawError>(raw_error_code::corrupt_file,
"Corrupted symbol stream.");
switch (Hdr.Type) {
case codeview::S_PUB32:
return makeStringRef(reinterpret_cast<DataSym32 *>(Buf.data())->name);
case codeview::S_PROCREF:
return makeStringRef(reinterpret_cast<RefSym *>(Buf.data())->name);
default:
return make_error<RawError>(raw_error_code::corrupt_file,
"Unknown symbol type");
}
return Error::success();
}