1 //===- ModInfo.cpp - PDB module information -------------------------------===// 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/Raw/ModInfo.h" 11 12 #include "llvm/DebugInfo/CodeView/StreamReader.h" 13 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" 14 #include "llvm/Support/Endian.h" 15 16 using namespace llvm; 17 using namespace llvm::pdb; 18 using namespace llvm::support; 19 20 namespace { 21 22 struct SCBytes { 23 ulittle16_t Section; 24 char Padding1[2]; 25 little32_t Offset; 26 little32_t Size; 27 ulittle32_t Characteristics; 28 ulittle16_t ModuleIndex; 29 char Padding2[2]; 30 ulittle32_t DataCrc; 31 ulittle32_t RelocCrc; 32 }; 33 34 // struct Flags { 35 // uint16_t fWritten : 1; // True if ModInfo is dirty 36 // uint16_t fECEnabled : 1; // Is EC symbolic info present? (What is EC?) 37 // uint16_t unused : 6; // Reserved 38 // uint16_t iTSM : 8; // Type Server Index for this module 39 //}; 40 const uint16_t HasECFlagMask = 0x2; 41 42 const uint16_t TypeServerIndexMask = 0xFF00; 43 const uint16_t TypeServerIndexShift = 8; 44 } 45 46 struct ModInfo::FileLayout { 47 ulittle32_t Mod; // Currently opened module. This field is a 48 // pointer in the reference implementation, but 49 // that won't work on 64-bit systems, and anyway 50 // it doesn't make sense to read a pointer from a 51 // file. For now it is unused, so just ignore it. 52 SCBytes SC; // First section contribution of this module. 53 ulittle16_t Flags; // See Flags definition. 54 ulittle16_t ModDiStream; // Stream Number of module debug info 55 ulittle32_t SymBytes; // Size of local symbol debug info in above stream 56 ulittle32_t LineBytes; // Size of line number debug info in above stream 57 ulittle32_t C13Bytes; // Size of C13 line number info in above stream 58 ulittle16_t NumFiles; // Number of files contributing to this module 59 char Padding1[2]; // Padding so the next field is 4-byte aligned. 60 ulittle32_t FileNameOffs; // array of [0..NumFiles) DBI name buffer offsets. 61 // This field is a pointer in the reference 62 // implementation, but as with `Mod`, we ignore it 63 // for now since it is unused. 64 ulittle32_t SrcFileNameNI; // Name Index for src file name 65 ulittle32_t PdbFilePathNI; // Name Index for path to compiler PDB 66 // Null terminated Module name 67 // Null terminated Obj File Name 68 }; 69 70 ModInfo::ModInfo() : Layout(nullptr) {} 71 72 ModInfo::ModInfo(const ModInfo &Info) 73 : ModuleName(Info.ModuleName), ObjFileName(Info.ObjFileName), 74 Layout(Info.Layout) {} 75 76 ModInfo::~ModInfo() {} 77 78 Error ModInfo::initialize(codeview::StreamRef Stream, ModInfo &Info) { 79 codeview::StreamReader Reader(Stream); 80 if (auto EC = Reader.readObject(Info.Layout)) 81 return EC; 82 83 if (auto EC = Reader.readZeroString(Info.ModuleName)) 84 return EC; 85 86 if (auto EC = Reader.readZeroString(Info.ObjFileName)) 87 return EC; 88 return Error::success(); 89 } 90 91 bool ModInfo::hasECInfo() const { return (Layout->Flags & HasECFlagMask) != 0; } 92 93 uint16_t ModInfo::getTypeServerIndex() const { 94 return (Layout->Flags & TypeServerIndexMask) >> TypeServerIndexShift; 95 } 96 97 uint16_t ModInfo::getModuleStreamIndex() const { return Layout->ModDiStream; } 98 99 uint32_t ModInfo::getSymbolDebugInfoByteSize() const { 100 return Layout->SymBytes; 101 } 102 103 uint32_t ModInfo::getLineInfoByteSize() const { return Layout->LineBytes; } 104 105 uint32_t ModInfo::getC13LineInfoByteSize() const { return Layout->C13Bytes; } 106 107 uint32_t ModInfo::getNumberOfFiles() const { return Layout->NumFiles; } 108 109 uint32_t ModInfo::getSourceFileNameIndex() const { 110 return Layout->SrcFileNameNI; 111 } 112 113 uint32_t ModInfo::getPdbFilePathNameIndex() const { 114 return Layout->PdbFilePathNI; 115 } 116 117 StringRef ModInfo::getModuleName() const { return ModuleName; } 118 119 StringRef ModInfo::getObjFileName() const { return ObjFileName; } 120 121 uint32_t ModInfo::getRecordLength() const { 122 uint32_t M = ModuleName.str().size() + 1; 123 uint32_t O = ObjFileName.str().size() + 1; 124 uint32_t Size = sizeof(FileLayout) + M + O; 125 Size = llvm::alignTo(Size, 4); 126 return Size; 127 } 128