mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-18 11:26:29 +00:00

Summary: This is a first step towards getting line info to show up in VS and windbg. So far, only llvm-pdbutil can parse the PDBs that we produce. cvdump doesn't like something about our file checksum tables. I'll have to dig into that next. This patch adds a new DebugSubsectionRecordBuilder which takes bytes directly from some other producer, such as a linker, and sticks it into the PDB. Line tables only need to be relocated. No data needs to be rewritten. File checksums and string tables, on the other hand, need to be re-done. Reviewers: zturner, ruiu Subscribers: llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D34257 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305713 91177308-0d34-0410-b5e6-96231b3b80d8
94 lines
3.4 KiB
C++
94 lines
3.4 KiB
C++
//===- DebugSubsectionRecord.cpp -----------------------------*- C++-*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
|
|
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
|
|
|
|
#include "llvm/Support/BinaryStreamReader.h"
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::codeview;
|
|
|
|
DebugSubsectionRecord::DebugSubsectionRecord()
|
|
: Container(CodeViewContainer::ObjectFile),
|
|
Kind(DebugSubsectionKind::None) {}
|
|
|
|
DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind,
|
|
BinaryStreamRef Data,
|
|
CodeViewContainer Container)
|
|
: Container(Container), Kind(Kind), Data(Data) {}
|
|
|
|
Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream,
|
|
DebugSubsectionRecord &Info,
|
|
CodeViewContainer Container) {
|
|
const DebugSubsectionHeader *Header;
|
|
BinaryStreamReader Reader(Stream);
|
|
if (auto EC = Reader.readObject(Header))
|
|
return EC;
|
|
|
|
DebugSubsectionKind Kind =
|
|
static_cast<DebugSubsectionKind>(uint32_t(Header->Kind));
|
|
if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))
|
|
return EC;
|
|
Info.Container = Container;
|
|
Info.Kind = Kind;
|
|
return Error::success();
|
|
}
|
|
|
|
uint32_t DebugSubsectionRecord::getRecordLength() const {
|
|
return sizeof(DebugSubsectionHeader) + Data.getLength();
|
|
}
|
|
|
|
DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; }
|
|
|
|
BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; }
|
|
|
|
DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
|
|
std::shared_ptr<DebugSubsection> Subsection, CodeViewContainer Container)
|
|
: Subsection(std::move(Subsection)), Container(Container) {}
|
|
|
|
DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
|
|
const DebugSubsectionRecord &Contents, CodeViewContainer Container)
|
|
: Contents(Contents), Container(Container) {}
|
|
|
|
uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() {
|
|
uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
|
|
: Contents.getRecordData().getLength();
|
|
// The length of the entire subsection is always padded to 4 bytes,
|
|
// regardless of the container kind.
|
|
return sizeof(DebugSubsectionHeader) + alignTo(DataSize, 4);
|
|
}
|
|
|
|
Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) const {
|
|
assert(Writer.getOffset() % alignOf(Container) == 0 &&
|
|
"Debug Subsection not properly aligned");
|
|
|
|
DebugSubsectionHeader Header;
|
|
Header.Kind = uint32_t(Subsection ? Subsection->kind() : Contents.kind());
|
|
// The value written into the Header's Length field is only padded to the
|
|
// container's alignment
|
|
uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
|
|
: Contents.getRecordData().getLength();
|
|
Header.Length = alignTo(DataSize, alignOf(Container));
|
|
|
|
if (auto EC = Writer.writeObject(Header))
|
|
return EC;
|
|
if (Subsection) {
|
|
if (auto EC = Subsection->commit(Writer))
|
|
return EC;
|
|
} else {
|
|
if (auto EC = Writer.writeStreamRef(Contents.getRecordData()))
|
|
return EC;
|
|
}
|
|
if (auto EC = Writer.padToAlignment(4))
|
|
return EC;
|
|
|
|
return Error::success();
|
|
}
|