1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
// Copyright 2017 pdb Developers // // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or // http://opensource.org/licenses/MIT>, at your option. This file may not be // copied, modified, or distributed except according to those terms. use common::*; use super::data::TypeData; // References for primitive types: // // cvinfo.h provides an enumeration: // https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/include/cvinfo.h#L328-L750 // // pdbparse.cpp describes them as strings: // https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/pdbdump/pdbdump.cpp#L1896-L1974 // // The most obscure: MSDN Library October 2001 Disk 2 contains a \MSDN\specs.chm file which contains // html\S66CD.HTM which actually documents the *format* of the primitive type descriptors rather // than just listing them. TypeData::Primitive is designed to model the orthogonal information // encoded into the bits of the TypeIndex rather than exploding the matrix like the reference // implementations. /// Represents a primitive type like `void` or `char *`. #[derive(Debug,Copy,Clone,PartialEq,Eq)] pub struct PrimitiveType { pub kind: PrimitiveKind, /// What kind of indirection was applied to the underlying type pub indirection: Indirection, } #[derive(Debug,Copy,Clone,PartialEq,Eq)] pub enum PrimitiveKind { Void, Char, UChar, /// "Really a char" RChar, //// Wide characters, i.e. 16 bits WChar, /// "Really a 16-bit char" RChar16, /// "Really a 32-bit char" RChar32, /// Signed 8-bit integer I8, /// Unsigned 8-bit integer U8, /// Signed 16-bit integer I16, /// Unsigned 16-bit integer U16, /// Signed 32-bit integer I32, /// Unsigned 32-bit inteer U32, /// Signed 64-bit integer I64, /// Unsigned 64-bit integer U64, /// Signed 128-bit integer I128, /// Unsigned 128-bit integer U128, /// 16-bit floating point F16, /// 32-bit floating point F32, /// 32-bit partial precision floating point F32PP, /// 48-bit floating point F48, /// 64-bit floating point F64, /// 80-bit floating point F80, /// 128-bit floating point F128, /// 32-bit complex number Complex32, /// 64-bit complex number Complex64, /// 80-bit complex number Complex80, /// 128-bit complex number Complex128, /// 8-bit boolean value Bool8, /// 16-bit boolean value Bool16, /// 32-bit boolean value Bool32, /// 16-bit boolean value Bool64, HRESULT, } #[derive(Debug,Copy,Clone,PartialEq,Eq)] pub enum Indirection { None, /// 16-bit ("near") pointer Pointer16, /// 16:16 far pointer FarPointer1616, /// 16:16 huge pointer HugePointer1616, /// 32-bit pointer Pointer32, /// 48-bit 16:32 pointer Pointer1632, /// 64-bit pointer Pointer64, } pub fn type_data_for_primitive(index: TypeIndex) -> Result<TypeData<'static>> { // https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/include/cvinfo.h#L326-L750 // primitives live under 0x1000, and we should never reach here for non-primitive indexes assert!(index < 0x1000); // indirection is stored in these bits let indirection = match index & 0xf00 { 0x000 => Indirection::None, 0x100 => Indirection::Pointer16, 0x200 => Indirection::FarPointer1616, 0x300 => Indirection::FarPointer1616, 0x400 => Indirection::Pointer32, 0x500 => Indirection::Pointer1632, 0x600 => Indirection::Pointer64, _ => { return Err(Error::TypeNotFound(index)); } }; // primitive types are stored in the lowest octet // this groups "short" and "16-bit integer" together, but... right? *scratches head* let kind = match index & 0xff { 0x03 => PrimitiveKind::Void, 0x08 => PrimitiveKind::HRESULT, 0x10 => PrimitiveKind::Char, 0x20 => PrimitiveKind::UChar, 0x68 => PrimitiveKind::I8, 0x69 => PrimitiveKind::U8, 0x70 => PrimitiveKind::RChar, 0x71 => PrimitiveKind::WChar, 0x7a => PrimitiveKind::RChar16, 0x7b => PrimitiveKind::RChar32, 0x11 => PrimitiveKind::I16, 0x21 => PrimitiveKind::U16, 0x72 => PrimitiveKind::I16, 0x73 => PrimitiveKind::U16, 0x12 => PrimitiveKind::I32, 0x22 => PrimitiveKind::U32, 0x74 => PrimitiveKind::I32, 0x75 => PrimitiveKind::U32, 0x13 => PrimitiveKind::I64, 0x23 => PrimitiveKind::U64, 0x76 => PrimitiveKind::I64, 0x77 => PrimitiveKind::U64, 0x14 => PrimitiveKind::I128, 0x24 => PrimitiveKind::U128, 0x78 => PrimitiveKind::I128, 0x79 => PrimitiveKind::U128, 0x46 => PrimitiveKind::F16, 0x40 => PrimitiveKind::F32, 0x45 => PrimitiveKind::F32PP, 0x44 => PrimitiveKind::F48, 0x41 => PrimitiveKind::F64, 0x42 => PrimitiveKind::F80, 0x43 => PrimitiveKind::F128, 0x50 => PrimitiveKind::Complex32, 0x51 => PrimitiveKind::Complex64, 0x52 => PrimitiveKind::Complex80, 0x53 => PrimitiveKind::Complex128, 0x30 => PrimitiveKind::Bool8, 0x31 => PrimitiveKind::Bool16, 0x32 => PrimitiveKind::Bool32, 0x33 => PrimitiveKind::Bool64, _ => { return Err(Error::TypeNotFound(index)); } }; Ok(TypeData::Primitive(PrimitiveType { kind: kind, indirection: indirection, })) }