1 /* 2 * CodeView debugging format - type information 3 * 4 * Copyright (C) 2006-2007 Peter Johnson 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the author nor the names of other contributors 15 * may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #include <util.h> 31 32 #include <libyasm.h> 33 34 #include "cv-dbgfmt.h" 35 36 enum cv_reservedtype { 37 /* Bitfields representation - type */ 38 CV_TYPE_SPECIAL = 0x00<<4, /* Special */ 39 CV_TYPE_SIGNED = 0x01<<4, /* Signed integral value */ 40 CV_TYPE_UNSIGNED = 0x02<<4, /* Unsigned integral value */ 41 CV_TYPE_BOOLEAN = 0x03<<4, /* Boolean */ 42 CV_TYPE_REAL = 0x04<<4, /* Real */ 43 CV_TYPE_COMPLEX = 0x05<<4, /* Complex */ 44 CV_TYPE_SPECIAL2 = 0x06<<4, /* Special2 */ 45 CV_TYPE_REALINT = 0x07<<4, /* Really int value */ 46 47 /* "size" of CV_TYPE_SPECIAL */ 48 CV_SPECIAL_NOTYPE = 0x00<<0, /* No type */ 49 CV_SPECIAL_ABS = 0x01<<0, /* Absolute symbol */ 50 CV_SPECIAL_SEG = 0x02<<0, /* Segment */ 51 CV_SPECIAL_VOID = 0x03<<0, /* Void */ 52 CV_SPECIAL_CURRENCY = 0x04<<0, /* Basic 8-byte currency value */ 53 CV_SPECIAL_NEARBSTR = 0x05<<0, /* Near Basic string */ 54 CV_SPECIAL_FARBSTR = 0x06<<0, /* Far Basic string */ 55 56 /* Size of CV_TYPE_SIGNED, CV_TYPE_UNSIGNED, and CV_TYPE_BOOLEAN */ 57 CV_INTEGER_1BYTE = 0x00<<0, /* 1 byte */ 58 CV_INTEGER_2BYTE = 0x01<<0, /* 2 byte */ 59 CV_INTEGER_4BYTE = 0x02<<0, /* 4 byte */ 60 CV_INTEGER_8BYTE = 0x03<<0, /* 8 byte */ 61 62 /* Size of CV_TYPE_REAL and CV_TYPE_COMPLEX */ 63 CV_REAL_32BIT = 0x00<<0, /* 32 bit */ 64 CV_REAL_64BIT = 0x01<<0, /* 64 bit */ 65 CV_REAL_80BIT = 0x02<<0, /* 80 bit */ 66 CV_REAL_128BIT = 0x03<<0, /* 128 bit */ 67 CV_REAL_48BIT = 0x04<<0, /* 48 bit */ 68 69 /* "size" of CV_TYPE_SPECIAL2 */ 70 CV_SPECIAL2_BIT = 0x00<<0, /* Bit */ 71 CV_SPECIAL2_PASCHAR = 0x01<<0, /* Pascal CHAR */ 72 73 /* Size of CV_TYPE_REALINT */ 74 CV_REALINT_CHAR = 0x00<<0, /* Char */ 75 CV_REALINT_WCHAR = 0x01<<0, /* Wide character */ 76 CV_REALINT_S2BYTE = 0x02<<0, /* 2-byte signed integer */ 77 CV_REALINT_U2BYTE = 0x03<<0, /* 2-byte unsigned integer */ 78 CV_REALINT_S4BYTE = 0x04<<0, /* 4-byte signed integer */ 79 CV_REALINT_U4BYTE = 0x05<<0, /* 4-byte unsigned integer */ 80 CV_REALINT_S8BYTE = 0x06<<0, /* 8-byte signed integer */ 81 CV_REALINT_U8BYTE = 0x07<<0, /* 8-byte unsigned integer */ 82 83 /* Mode */ 84 CV_MODE_DIRECT = 0x00<<8, /* Direct; not a pointer */ 85 CV_MODE_NEAR = 0x01<<8, /* Near pointer */ 86 CV_MODE_FAR = 0x02<<8, /* Far pointer */ 87 CV_MODE_HUGE = 0x03<<8, /* Huge pointer */ 88 CV_MODE_NEAR32 = 0x04<<8, /* 32-bit near pointer */ 89 CV_MODE_FAR32 = 0x05<<8, /* 32-bit far pointer */ 90 CV_MODE_NEAR64 = 0x06<<8, /* 64-bit near pointer */ 91 92 /* Pure primitive type listing - based on above bitfields */ 93 94 /* Special Types */ 95 CV_T_NOTYPE = 0x0000, /* Uncharacterized type (no type) */ 96 CV_T_ABS = 0x0001, /* Absolute symbol */ 97 CV_T_SEGMENT = 0x0002, /* Segment type */ 98 CV_T_VOID = 0x0003, /* Void */ 99 CV_T_PVOID = 0x0103, /* Near pointer to void */ 100 CV_T_PFVOID = 0x0203, /* Far pointer to void */ 101 CV_T_PHVOID = 0x0303, /* Huge pointer to void */ 102 CV_T_32PVOID = 0x0403, /* 32-bit near pointer to void */ 103 CV_T_32PFVOID = 0x0503, /* 32-bit far pointer to void */ 104 CV_T_CURRENCY = 0x0004, /* Basic 8-byte currency value */ 105 CV_T_NBASICSTR = 0x0005, /* Near Basic string */ 106 CV_T_FBASICSTR = 0x0006, /* Far Basic string */ 107 CV_T_BIT = 0x0060, /* Bit */ 108 CV_T_PASCHAR = 0x0061, /* Pascal CHAR */ 109 /* Character Types */ 110 CV_T_CHAR = 0x0010, /* 8-bit signed */ 111 CV_T_UCHAR = 0x0020, /* 8-bit unsigned */ 112 CV_T_PCHAR = 0x0110, /* Near pointer to 8-bit signed */ 113 CV_T_PUCHAR = 0x0120, /* Near pointer to 8-bit unsigned */ 114 CV_T_PFCHAR = 0x0210, /* Far pointer to 8-bit signed */ 115 CV_T_PFUCHAR = 0x0220, /* Far pointer to 8-bit unsigned */ 116 CV_T_PHCHAR = 0x0310, /* Huge pointer to 8-bit signed */ 117 CV_T_PHUCHAR = 0x0320, /* Huge pointer to 8-bit unsigned */ 118 CV_T_32PCHAR = 0x0410, /* 16:32 near pointer to 8-bit signed */ 119 CV_T_32PUCHAR = 0x0420, /* 16:32 near pointer to 8-bit unsigned */ 120 CV_T_32PFCHAR = 0x0510, /* 16:32 far pointer to 8-bit signed */ 121 CV_T_32PFUCHAR = 0x0520, /* 16:32 far pointer to 8-bit unsigned */ 122 /* Real Character Types */ 123 CV_T_RCHAR = 0x0070, /* Real char */ 124 CV_T_PRCHAR = 0x0170, /* Near pointer to a real char */ 125 CV_T_PFRCHAR = 0x0270, /* Far pointer to a real char */ 126 CV_T_PHRCHAR = 0x0370, /* Huge pointer to a real char */ 127 CV_T_32PRCHAR = 0x0470, /* 16:32 near pointer to a real char */ 128 CV_T_32PFRCHAR = 0x0570, /* 16:32 far pointer to a real char */ 129 /* Wide Character Types */ 130 CV_T_WCHAR = 0x0071, /* Wide char */ 131 CV_T_PWCHAR = 0x0171, /* Near pointer to a wide char */ 132 CV_T_PFWCHAR = 0x0271, /* Far pointer to a wide char */ 133 CV_T_PHWCHAR = 0x0371, /* Huge pointer to a wide char */ 134 CV_T_32PWCHAR = 0x0471, /* 16:32 near pointer to a wide char */ 135 CV_T_32PFWCHAR = 0x0571, /* 16:32 far pointer to a wide char */ 136 /* Real 16-bit Integer Types */ 137 CV_T_INT2 = 0x0072, /* Real 16-bit signed int */ 138 CV_T_UINT2 = 0x0073, /* Real 16-bit unsigned int */ 139 CV_T_PINT2 = 0x0172, /* Near pointer to 16-bit signed int */ 140 CV_T_PUINT2 = 0x0173, /* Near pointer to 16-bit unsigned int */ 141 CV_T_PFINT2 = 0x0272, /* Far pointer to 16-bit signed int */ 142 CV_T_PFUINT2 = 0x0273, /* Far pointer to 16-bit unsigned int */ 143 CV_T_PHINT2 = 0x0372, /* Huge pointer to 16-bit signed int */ 144 CV_T_PHUINT2 = 0x0373, /* Huge pointer to 16-bit unsigned int */ 145 CV_T_32PINT2 = 0x0472, /* 16:32 near pointer to 16-bit signed int */ 146 CV_T_32PUINT2 = 0x0473, /* 16:32 near pointer to 16-bit unsigned int */ 147 CV_T_32PFINT2 = 0x0572, /* 16:32 far pointer to 16-bit signed int */ 148 CV_T_32PFUINT2 = 0x0573, /* 16:32 far pointer to 16-bit unsigned int */ 149 /* 16-bit Short Types */ 150 CV_T_SHORT = 0x0011, /* 16-bit signed */ 151 CV_T_USHORT = 0x0021, /* 16-bit unsigned */ 152 CV_T_PSHORT = 0x0111, /* Near pointer to 16-bit signed */ 153 CV_T_PUSHORT = 0x0121, /* Near pointer to 16-bit unsigned */ 154 CV_T_PFSHORT = 0x0211, /* Far pointer to 16-bit signed */ 155 CV_T_PFUSHORT = 0x0221, /* Far pointer to 16-bit unsigned */ 156 CV_T_PHSHORT = 0x0311, /* Huge pointer to 16-bit signed */ 157 CV_T_PHUSHORT = 0x0321, /* Huge pointer to 16-bit unsigned */ 158 CV_T_32PSHORT = 0x0411, /* 16:32 near pointer to 16-bit signed */ 159 CV_T_32PUSHORT = 0x0421, /* 16:32 near pointer to 16-bit unsigned */ 160 CV_T_32PFSHORT = 0x0511, /* 16:32 far pointer to 16-bit signed */ 161 CV_T_32PFUSHORT = 0x0521, /* 16:32 far pointer to 16-bit unsigned */ 162 /* Real 32-bit Integer Types */ 163 CV_T_INT4 = 0x0074, /* Real 32-bit signed int */ 164 CV_T_UINT4 = 0x0075, /* Real 32-bit unsigned int */ 165 CV_T_PINT4 = 0x0174, /* Near pointer to 32-bit signed int */ 166 CV_T_PUINT4 = 0x0175, /* Near pointer to 32-bit unsigned int */ 167 CV_T_PFINT4 = 0x0274, /* Far pointer to 32-bit signed int */ 168 CV_T_PFUINT4 = 0x0275, /* Far pointer to 32-bit unsigned int */ 169 CV_T_PHINT4 = 0x0374, /* Huge pointer to 32-bit signed int */ 170 CV_T_PHUINT4 = 0x0375, /* Huge pointer to 32-bit unsigned int */ 171 CV_T_32PINT4 = 0x0474, /* 16:32 near pointer to 32-bit signed int */ 172 CV_T_32PUINT4 = 0x0475, /* 16:32 near pointer to 32-bit unsigned int */ 173 CV_T_32PFINT4 = 0x0574, /* 16:32 far pointer to 32-bit signed int */ 174 CV_T_32PFUINT4 = 0x0575, /* 16:32 far pointer to 32-bit unsigned int */ 175 /* 32-bit Long Types */ 176 CV_T_LONG = 0x0012, /* 32-bit signed */ 177 CV_T_ULONG = 0x0022, /* 32-bit unsigned */ 178 CV_T_PLONG = 0x0112, /* Near pointer to 32-bit signed */ 179 CV_T_PULONG = 0x0122, /* Near pointer to 32-bit unsigned */ 180 CV_T_PFLONG = 0x0212, /* Far pointer to 32-bit signed */ 181 CV_T_PFULONG = 0x0222, /* Far pointer to 32-bit unsigned */ 182 CV_T_PHLONG = 0x0312, /* Huge pointer to 32-bit signed */ 183 CV_T_PHULONG = 0x0322, /* Huge pointer to 32-bit unsigned */ 184 CV_T_32PLONG = 0x0412, /* 16:32 near pointer to 32-bit signed */ 185 CV_T_32PULONG = 0x0422, /* 16:32 near pointer to 32-bit unsigned */ 186 CV_T_32PFLONG = 0x0512, /* 16:32 far pointer to 32-bit signed */ 187 CV_T_32PFULONG = 0x0522, /* 16:32 far pointer to 32-bit unsigned */ 188 /* Real 64-bit int Types */ 189 CV_T_INT8 = 0x0076, /* 64-bit signed int */ 190 CV_T_UINT8 = 0x0077, /* 64-bit unsigned int */ 191 CV_T_PINT8 = 0x0176, /* Near pointer to 64-bit signed int */ 192 CV_T_PUINT8 = 0x0177, /* Near pointer to 64-bit unsigned int */ 193 CV_T_PFINT8 = 0x0276, /* Far pointer to 64-bit signed int */ 194 CV_T_PFUINT8 = 0x0277, /* Far pointer to 64-bit unsigned int */ 195 CV_T_PHINT8 = 0x0376, /* Huge pointer to 64-bit signed int */ 196 CV_T_PHUINT8 = 0x0377, /* Huge pointer to 64-bit unsigned int */ 197 CV_T_32PINT8 = 0x0476, /* 16:32 near pointer to 64-bit signed int */ 198 CV_T_32PUINT8 = 0x0477, /* 16:32 near pointer to 64-bit unsigned int */ 199 CV_T_32PFINT8 = 0x0576, /* 16:32 far pointer to 64-bit signed int */ 200 CV_T_32PFUINT8 = 0x0577, /* 16:32 far pointer to 64-bit unsigned int */ 201 /* 64-bit Integral Types */ 202 CV_T_QUAD = 0x0013, /* 64-bit signed */ 203 CV_T_UQUAD = 0x0023, /* 64-bit unsigned */ 204 CV_T_PQUAD = 0x0113, /* Near pointer to 64-bit signed */ 205 CV_T_PUQUAD = 0x0123, /* Near pointer to 64-bit unsigned */ 206 CV_T_PFQUAD = 0x0213, /* Far pointer to 64-bit signed */ 207 CV_T_PFUQUAD = 0x0223, /* Far pointer to 64-bit unsigned */ 208 CV_T_PHQUAD = 0x0313, /* Huge pointer to 64-bit signed */ 209 CV_T_PHUQUAD = 0x0323, /* Huge pointer to 64-bit unsigned */ 210 CV_T_32PQUAD = 0x0413, /* 16:32 near pointer to 64-bit signed */ 211 CV_T_32PUQUAD = 0x0423, /* 16:32 near pointer to 64-bit unsigned */ 212 CV_T_32PFQUAD = 0x0513, /* 16:32 far pointer to 64-bit signed */ 213 CV_T_32PFUQUAD = 0x0523, /* 16:32 far pointer to 64-bit unsigned */ 214 /* 32-bit Real Types */ 215 CV_T_REAL32 = 0x0040, /* 32-bit real */ 216 CV_T_PREAL32 = 0x0140, /* Near pointer to 32-bit real */ 217 CV_T_PFREAL32 = 0x0240, /* Far pointer to 32-bit real */ 218 CV_T_PHREAL32 = 0x0340, /* Huge pointer to 32-bit real */ 219 CV_T_32PREAL32 = 0x0440, /* 16:32 near pointer to 32-bit real */ 220 CV_T_32PFREAL32 = 0x0540, /* 16:32 far pointer to 32-bit real */ 221 /* 48-bit Real Types */ 222 CV_T_REAL48 = 0x0044, /* 48-bit real */ 223 CV_T_PREAL48 = 0x0144, /* Near pointer to 48-bit real */ 224 CV_T_PFREAL48 = 0x0244, /* Far pointer to 48-bit real */ 225 CV_T_PHREAL48 = 0x0344, /* Huge pointer to 48-bit real */ 226 CV_T_32PREAL48 = 0x0444, /* 16:32 near pointer to 48-bit real */ 227 CV_T_32PFREAL48 = 0x0544, /* 16:32 far pointer to 48-bit real */ 228 /* 64-bit Real Types */ 229 CV_T_REAL64 = 0x0041, /* 64-bit real */ 230 CV_T_PREAL64 = 0x0141, /* Near pointer to 64-bit real */ 231 CV_T_PFREAL64 = 0x0241, /* Far pointer to 64-bit real */ 232 CV_T_PHREAL64 = 0x0341, /* Huge pointer to 64-bit real */ 233 CV_T_32PREAL64 = 0x0441, /* 16:32 near pointer to 64-bit real */ 234 CV_T_32PFREAL64 = 0x0541, /* 16:32 far pointer to 64-bit real */ 235 /* 80-bit Real Types */ 236 CV_T_REAL80 = 0x0042, /* 80-bit real */ 237 CV_T_PREAL80 = 0x0142, /* Near pointer to 80-bit real */ 238 CV_T_PFREAL80 = 0x0242, /* Far pointer to 80-bit real */ 239 CV_T_PHREAL80 = 0x0342, /* Huge pointer to 80-bit real */ 240 CV_T_32PREAL80 = 0x0442, /* 16:32 near pointer to 80-bit real */ 241 CV_T_32PFREAL80 = 0x0542, /* 16:32 far pointer to 80-bit real */ 242 /* 128-bit Real Types */ 243 CV_T_REAL128 = 0x0043, /* 128-bit real */ 244 CV_T_PREAL128 = 0x0143, /* Near pointer to 128-bit real */ 245 CV_T_PFREAL128 = 0x0243, /* Far pointer to 128-bit real */ 246 CV_T_PHREAL128 = 0x0343, /* Huge pointer to 128-bit real */ 247 CV_T_32PREAL128 = 0x0443, /* 16:32 near pointer to 128-bit real */ 248 CV_T_32PFREAL128 = 0x0543, /* 16:32 far pointer to 128-bit real */ 249 /* 32-bit Complex Types */ 250 CV_T_CPLX32 = 0x0050, /* 32-bit complex */ 251 CV_T_PCPLX32 = 0x0150, /* Near pointer to 32-bit complex */ 252 CV_T_PFCPLX32 = 0x0250, /* Far pointer to 32-bit complex */ 253 CV_T_PHCPLX32 = 0x0350, /* Huge pointer to 32-bit complex */ 254 CV_T_32PCPLX32 = 0x0450, /* 16:32 near pointer to 32-bit complex */ 255 CV_T_32PFCPLX32 = 0x0550, /* 16:32 far pointer to 32-bit complex */ 256 /* 64-bit Complex Types */ 257 CV_T_CPLX64 = 0x0051, /* 64-bit complex */ 258 CV_T_PCPLX64 = 0x0151, /* Near pointer to 64-bit complex */ 259 CV_T_PFCPLX64 = 0x0251, /* Far pointer to 64-bit complex */ 260 CV_T_PHCPLX64 = 0x0351, /* Huge pointer to 64-bit complex */ 261 CV_T_32PCPLX64 = 0x0451, /* 16:32 near pointer to 64-bit complex */ 262 CV_T_32PFCPLX64 = 0x0551, /* 16:32 far pointer to 64-bit complex */ 263 /* 80-bit Complex Types */ 264 CV_T_CPLX80 = 0x0052, /* 80-bit complex */ 265 CV_T_PCPLX80 = 0x0152, /* Near pointer to 80-bit complex */ 266 CV_T_PFCPLX80 = 0x0252, /* Far pointer to 80-bit complex */ 267 CV_T_PHCPLX80 = 0x0352, /* Huge pointer to 80-bit complex */ 268 CV_T_32PCPLX80 = 0x0452, /* 16:32 near pointer to 80-bit complex */ 269 CV_T_32PFCPLX80 = 0x0552, /* 16:32 far pointer to 80-bit complex */ 270 /* 128-bit Complex Types */ 271 CV_T_CPLX128 = 0x0053, /* 128-bit complex */ 272 CV_T_PCPLX128 = 0x0153, /* Near pointer to 128-bit complex */ 273 CV_T_PFCPLX128 = 0x0253, /* Far pointer to 128-bit complex */ 274 CV_T_PHCPLX128 = 0x0353, /* Huge pointer to 128-bit real */ 275 CV_T_32PCPLX128 = 0x0453, /* 16:32 near pointer to 128-bit complex */ 276 CV_T_32PFCPLX128 = 0x0553, /* 16:32 far pointer to 128-bit complex */ 277 /* Boolean Types */ 278 CV_T_BOOL08 = 0x0030, /* 8-bit Boolean */ 279 CV_T_BOOL16 = 0x0031, /* 16-bit Boolean */ 280 CV_T_BOOL32 = 0x0032, /* 32-bit Boolean */ 281 CV_T_BOOL64 = 0x0033, /* 64-bit Boolean */ 282 CV_T_PBOOL08 = 0x0130, /* Near pointer to 8-bit Boolean */ 283 CV_T_PBOOL16 = 0x0131, /* Near pointer to 16-bit Boolean */ 284 CV_T_PBOOL32 = 0x0132, /* Near pointer to 32-bit Boolean */ 285 CV_T_PBOOL64 = 0x0133, /* Near pointer to 64-bit Boolean */ 286 CV_T_PFBOOL08 = 0x0230, /* Far pointer to 8-bit Boolean */ 287 CV_T_PFBOOL16 = 0x0231, /* Far pointer to 16-bit Boolean */ 288 CV_T_PFBOOL32 = 0x0232, /* Far pointer to 32-bit Boolean */ 289 CV_T_PFBOOL64 = 0x0233, /* Far pointer to 64-bit Boolean */ 290 CV_T_PHBOOL08 = 0x0330, /* Huge pointer to 8-bit Boolean */ 291 CV_T_PHBOOL16 = 0x0331, /* Huge pointer to 16-bit Boolean */ 292 CV_T_PHBOOL32 = 0x0332, /* Huge pointer to 32-bit Boolean */ 293 CV_T_PHBOOL64 = 0x0333, /* Huge pointer to 64-bit Boolean */ 294 CV_T_32PBOOL08 = 0x0430, /* 16:32 near pointer to 8-bit Boolean */ 295 CV_T_32PBOOL16 = 0x0431, /* 16:32 near pointer to 16-bit Boolean */ 296 CV_T_32PBOOL32 = 0x0432, /* 16:32 near pointer to 32-bit Boolean */ 297 CV_T_32PBOOL64 = 0x0433, /* 16:32 near pointer to 64-bit Boolean */ 298 CV_T_32PFBOOL08 = 0x0530, /* 16:32 far pointer to 8-bit Boolean */ 299 CV_T_32PFBOOL16 = 0x0531, /* 16:32 far pointer to 16-bit Boolean */ 300 CV_T_32PFBOOL32 = 0x0532, /* 16:32 far pointer to 32-bit Boolean */ 301 CV_T_32PFBOOL64 = 0x0533, /* 16:32 far pointer to 64-bit Boolean */ 302 303 /* Non-primitive types are stored in the TYPES section (generated in 304 * cv-type.c) and start at this index (e.g. 0x1000 is the first type 305 * in TYPES, 0x1001 the second, etc. 306 */ 307 CV_FIRST_NONPRIM = 0x1000 308 }; 309 310 enum cv_leaftype { 311 /* Leaf indices for type records that can be referenced from symbols */ 312 CV4_LF_MODIFIER = 0x0001, /* Type Modifier */ 313 CV4_LF_POINTER = 0x0002, /* Pointer */ 314 CV4_LF_ARRAY = 0x0003, /* Simple Array */ 315 CV4_LF_CLASS = 0x0004, /* Classes */ 316 CV4_LF_STRUCTURE = 0x0005, /* Structures */ 317 CV4_LF_UNION = 0x0006, /* Unions */ 318 CV4_LF_ENUM = 0x0007, /* Enumeration */ 319 CV4_LF_PROCEDURE = 0x0008, /* Procedure */ 320 CV4_LF_MFUNCTION = 0x0009, /* Member Function */ 321 CV4_LF_VTSHAPE = 0x000a, /* Virtual Function Table Shape */ 322 CV4_LF_BARRAY = 0x000d, /* Basic Array */ 323 CV4_LF_LABEL = 0x000e, /* Label */ 324 CV4_LF_NULL = 0x000f, /* Null */ 325 CV4_LF_DIMARRAY = 0x0011, /* Multiply Dimensioned Array */ 326 CV4_LF_VFTPATH = 0x0012, /* Path to Virtual Function Table */ 327 CV4_LF_PRECOMP = 0x0013, /* Reference Precompiled Types */ 328 CV4_LF_ENDPRECOMP = 0x0014, /* End of Precompiled Types */ 329 330 /* CodeView 5.0 version */ 331 CV5_LF_MODIFIER = 0x1001, /* Type Modifier */ 332 CV5_LF_POINTER = 0x1002, /* Pointer */ 333 CV5_LF_ARRAY = 0x1003, /* Simple Array */ 334 CV5_LF_CLASS = 0x1004, /* Classes */ 335 CV5_LF_STRUCTURE = 0x1005, /* Structures */ 336 CV5_LF_UNION = 0x1006, /* Unions */ 337 CV5_LF_ENUM = 0x1007, /* Enumeration */ 338 CV5_LF_PROCEDURE = 0x1008, /* Procedure */ 339 CV5_LF_MFUNCTION = 0x1009, /* Member Function */ 340 CV5_LF_VTSHAPE = 0x000a, /* Virtual Function Table Shape */ 341 CV5_LF_BARRAY = 0x100d, /* Basic Array */ 342 CV5_LF_LABEL = 0x000e, /* Label */ 343 CV5_LF_NULL = 0x000f, /* Null */ 344 CV5_LF_DIMARRAY = 0x100c, /* Multiply Dimensioned Array */ 345 CV5_LF_VFTPATH = 0x100d, /* Path to Virtual Function Table */ 346 CV5_LF_PRECOMP = 0x100e, /* Reference Precompiled Types */ 347 CV5_LF_ENDPRECOMP = 0x0014, /* End of Precompiled Types */ 348 CV5_LF_TYPESERVER = 0x0016, /* Reference Typeserver */ 349 350 /* Leaf indices for type records that can be referenced from other type 351 * records 352 */ 353 CV4_LF_SKIP = 0x0200, /* Skip */ 354 CV4_LF_ARGLIST = 0x0201, /* Argument List */ 355 CV4_LF_DEFARG = 0x0202, /* Default Argument */ 356 CV4_LF_LIST = 0x0203, /* Arbitrary List */ 357 CV4_LF_FIELDLIST = 0x0204, /* Field List */ 358 CV4_LF_DERIVED = 0x0205, /* Derived Classes */ 359 CV4_LF_BITFIELD = 0x0206, /* Bit Fields */ 360 CV4_LF_METHODLIST = 0x0207, /* Method List */ 361 CV4_LF_DIMCONU = 0x0208, /* Dimensioned Array with Constant Upper Bound */ 362 CV4_LF_DIMCONLU = 0x0209, /* Dimensioned Array with Constant Lower and Upper Bounds */ 363 CV4_LF_DIMVARU = 0x020a, /* Dimensioned Array with Variable Upper Bound */ 364 CV4_LF_DIMVARLU = 0x020b, /* Dimensioned Array with Variable Lower and Upper Bounds */ 365 CV4_LF_REFSYM = 0x020c, /* Referenced Symbol */ 366 367 /* CodeView 5.0 version */ 368 CV5_LF_SKIP = 0x1200, /* Skip */ 369 CV5_LF_ARGLIST = 0x1201, /* Argument List */ 370 CV5_LF_DEFARG = 0x1202, /* Default Argument */ 371 CV5_LF_FIELDLIST = 0x1203, /* Field List */ 372 CV5_LF_DERIVED = 0x1204, /* Derived Classes */ 373 CV5_LF_BITFIELD = 0x1205, /* Bit Fields */ 374 CV5_LF_METHODLIST = 0x1206, /* Method List */ 375 CV5_LF_DIMCONU = 0x1207, /* Dimensioned Array with Constant Upper Bound */ 376 CV5_LF_DIMCONLU = 0x1208, /* Dimensioned Array with Constant Lower and Upper Bounds */ 377 CV5_LF_DIMVARU = 0x1209, /* Dimensioned Array with Variable Upper Bound */ 378 CV5_LF_DIMVARLU = 0x120a, /* Dimensioned Array with Variable Lower and Upper Bounds */ 379 CV5_LF_REFSYM = 0x020c, /* Referenced Symbol */ 380 381 /* Leaf indices for fields of complex lists */ 382 CV4_LF_BCLASS = 0x0400, /* Real Base Class */ 383 CV4_LF_VBCLASS = 0x0401, /* Direct Virtual Base Class */ 384 CV4_LF_IVBCLASS = 0x0402, /* Indirect Virtual Base Class */ 385 CV4_LF_ENUMERATE = 0x0403, /* Enumeration Name and Value */ 386 CV4_LF_FRIENDFCN = 0x0404, /* Friend Function */ 387 CV4_LF_INDEX = 0x0405, /* Index To Another Type Record */ 388 CV4_LF_MEMBER = 0x0406, /* Data Member */ 389 CV4_LF_STMEMBER = 0x0407, /* Static Data Member */ 390 CV4_LF_METHOD = 0x0408, /* Method */ 391 CV4_LF_NESTTYPE = 0x0409, /* Nested Type Definition */ 392 CV4_LF_VFUNCTAB = 0x040a, /* Virtual Function Table Pointer */ 393 CV4_LF_FRIENDCLS = 0x040b, /* Friend Class */ 394 CV4_LF_ONEMETHOD = 0x040c, /* One Method */ 395 CV4_LF_VFUNCOFF = 0x040d, /* Virtual Function Offset */ 396 397 /* CodeView 5.0 version */ 398 CV5_LF_BCLASS = 0x1400, /* Real Base Class */ 399 CV5_LF_VBCLASS = 0x1401, /* Direct Virtual Base Class */ 400 CV5_LF_IVBCLASS = 0x1402, /* Indirect Virtual Base Class */ 401 CV5_LF_ENUMERATE = 0x0403, /* Enumeration Name and Value */ 402 CV5_LF_FRIENDFCN = 0x1403, /* Friend Function */ 403 CV5_LF_INDEX = 0x1404, /* Index To Another Type Record */ 404 CV5_LF_MEMBER = 0x1405, /* Data Member */ 405 CV5_LF_STMEMBER = 0x1406, /* Static Data Member */ 406 CV5_LF_METHOD = 0x1407, /* Method */ 407 CV5_LF_NESTTYPE = 0x1408, /* Nested Type Definition */ 408 CV5_LF_VFUNCTAB = 0x1409, /* Virtual Function Table Pointer */ 409 CV5_LF_FRIENDCLS = 0x140a, /* Friend Class */ 410 CV5_LF_ONEMETHOD = 0x140b, /* One Method */ 411 CV5_LF_VFUNCOFF = 0x140c, /* Virtual Function Offset */ 412 CV5_LF_NESTTYPEEX = 0x140d, /* Nested Type Extended Definition */ 413 CV5_LF_MEMBERMODIFY = 0x140e, /* Member Modification */ 414 /* XXX: CodeView 5.0 spec also lists 0x040f as LF_MEMBERMODIFY? */ 415 416 /* Leaf indices for numeric fields of symbols and type records */ 417 CV_LF_NUMERIC = 0x8000, 418 CV_LF_CHAR = 0x8000, /* Signed Char (8-bit) */ 419 CV_LF_SHORT = 0x8001, /* Signed Short (16-bit) */ 420 CV_LF_USHORT = 0x8002, /* Unsigned Short (16-bit) */ 421 CV_LF_LONG = 0x8003, /* Signed Long (32-bit) */ 422 CV_LF_ULONG = 0x8004, /* Unsigned Long (32-bit) */ 423 CV_LF_REAL32 = 0x8005, /* 32-bit Float */ 424 CV_LF_REAL64 = 0x8006, /* 64-bit Float */ 425 CV_LF_REAL80 = 0x8007, /* 80-bit Float */ 426 CV_LF_REAL128 = 0x8008, /* 128-bit Float */ 427 CV_LF_QUADWORD = 0x8009, /* Signed Quad Word (64-bit) */ 428 CV_LF_UQUADWORD = 0x800a, /* Unsigned Quad Word (64-bit) */ 429 CV_LF_REAL48 = 0x800b, /* 48-bit Float */ 430 CV_LF_COMPLEX32 = 0x800c, /* 32-bit Complex */ 431 CV_LF_COMPLEX64 = 0x800d, /* 64-bit Complex */ 432 CV_LF_COMPLEX80 = 0x800e, /* 80-bit Complex */ 433 CV_LF_COMPLEX128 = 0x800f, /* 128-bit Complex */ 434 CV_LF_VARSTRING = 0x8010, /* Variable-length String */ 435 436 /* Leaf padding bytes */ 437 CV_LF_PAD0 = 0xf0, 438 CV_LF_PAD1 = 0xf1, 439 CV_LF_PAD2 = 0xf2, 440 CV_LF_PAD3 = 0xf3, 441 CV_LF_PAD4 = 0xf4, 442 CV_LF_PAD5 = 0xf5, 443 CV_LF_PAD6 = 0xf6, 444 CV_LF_PAD7 = 0xf7, 445 CV_LF_PAD8 = 0xf8, 446 CV_LF_PAD9 = 0xf9, 447 CV_LF_PAD10 = 0xfa, 448 CV_LF_PAD11 = 0xfb, 449 CV_LF_PAD12 = 0xfc, 450 CV_LF_PAD13 = 0xfc, 451 CV_LF_PAD14 = 0xfe, 452 CV_LF_PAD15 = 0xff 453 }; 454 455 /* Leaves use a bit of meta-programming to encode formats: each character 456 * of format represents the output generated, as follows: 457 * 'b' : 1 byte value (integer) 458 * 'h' : 2 byte value (integer) 459 * 'w' : 4 byte value (integer) 460 * 'L' : subleaf, recurses into cv_leaf (pointer) 461 * 'T' : 4 byte type index, pulls cv_type.index from cv_type (pointer) 462 * 'S' : length-prefixed string (pointer) 463 */ 464 typedef struct cv_leaf { 465 enum cv_leaftype type; 466 const char *format; /* format of args */ 467 union { 468 unsigned long i; 469 void *p; 470 } args[6]; 471 } cv_leaf; 472 473 typedef struct cv_type { 474 unsigned long indx; /* type # (must be same as output order) */ 475 size_t num_leaves; 476 /*@null@*/ /*@only@*/ cv_leaf **leaves; 477 } cv_type; 478 479 /* Bytecode callback function prototypes */ 480 static void cv_type_bc_destroy(void *contents); 481 static void cv_type_bc_print(const void *contents, FILE *f, int indent_level); 482 static int cv_type_bc_calc_len 483 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); 484 static int cv_type_bc_tobytes 485 (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, 486 yasm_output_value_func output_value, 487 /*@null@*/ yasm_output_reloc_func output_reloc); 488 489 /* Bytecode callback structures */ 490 static const yasm_bytecode_callback cv_type_bc_callback = { 491 cv_type_bc_destroy, 492 cv_type_bc_print, 493 yasm_bc_finalize_common, 494 NULL, 495 cv_type_bc_calc_len, 496 yasm_bc_expand_common, 497 cv_type_bc_tobytes, 498 0 499 }; 500 501 static cv_type *cv_type_create(unsigned long indx); 502 static void cv_type_append_leaf(cv_type *type, /*@keep@*/ cv_leaf *leaf); 503 504 505 static cv_leaf * 506 cv_leaf_create_label(int is_far) 507 { 508 cv_leaf *leaf = yasm_xmalloc(sizeof(cv_leaf)); 509 leaf->type = CV5_LF_LABEL; 510 leaf->format = "h"; 511 leaf->args[0].i = is_far ? 4 : 0; 512 return leaf; 513 } 514 515 yasm_section * 516 yasm_cv__generate_type(yasm_object *object) 517 { 518 int new; 519 unsigned long indx = CV_FIRST_NONPRIM; 520 yasm_section *debug_type; 521 yasm_bytecode *bc; 522 cv_type *type; 523 524 debug_type = 525 yasm_object_get_general(object, ".debug$T", 1, 0, 0, &new, 0); 526 527 /* Add label type */ 528 type = cv_type_create(indx++); 529 cv_type_append_leaf(type, cv_leaf_create_label(0)); 530 bc = yasm_bc_create_common(&cv_type_bc_callback, type, 0); 531 yasm_bc_finalize(bc, yasm_cv__append_bc(debug_type, bc)); 532 yasm_bc_calc_len(bc, NULL, NULL); 533 534 return debug_type; 535 } 536 537 static void 538 cv_leaf_destroy(cv_leaf *leaf) 539 { 540 const char *ch = leaf->format; 541 int arg = 0; 542 543 while (*ch) { 544 switch (*ch) { 545 case 'b': 546 case 'h': 547 case 'w': 548 arg++; 549 break; /* nothing to destroy */ 550 case 'L': 551 cv_leaf_destroy((cv_leaf *)leaf->args[arg++].p); 552 break; 553 case 'T': 554 arg++; /* nothing to destroy */ 555 break; 556 case 'S': 557 yasm_xfree(leaf->args[arg++].p); 558 break; 559 default: 560 yasm_internal_error(N_("unknown leaf format character")); 561 } 562 ch++; 563 } 564 } 565 566 static unsigned long 567 cv_leaf_size(const cv_leaf *leaf) 568 { 569 const char *ch = leaf->format; 570 unsigned long len = 2; /* leaf type */ 571 unsigned long slen; 572 int arg = 0; 573 574 while (*ch) { 575 switch (*ch) { 576 case 'b': 577 len++; 578 arg++; 579 break; 580 case 'h': 581 len += 2; 582 arg++; 583 break; 584 case 'w': 585 len += 4; 586 arg++; 587 break; 588 case 'L': 589 len += cv_leaf_size((const cv_leaf *)leaf->args[arg++].p); 590 break; 591 case 'T': 592 len += 4; /* XXX: will be 2 in CV4 */ 593 arg++; 594 break; 595 case 'S': 596 len += 1; /* XXX: is this 1 or 2? */ 597 slen = (unsigned long)strlen((const char *)leaf->args[arg++].p); 598 len += slen <= 0xff ? slen : 0xff; 599 break; 600 default: 601 yasm_internal_error(N_("unknown leaf format character")); 602 } 603 ch++; 604 } 605 606 return len; 607 } 608 609 static void 610 cv_leaf_tobytes(const cv_leaf *leaf, yasm_bytecode *bc, yasm_arch *arch, 611 unsigned char **bufp, yasm_intnum *cval) 612 { 613 unsigned char *buf = *bufp; 614 const char *ch = leaf->format; 615 size_t len; 616 int arg = 0; 617 618 /* leaf type */ 619 yasm_intnum_set_uint(cval, leaf->type); 620 yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0); 621 buf += 2; 622 623 while (*ch) { 624 switch (*ch) { 625 case 'b': 626 YASM_WRITE_8(buf, leaf->args[arg].i); 627 arg++; 628 break; 629 case 'h': 630 yasm_intnum_set_uint(cval, leaf->args[arg++].i); 631 yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0); 632 buf += 2; 633 break; 634 case 'w': 635 yasm_intnum_set_uint(cval, leaf->args[arg++].i); 636 yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0); 637 buf += 4; 638 break; 639 case 'L': 640 cv_leaf_tobytes((const cv_leaf *)leaf->args[arg++].p, bc, arch, 641 &buf, cval); 642 break; 643 case 'T': 644 yasm_intnum_set_uint(cval, 645 ((const cv_type *)leaf->args[arg++].p)->indx); 646 yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0); 647 buf += 4; /* XXX: will be 2 in CV4 */ 648 break; 649 case 'S': 650 len = strlen((const char *)leaf->args[arg].p); 651 len = len <= 0xff ? len : 0xff; 652 YASM_WRITE_8(buf, len); 653 memcpy(buf, (const char *)leaf->args[arg].p, len); 654 buf += len; 655 arg++; 656 break; 657 default: 658 yasm_internal_error(N_("unknown leaf format character")); 659 } 660 ch++; 661 } 662 663 *bufp = buf; 664 } 665 666 static cv_type * 667 cv_type_create(unsigned long indx) 668 { 669 cv_type *type = yasm_xmalloc(sizeof(cv_type)); 670 671 type->indx = indx; 672 type->num_leaves = 0; 673 type->leaves = NULL; 674 675 return type; 676 } 677 678 static void 679 cv_type_append_leaf(cv_type *type, /*@keep@*/ cv_leaf *leaf) 680 { 681 type->num_leaves++; 682 683 /* This is inefficient for large numbers of leaves, but that won't happen 684 * until we add structure support. 685 */ 686 type->leaves = yasm_xrealloc(type->leaves, 687 type->num_leaves*sizeof(cv_leaf *)); 688 689 type->leaves[type->num_leaves-1] = leaf; 690 } 691 692 static void 693 cv_type_bc_destroy(void *contents) 694 { 695 cv_type *type = (cv_type *)contents; 696 size_t i; 697 698 for (i=0; i<type->num_leaves; i++) 699 cv_leaf_destroy(type->leaves[i]); 700 if (type->leaves) 701 yasm_xfree(type->leaves); 702 yasm_xfree(contents); 703 } 704 705 static void 706 cv_type_bc_print(const void *contents, FILE *f, int indent_level) 707 { 708 /* TODO */ 709 } 710 711 static int 712 cv_type_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 713 void *add_span_data) 714 { 715 cv_type *type = (cv_type *)bc->contents; 716 size_t i; 717 718 if (type->indx == CV_FIRST_NONPRIM) 719 bc->len = 4+2; 720 else 721 bc->len = 2; 722 723 for (i=0; i<type->num_leaves; i++) 724 bc->len += cv_leaf_size(type->leaves[i]); 725 726 /* Pad to multiple of 4 */ 727 if (bc->len & 0x3) 728 bc->len += 4-(bc->len & 0x3); 729 730 return 0; 731 } 732 733 static int 734 cv_type_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, 735 unsigned char *bufstart, void *d, 736 yasm_output_value_func output_value, 737 yasm_output_reloc_func output_reloc) 738 { 739 yasm_object *object = yasm_section_get_object(bc->section); 740 cv_type *type = (cv_type *)bc->contents; 741 unsigned char *buf = *bufp; 742 yasm_intnum *cval; 743 size_t i; 744 unsigned long reclen = bc->len - 2; 745 746 cval = yasm_intnum_create_uint(4); /* version */ 747 if (type->indx == CV_FIRST_NONPRIM) { 748 yasm_arch_intnum_tobytes(object->arch, cval, buf, 4, 32, 0, bc, 1); 749 buf += 4; 750 reclen -= 4; 751 } 752 753 /* Total length of record (following this field) - 2 bytes */ 754 yasm_intnum_set_uint(cval, reclen); 755 yasm_arch_intnum_tobytes(object->arch, cval, buf, 2, 16, 0, bc, 1); 756 buf += 2; 757 758 /* Leaves */ 759 for (i=0; i<type->num_leaves; i++) 760 cv_leaf_tobytes(type->leaves[i], bc, object->arch, &buf, cval); 761 762 /* Pad to multiple of 4 */ 763 switch ((buf-(*bufp)) & 0x3) { 764 case 3: 765 YASM_WRITE_8(buf, CV_LF_PAD3); 766 case 2: 767 YASM_WRITE_8(buf, CV_LF_PAD2); 768 case 1: 769 YASM_WRITE_8(buf, CV_LF_PAD1); 770 case 0: 771 break; 772 } 773 774 *bufp = buf; 775 776 yasm_intnum_destroy(cval); 777 return 0; 778 } 779