[llvm] r285606 - Define DbiStreamBuilder::addSectionMap.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 31 10:38:56 PDT 2016
Author: ruiu
Date: Mon Oct 31 12:38:56 2016
New Revision: 285606
URL: http://llvm.org/viewvc/llvm-project?rev=285606&view=rev
Log:
Define DbiStreamBuilder::addSectionMap.
This change enables LLD to construct a Section Map stream in a PDB file.
I do not understand all these fields in the Section Map yet, but it seems
like a copy of a COFF section header in another format.
With this patch, DbiStreamBuilder can emit a Section Map which
llvm-pdbdump can dump.
Differential Revision: https://reviews.llvm.org/D26112
Modified:
llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h?rev=285606&r1=285605&r2=285606&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h Mon Oct 31 12:38:56 2016
@@ -25,6 +25,9 @@ namespace llvm {
namespace msf {
class MSFBuilder;
}
+namespace object {
+struct coff_section;
+}
namespace pdb {
class DbiStream;
struct DbiStreamHeader;
@@ -44,6 +47,7 @@ public:
void setPdbDllRbld(uint16_t R);
void setFlags(uint16_t F);
void setMachineType(PDB_Machine M);
+ void setSectionMap(ArrayRef<SecMapEntry> SecMap);
// Add given bytes as a new stream.
Error addDbgStream(pdb::DbgHeaderType Type, ArrayRef<uint8_t> Data);
@@ -60,6 +64,10 @@ public:
Error commit(const msf::MSFLayout &Layout,
const msf::WritableStream &Buffer);
+ // A helper function to create a Section Map from a COFF section header.
+ static std::vector<SecMapEntry>
+ createSectionMap(ArrayRef<llvm::object::coff_section> SecHdrs);
+
private:
struct DebugStream {
ArrayRef<uint8_t> Data;
@@ -68,6 +76,7 @@ private:
Error finalize();
uint32_t calculateModiSubstreamSize() const;
+ uint32_t calculateSectionMapStreamSize() const;
uint32_t calculateFileInfoSubstreamSize() const;
uint32_t calculateNamesBufferSize() const;
uint32_t calculateDbgStreamsSize() const;
@@ -102,6 +111,7 @@ private:
msf::WritableStreamRef NamesBuffer;
msf::MutableByteStream ModInfoBuffer;
msf::MutableByteStream FileInfoBuffer;
+ ArrayRef<SecMapEntry> SectionMap;
llvm::SmallVector<DebugStream, (int)DbgHeaderType::Max> DbgStreams;
};
}
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp?rev=285606&r1=285605&r2=285606&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp Mon Oct 31 12:38:56 2016
@@ -15,6 +15,8 @@
#include "llvm/DebugInfo/MSF/StreamWriter.h"
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/COFF.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -44,6 +46,10 @@ void DbiStreamBuilder::setFlags(uint16_t
void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; }
+void DbiStreamBuilder::setSectionMap(ArrayRef<SecMapEntry> SecMap) {
+ SectionMap = SecMap;
+}
+
Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
ArrayRef<uint8_t> Data) {
if (DbgStreams[(int)Type].StreamNumber)
@@ -61,7 +67,8 @@ Error DbiStreamBuilder::addDbgStream(pdb
uint32_t DbiStreamBuilder::calculateSerializedLength() const {
// For now we only support serializing the header.
return sizeof(DbiStreamHeader) + calculateFileInfoSubstreamSize() +
- calculateModiSubstreamSize() + calculateDbgStreamsSize();
+ calculateModiSubstreamSize() + calculateSectionMapStreamSize() +
+ calculateDbgStreamsSize();
}
Error DbiStreamBuilder::addModuleInfo(StringRef ObjFile, StringRef Module) {
@@ -99,6 +106,12 @@ uint32_t DbiStreamBuilder::calculateModi
return Size;
}
+uint32_t DbiStreamBuilder::calculateSectionMapStreamSize() const {
+ if (SectionMap.empty())
+ return 0;
+ return sizeof(SecMapHeader) + sizeof(SecMapEntry) * SectionMap.size();
+}
+
uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const {
uint32_t Size = 0;
Size += sizeof(ulittle16_t); // NumModules
@@ -237,7 +250,7 @@ Error DbiStreamBuilder::finalize() {
H->ModiSubstreamSize = ModInfoBuffer.getLength();
H->OptionalDbgHdrSize = DbgStreams.size() * sizeof(uint16_t);
H->SecContrSubstreamSize = 0;
- H->SectionMapSize = 0;
+ H->SectionMapSize = calculateSectionMapStreamSize();
H->TypeServerSize = 0;
H->SymRecordStreamIndex = kInvalidStreamIndex;
H->PublicSymbolStreamIndex = kInvalidStreamIndex;
@@ -255,6 +268,65 @@ Error DbiStreamBuilder::finalizeMsfLayou
return Error::success();
}
+static uint16_t toSecMapFlags(uint32_t Flags) {
+ uint16_t Ret = 0;
+ if (Flags & COFF::IMAGE_SCN_MEM_READ)
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::Read);
+ if (Flags & COFF::IMAGE_SCN_MEM_WRITE)
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::Write);
+ if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::Execute);
+ if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::Execute);
+ if (!(Flags & COFF::IMAGE_SCN_MEM_16BIT))
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::AddressIs32Bit);
+
+ // This seems always 1.
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::IsSelector);
+
+ return Ret;
+}
+
+// A utility function to create a Section Map for a given list of COFF sections.
+//
+// A Section Map seem to be a copy of a COFF section list in other format.
+// I don't know why a PDB file contains both a COFF section header and
+// a Section Map, but it seems it must be present in a PDB.
+std::vector<SecMapEntry> DbiStreamBuilder::createSectionMap(
+ ArrayRef<llvm::object::coff_section> SecHdrs) {
+ std::vector<SecMapEntry> Ret;
+ int Idx = 0;
+
+ auto Add = [&]() -> SecMapEntry & {
+ Ret.emplace_back();
+ auto &Entry = Ret.back();
+ memset(&Entry, 0, sizeof(Entry));
+
+ Entry.Frame = Idx + 1;
+
+ // We don't know the meaning of these fields yet.
+ Entry.SecName = UINT16_MAX;
+ Entry.ClassName = UINT16_MAX;
+
+ return Entry;
+ };
+
+ for (auto &Hdr : SecHdrs) {
+ auto &Entry = Add();
+ Entry.Flags = toSecMapFlags(Hdr.Characteristics);
+ Entry.SecByteLength = Hdr.VirtualSize;
+ ++Idx;
+ }
+
+ // The last entry is for absolute symbols.
+ auto &Entry = Add();
+ Entry.Flags = static_cast<uint16_t>(OMFSegDescFlags::AddressIs32Bit) |
+ static_cast<uint16_t>(OMFSegDescFlags::IsAbsoluteAddress);
+ Entry.SecByteLength = UINT32_MAX;
+
+ return Ret;
+}
+
Expected<std::unique_ptr<DbiStream>>
DbiStreamBuilder::build(PDBFile &File, const msf::WritableStream &Buffer) {
if (!VerHeader.hasValue())
@@ -290,8 +362,19 @@ Error DbiStreamBuilder::commit(const msf
if (auto EC = Writer.writeStreamRef(ModInfoBuffer))
return EC;
+
+ if (!SectionMap.empty()) {
+ ulittle16_t Size = static_cast<ulittle16_t>(SectionMap.size());
+ SecMapHeader SMHeader = {Size, Size};
+ if (auto EC = Writer.writeObject(SMHeader))
+ return EC;
+ if (auto EC = Writer.writeArray(SectionMap))
+ return EC;
+ }
+
if (auto EC = Writer.writeStreamRef(FileInfoBuffer))
return EC;
+
for (auto &Stream : DbgStreams)
if (auto EC = Writer.writeInteger(Stream.StreamNumber))
return EC;
More information about the llvm-commits
mailing list