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