Zachary Turner | 1822af54 | 2016-04-27 23:41:42 +0000 | [diff] [blame] | 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" |
Zachary Turner | 8dbe362 | 2016-05-27 01:54:44 +0000 | [diff] [blame] | 11 | |
| 12 | #include "llvm/DebugInfo/CodeView/StreamReader.h" |
Zachary Turner | 1822af54 | 2016-04-27 23:41:42 +0000 | [diff] [blame] | 13 | #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" |
| 14 | #include "llvm/Support/Endian.h" |
| 15 | |
| 16 | using namespace llvm; |
Zachary Turner | 2f09b50 | 2016-04-29 17:28:47 +0000 | [diff] [blame] | 17 | using namespace llvm::pdb; |
Zachary Turner | 1822af54 | 2016-04-27 23:41:42 +0000 | [diff] [blame] | 18 | using namespace llvm::support; |
| 19 | |
| 20 | namespace { |
Zachary Turner | 8dbe362 | 2016-05-27 01:54:44 +0000 | [diff] [blame] | 21 | |
Zachary Turner | 1822af54 | 2016-04-27 23:41:42 +0000 | [diff] [blame] | 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 |
Zachary Turner | 8dbe362 | 2016-05-27 01:54:44 +0000 | [diff] [blame] | 66 | // Null terminated Module name |
| 67 | // Null terminated Obj File Name |
Zachary Turner | 1822af54 | 2016-04-27 23:41:42 +0000 | [diff] [blame] | 68 | }; |
| 69 | |
Zachary Turner | 1de49c9 | 2016-05-27 18:47:20 +0000 | [diff] [blame] | 70 | ModInfo::ModInfo() : Layout(nullptr) {} |
| 71 | |
Zachary Turner | 8dbe362 | 2016-05-27 01:54:44 +0000 | [diff] [blame] | 72 | ModInfo::ModInfo(codeview::StreamRef Stream) : Layout(nullptr) { |
| 73 | codeview::StreamReader Reader(Stream); |
| 74 | if (auto EC = Reader.readObject(Layout)) { |
| 75 | consumeError(std::move(EC)); |
| 76 | return; |
| 77 | } |
| 78 | if (auto EC = Reader.readZeroString(ModuleName)) { |
| 79 | consumeError(std::move(EC)); |
| 80 | return; |
| 81 | } |
| 82 | if (auto EC = Reader.readZeroString(ObjFileName)) { |
| 83 | consumeError(std::move(EC)); |
| 84 | return; |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | ModInfo::ModInfo(const ModInfo &Info) |
| 89 | : ModuleName(Info.ModuleName), ObjFileName(Info.ObjFileName), |
| 90 | Layout(Info.Layout) {} |
Zachary Turner | 1822af54 | 2016-04-27 23:41:42 +0000 | [diff] [blame] | 91 | |
| 92 | ModInfo::~ModInfo() {} |
| 93 | |
| 94 | bool ModInfo::hasECInfo() const { return (Layout->Flags & HasECFlagMask) != 0; } |
| 95 | |
| 96 | uint16_t ModInfo::getTypeServerIndex() const { |
| 97 | return (Layout->Flags & TypeServerIndexMask) >> TypeServerIndexShift; |
| 98 | } |
| 99 | |
| 100 | uint16_t ModInfo::getModuleStreamIndex() const { return Layout->ModDiStream; } |
| 101 | |
| 102 | uint32_t ModInfo::getSymbolDebugInfoByteSize() const { |
| 103 | return Layout->SymBytes; |
| 104 | } |
| 105 | |
| 106 | uint32_t ModInfo::getLineInfoByteSize() const { return Layout->LineBytes; } |
| 107 | |
| 108 | uint32_t ModInfo::getC13LineInfoByteSize() const { return Layout->C13Bytes; } |
| 109 | |
| 110 | uint32_t ModInfo::getNumberOfFiles() const { return Layout->NumFiles; } |
| 111 | |
| 112 | uint32_t ModInfo::getSourceFileNameIndex() const { |
| 113 | return Layout->SrcFileNameNI; |
| 114 | } |
| 115 | |
| 116 | uint32_t ModInfo::getPdbFilePathNameIndex() const { |
| 117 | return Layout->PdbFilePathNI; |
| 118 | } |
| 119 | |
Zachary Turner | 8dbe362 | 2016-05-27 01:54:44 +0000 | [diff] [blame] | 120 | StringRef ModInfo::getModuleName() const { return ModuleName; } |
Zachary Turner | 1822af54 | 2016-04-27 23:41:42 +0000 | [diff] [blame] | 121 | |
Zachary Turner | 8dbe362 | 2016-05-27 01:54:44 +0000 | [diff] [blame] | 122 | StringRef ModInfo::getObjFileName() const { return ObjFileName; } |
Zachary Turner | 1822af54 | 2016-04-27 23:41:42 +0000 | [diff] [blame] | 123 | |
Zachary Turner | 8dbe362 | 2016-05-27 01:54:44 +0000 | [diff] [blame] | 124 | uint32_t ModInfo::getRecordLength() const { |
| 125 | uint32_t M = ModuleName.str().size() + 1; |
| 126 | uint32_t O = ObjFileName.str().size() + 1; |
| 127 | uint32_t Size = sizeof(FileLayout) + M + O; |
| 128 | Size = llvm::alignTo(Size, 4); |
| 129 | return Size; |
Zachary Turner | 1822af54 | 2016-04-27 23:41:42 +0000 | [diff] [blame] | 130 | } |