Home | History | Annotate | Download | only in codeview
      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