22 using namespace llvm::codeview;
23 using namespace llvm::msf;
24 using namespace llvm::pdb;
27 class ModiSubstreamBuilder {};
31 : Msf(Msf),
Allocator(Msf.getAllocator()), Age(1), BuildNumber(0),
50 SectionContribs = Arr;
59 if (DbgStreams[(
int)Type].StreamNumber)
61 "The specified stream type already exists");
64 return ExpectedIndex.takeError();
65 uint32_t Index = std::move(*ExpectedIndex);
66 DbgStreams[(int)Type].Data = Data;
67 DbgStreams[(int)Type].StreamNumber = Index;
74 calculateModiSubstreamSize() + calculateSectionContribsStreamSize() +
75 calculateSectionMapStreamSize() + calculateDbgStreamsSize();
79 auto Entry = llvm::make_unique<ModuleInfo>();
80 ModuleInfo *M = Entry.get();
83 auto Result = ModuleInfos.
insert(std::make_pair(Module, std::move(Entry)));
86 "The specified module already exists");
87 ModuleInfoList.push_back(M);
92 auto ModIter = ModuleInfos.
find(Module);
93 if (ModIter == ModuleInfos.
end())
95 "The specified module was not found");
97 SourceFileNames.
insert(std::make_pair(File, Index));
98 auto &ModEntry = *ModIter;
99 ModEntry.second->SourceFiles.push_back(File);
103 uint32_t DbiStreamBuilder::calculateModiSubstreamSize()
const {
105 for (
const auto &M : ModuleInfoList) {
107 Size += M->Mod.size() + 1;
108 Size += M->Obj.size() + 1;
113 uint32_t DbiStreamBuilder::calculateSectionContribsStreamSize()
const {
114 if (SectionContribs.empty())
117 sizeof(SectionContribs[0]) * SectionContribs.size();
120 uint32_t DbiStreamBuilder::calculateSectionMapStreamSize()
const {
121 if (SectionMap.empty())
126 uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize()
const {
130 Size += ModuleInfoList.size() *
sizeof(
ulittle16_t);
131 Size += ModuleInfoList.size() *
sizeof(
ulittle16_t);
133 for (
const auto &M : ModuleInfoList)
134 NumFileInfos += M->SourceFiles.size();
136 Size += calculateNamesBufferSize();
140 uint32_t DbiStreamBuilder::calculateNamesBufferSize()
const {
142 for (
const auto &
F : SourceFileNames) {
143 Size +=
F.getKeyLength() + 1;
148 uint32_t DbiStreamBuilder::calculateDbgStreamsSize()
const {
149 return DbgStreams.
size() *
sizeof(uint16_t);
152 Error DbiStreamBuilder::generateModiSubstream() {
153 uint32_t Size = calculateModiSubstreamSize();
159 for (
const auto &M : ModuleInfoList) {
162 Layout.
NumFiles = M->SourceFiles.size();
163 if (
auto EC = ModiWriter.writeObject(Layout))
165 if (
auto EC = ModiWriter.writeZeroString(M->Mod))
167 if (
auto EC = ModiWriter.writeZeroString(M->Obj))
170 if (ModiWriter.bytesRemaining() >
sizeof(
uint32_t))
172 "Unexpected bytes in Modi Stream Data");
176 Error DbiStreamBuilder::generateFileInfoSubstream() {
177 uint32_t Size = calculateFileInfoSubstreamSize();
188 uint16_t ModiCount = std::min<uint32_t>(UINT16_MAX, ModuleInfos.
size());
189 uint16_t FileCount = std::min<uint32_t>(UINT16_MAX, SourceFileNames.size());
190 if (
auto EC = MetadataWriter.writeInteger(ModiCount))
192 if (
auto EC = MetadataWriter.writeInteger(FileCount))
194 for (uint16_t
I = 0;
I < ModiCount; ++
I) {
195 if (
auto EC = MetadataWriter.writeInteger(
I))
198 for (
const auto MI : ModuleInfoList) {
199 FileCount =
static_cast<uint16_t
>(
MI->SourceFiles.size());
200 if (
auto EC = MetadataWriter.writeInteger(FileCount))
210 for (
auto &
Name : SourceFileNames) {
211 Name.second = NameBufferWriter.getOffset();
212 if (
auto EC = NameBufferWriter.writeZeroString(
Name.getKey()))
216 for (
const auto MI : ModuleInfoList) {
218 auto Result = SourceFileNames.find(Name);
219 if (Result == SourceFileNames.end())
221 "The source file was not found.");
222 if (
auto EC = MetadataWriter.writeInteger(Result->second))
227 if (NameBufferWriter.bytesRemaining() > 0)
229 "The names buffer contained unexpected data.");
231 if (MetadataWriter.bytesRemaining() >
sizeof(
uint32_t))
232 return make_error<RawError>(
234 "The metadata buffer contained unexpected data.");
239 Error DbiStreamBuilder::finalize() {
245 if (
auto EC = generateModiSubstream())
247 if (
auto EC = generateFileInfoSubstream())
257 H->
MachineType =
static_cast<uint16_t
>(MachineType);
290 if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
305 std::vector<SectionContrib>
Ret;
308 for (
auto &Sec : SecHdrs) {
310 auto &Entry = Ret.back();
311 memset(&Entry, 0,
sizeof(Entry));
313 Entry.Off = Sec.PointerToRawData;
314 Entry.Size = Sec.SizeOfRawData;
315 Entry.Characteristics = Sec.Characteristics;
327 std::vector<SecMapEntry>
Ret;
332 auto &Entry = Ret.back();
333 memset(&Entry, 0,
sizeof(Entry));
335 Entry.Frame = Idx + 1;
338 Entry.SecName = UINT16_MAX;
339 Entry.ClassName = UINT16_MAX;
344 for (
auto &Hdr : SecHdrs) {
347 Entry.SecByteLength = Hdr.VirtualSize;
355 Entry.SecByteLength = UINT32_MAX;
362 if (
auto EC = finalize())
366 WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
StreamDBI);
375 if (!SectionContribs.empty()) {
382 if (!SectionMap.empty()) {
394 for (
auto &Stream : DbgStreams)
398 for (
auto &Stream : DbgStreams) {
401 auto WritableStream = WritableMappedBlockStream::createIndexedStream(
402 Layout, Buffer, Stream.StreamNumber);
410 "Unexpected bytes found in DBI Stream");
Error finalizeMsfLayout()
uint32_t calculateSerializedLength() const
A Module instance is used to store all the information related to an LLVM module. ...
void setSectionMap(ArrayRef< SecMapEntry > SecMap)
void setMachineType(PDB_Machine M)
static std::vector< SecMapEntry > createSectionMap(ArrayRef< llvm::object::coff_section > SecHdrs)
iterator find(StringRef Key)
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
struct fuzzer::@269 Flags
Error writeStreamRef(ReadableStreamRef Ref)
RefType keep_front(uint32_t N) const
Error writeObject(const T &Obj)
Error addDbgStream(pdb::DbgHeaderType Type, ArrayRef< uint8_t > Data)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Error commit(const msf::MSFLayout &Layout, const msf::WritableStream &Buffer)
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
uint32_t getLength() const override
size_t size() const
size - Get the array size.
const uint16_t kInvalidStreamIndex
RefType drop_front(uint32_t N) const
The instances of the Type class are immutable: once they are created, they are never changed...
void setBuildNumber(uint16_t B)
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
Greedy Register Allocator
void setFlags(uint16_t F)
void setVersionHeader(PdbRaw_DbiVer V)
void setPdbDllRbld(uint16_t R)
Error writeInteger(uint8_t Int)
void setPdbDllVersion(uint16_t V)
Error setStreamSize(uint32_t Idx, uint32_t Size)
Update the size of an existing stream.
Error writeArray(ArrayRef< T > Array)
static std::vector< SectionContrib > createSectionContribs(ArrayRef< llvm::object::coff_section > SecHdrs)
static ErrorSuccess success()
Create a success value.
Expected< uint32_t > addStream(uint32_t Size, ArrayRef< uint32_t > Blocks)
Add a stream to the MSF file with the given size, occupying the given list of blocks.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
detail::packed_endian_specific_integral< uint16_t, little, unaligned > ulittle16_t
Error addModuleSourceFile(StringRef Module, StringRef File)
void setSectionContribs(ArrayRef< SectionContrib > SecMap)
static uint16_t toSecMapFlags(uint32_t Flags)
Error addModuleInfo(StringRef ObjFile, StringRef Module)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
Lightweight error class with error context and mandatory checking.
uint32_t bytesRemaining() const
StringRef - Represent a constant reference to a string, i.e.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")