Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- DbiModuleDescriptorBuilder.cpp - PDB Mod Info Creation ---*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
11
12
#include "llvm/ADT/ArrayRef.h"
13
#include "llvm/BinaryFormat/COFF.h"
14
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
15
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
16
#include "llvm/DebugInfo/MSF/MSFCommon.h"
17
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
18
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
19
#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
20
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
21
#include "llvm/DebugInfo/PDB/Native/RawError.h"
22
#include "llvm/Support/BinaryItemStream.h"
23
#include "llvm/Support/BinaryStreamWriter.h"
24
25
using namespace llvm;
26
using namespace llvm::codeview;
27
using namespace llvm::msf;
28
using namespace llvm::pdb;
29
30
static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize,
31
108
                                            uint32_t C13Size) {
32
108
  uint32_t Size = sizeof(uint32_t);   // Signature
33
108
  Size += alignTo(SymbolByteSize, 4); // Symbol Data
34
108
  Size += 0;                          // TODO: Layout.C11Bytes
35
108
  Size += C13Size;                    // C13 Debug Info Size
36
108
  Size += sizeof(uint32_t);           // GlobalRefs substream size (always 0)
37
108
  Size += 0;                          // GlobalRefs substream bytes
38
108
  return Size;
39
108
}
40
41
DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
42
                                                       uint32_t ModIndex,
43
                                                       msf::MSFBuilder &Msf)
44
108
    : MSF(Msf), ModuleName(ModuleName) {
45
108
  ::memset(&Layout, 0, sizeof(Layout));
46
108
  Layout.Mod = ModIndex;
47
108
}
48
49
108
DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder() {}
50
51
0
uint16_t DbiModuleDescriptorBuilder::getStreamIndex() const {
52
0
  return Layout.ModDiStream;
53
0
}
54
55
68
void DbiModuleDescriptorBuilder::setObjFileName(StringRef Name) {
56
68
  ObjFileName = Name;
57
68
}
58
59
40
void DbiModuleDescriptorBuilder::setPdbFilePathNI(uint32_t NI) {
60
40
  PdbFilePathNI = NI;
61
40
}
62
63
498
void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
64
498
  Symbols.push_back(Symbol);
65
498
  // Symbols written to a PDB file are required to be 4 byte aligned.  The same
66
498
  // is not true of object files.
67
498
  assert(Symbol.length() % alignOf(CodeViewContainer::Pdb) == 0 &&
68
498
         "Invalid Symbol alignment!");
69
498
  SymbolByteSize += Symbol.length();
70
498
}
71
72
39
void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
73
39
  SourceFiles.push_back(Path);
74
39
}
75
76
216
uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
77
216
  uint32_t Result = 0;
78
152
  for (const auto &Builder : C13Builders) {
79
152
    assert(Builder && "Empty C13 Fragment Builder!");
80
152
    Result += Builder->calculateSerializedLength();
81
152
  }
82
216
  return Result;
83
216
}
84
85
216
uint32_t DbiModuleDescriptorBuilder::calculateSerializedLength() const {
86
216
  uint32_t L = sizeof(Layout);
87
216
  uint32_t M = ModuleName.size() + 1;
88
216
  uint32_t O = ObjFileName.size() + 1;
89
216
  return alignTo(L + M + O, sizeof(uint32_t));
90
216
}
91
92
108
void DbiModuleDescriptorBuilder::finalize() {
93
108
  Layout.SC.ModuleIndex = Layout.Mod;
94
108
  Layout.FileNameOffs = 0; // TODO: Fix this
95
108
  Layout.Flags = 0;        // TODO: Fix this
96
108
  Layout.C11Bytes = 0;
97
108
  Layout.C13Bytes = calculateC13DebugInfoSize();
98
108
  (void)Layout.Mod;         // Set in constructor
99
108
  (void)Layout.ModDiStream; // Set in finalizeMsfLayout
100
108
  Layout.NumFiles = SourceFiles.size();
101
108
  Layout.PdbFilePathNI = PdbFilePathNI;
102
108
  Layout.SrcFileNameNI = 0;
103
108
104
108
  // This value includes both the signature field as well as the record bytes
105
108
  // from the symbol stream.
106
108
  Layout.SymBytes = SymbolByteSize + sizeof(uint32_t);
107
108
}
108
109
108
Error DbiModuleDescriptorBuilder::finalizeMsfLayout() {
110
108
  this->Layout.ModDiStream = kInvalidStreamIndex;
111
108
  uint32_t C13Size = calculateC13DebugInfoSize();
112
108
  auto ExpectedSN =
113
108
      MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size));
114
108
  if (!ExpectedSN)
115
0
    return ExpectedSN.takeError();
116
108
  Layout.ModDiStream = *ExpectedSN;
117
108
  return Error::success();
118
108
}
119
120
Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
121
                                         const msf::MSFLayout &MsfLayout,
122
108
                                         WritableBinaryStreamRef MsfBuffer) {
123
108
  // We write the Modi record to the `ModiWriter`, but we additionally write its
124
108
  // symbol stream to a brand new stream.
125
108
  if (auto EC = ModiWriter.writeObject(Layout))
126
0
    return EC;
127
108
  
if (auto 108
EC108
= ModiWriter.writeCString(ModuleName))
128
0
    return EC;
129
108
  
if (auto 108
EC108
= ModiWriter.writeCString(ObjFileName))
130
0
    return EC;
131
108
  
if (auto 108
EC108
= ModiWriter.padToAlignment(sizeof(uint32_t)))
132
0
    return EC;
133
108
134
108
  
if (108
Layout.ModDiStream != kInvalidStreamIndex108
) {
135
108
    auto NS = WritableMappedBlockStream::createIndexedStream(
136
108
        MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
137
108
    WritableBinaryStreamRef Ref(*NS);
138
108
    BinaryStreamWriter SymbolWriter(Ref);
139
108
    // Write the symbols.
140
108
    if (auto EC =
141
108
            SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
142
0
      return EC;
143
108
    BinaryItemStream<CVSymbol> Records(llvm::support::endianness::little);
144
108
    Records.setItems(Symbols);
145
108
    BinaryStreamRef RecordsRef(Records);
146
108
    if (auto EC = SymbolWriter.writeStreamRef(RecordsRef))
147
0
      return EC;
148
108
    
if (auto 108
EC108
= SymbolWriter.padToAlignment(4))
149
0
      return EC;
150
108
    // TODO: Write C11 Line data
151
108
    assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
152
108
           "Invalid debug section alignment!");
153
76
    for (const auto &Builder : C13Builders) {
154
76
      assert(Builder && "Empty C13 Fragment Builder!");
155
76
      if (auto EC = Builder->commit(SymbolWriter))
156
0
        return EC;
157
108
    }
158
108
159
108
    // TODO: Figure out what GlobalRefs substream actually is and populate it.
160
108
    
if (auto 108
EC108
= SymbolWriter.writeInteger<uint32_t>(0))
161
0
      return EC;
162
108
    
if (108
SymbolWriter.bytesRemaining() > 0108
)
163
0
      return make_error<RawError>(raw_error_code::stream_too_long);
164
108
  }
165
108
  return Error::success();
166
108
}
167
168
void DbiModuleDescriptorBuilder::addDebugSubsection(
169
39
    std::shared_ptr<DebugSubsection> Subsection) {
170
39
  assert(Subsection);
171
39
  C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
172
39
      std::move(Subsection), CodeViewContainer::Pdb));
173
39
}
174
175
void DbiModuleDescriptorBuilder::addDebugSubsection(
176
37
    const DebugSubsectionRecord &SubsectionContents) {
177
37
  C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
178
37
      SubsectionContents, CodeViewContainer::Pdb));
179
37
}