home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / Cv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  19.1 KB  |  767 lines

  1. #include "c.h"
  2. #include "cv.h"
  3.  
  4. typedef struct tagLocal {
  5.     char data[50];
  6.     short len;
  7. } LocalVariable;
  8.  
  9. LocalVariable LocalsTable[256];
  10. static ProcList *LastProc;
  11. ProcList *ProceduresList;
  12. static int DebugSymbolPtr = 0;
  13. DataList *DataSymbolsInfo;
  14. static DataList *LastDataSymbolsInfo;
  15. DataList *DataTypesInfo;
  16. static DataList *LastDataTypesInfo;
  17. static int AddToEmittedTypes(Type ty,int cvType);
  18. int AddNewType(char *data,int len,char *name);
  19. int AddArrayType(Type ty,char *name);
  20. int BuildPointerType(int xrefIdx);
  21. static int Typesidx = 0;
  22. static int GetTypeInternal(Type ty,char *name);
  23.  
  24. void PutInSymbolBuffer(char *data,int len)
  25. {
  26.     if (DebugSymbolPtr > 255) return;
  27.     if (len < 50) {
  28.         memcpy(LocalsTable[DebugSymbolPtr].data,data,len);
  29.         LocalsTable[DebugSymbolPtr].len = len;
  30.         DebugSymbolPtr++;
  31.     }
  32. }
  33.  
  34. void PutSymbolRecord(int type,char *data,int len,char *name)
  35. {
  36.     char tmprec[256];
  37.     int i;
  38.  
  39.     for (i=4; i<len+4;i++) {
  40.         tmprec[i] = data[i-4];
  41.     }
  42.     tmprec[i++] = strlen(name);
  43.     while (*name) {
  44.         tmprec[i++] = *name++;
  45.     }
  46.     *((unsigned short *)tmprec) = i-2;
  47.     *((unsigned short *)(tmprec+2)) = type;
  48.     PutInSymbolBuffer(tmprec,i);
  49. }
  50.  
  51. int BuildFunctionPointerRecord(Type ty,char *name)
  52. {
  53.     Type *tp;
  54.     int nrOfArgs,len,idx,result;
  55.     unsigned short *data;
  56.     char tmpbuffer[12],*p;
  57.  
  58.     nrOfArgs = 0;
  59.     tp = ty->type->u.f.proto;
  60.     if (tp) {
  61.         while (*tp) {
  62.             nrOfArgs++;
  63.             tp++;
  64.         }
  65.     }
  66.     len = 3 + nrOfArgs;
  67.     len = len * sizeof(short);
  68.     data = (unsigned short *)malloc(len);
  69.     data[0] = len-2;
  70.     data[1] = LF_ARGLIST;
  71.     data[2] = nrOfArgs;
  72.     tp = ty->type->u.f.proto;
  73.     idx = 3;
  74.     if (tp) {
  75.         while (*tp) {
  76.             data[idx++] = GetTypeInternal(*tp,"");
  77.             tp++;
  78.         }
  79.     }
  80.     result = AddNewType((char *)data,len,name);
  81.     free(data);
  82.     p = tmpbuffer;
  83.     *(unsigned short *)p = 10;
  84.     p += 2;
  85.     *(unsigned short *)p = 0x8; /* Procedure */
  86.     p += 2;
  87.     *(unsigned short *)p = 116; /* ??? */
  88.     p += 2;
  89.     *p++ = 0;    /* no special call flags */
  90.     *p++ = 0;   /* reserved */
  91.     *(unsigned short *)p = nrOfArgs;
  92.     p += 2;
  93.     *(unsigned short *)p = Typesidx+4096 - 1;
  94.     result = AddNewType(tmpbuffer,12,name);
  95.     return(BuildPointerType(4096+result));
  96. }
  97.  
  98.  
  99. static int GetTypeInternal(Type ty,char *name)
  100. {
  101.     int st;
  102.  
  103.     switch (ty->op) {
  104.         case CHAR:
  105.             if (ty->u.sym->name[0] == 'u')
  106.                 return(0x20);
  107.             return(0x10);
  108.         case DOUBLE:
  109.             return(0x41);
  110.         case FLOAT:
  111.              return(0x40);
  112.         case STRUCT:
  113.             return(AddToEmittedTypes(ty,LF_STRUCTURE));
  114.         case ENUM:
  115.             return(0x74); /* signed int */
  116.         case INT:
  117.         case UNSIGNED:
  118.             if (ty->u.sym->name[0] == 'u')
  119.                 return(0x75);
  120.             return(0x74); /* signed int */
  121.         case SHORT:
  122.             if (ty->u.sym->name[0] == 'u')
  123.                 return(0x73);
  124.             return(0x72); /* signed int */
  125.         case FUNCTION:
  126.             if (ty->type)
  127.                 return GetTypeInternal(ty->type,name);
  128.             break;
  129.         case LONGLONG:
  130.             return 0x76;
  131.         case ARRAY:
  132.             return(AddArrayType(ty,name));
  133.         case UNION:
  134.             return(AddToEmittedTypes(ty,LF_UNION));
  135.         case POINTER:
  136.  
  137.             assert(ty->type);
  138. redo:
  139.             st = ty->type->op;
  140.             switch(st) {
  141.                 case CONST:
  142.                     ty = ty->type;
  143.                     goto redo;
  144.                 case CHAR:
  145.                     return(0x470);
  146.                 case DOUBLE:
  147.                     return(0x441);
  148.                 case FLOAT:
  149.                     return(0x440);
  150.                 case STRUCT:
  151.                     return(AddToEmittedTypes(ty,LF_STRUCTURE));
  152.                 case UNION:
  153.                     return(AddToEmittedTypes(ty,LF_UNION));
  154.                 case ENUM:
  155.                 case INT:
  156.                     if (ty->type->type && ty->type->type->u.sym->name &&
  157.                         ty->type->u.sym->name[0] == 'u')
  158.                         return(0x475);
  159.                     return(0x474);
  160.                 case UNSIGNED:
  161.                     if (ty->type->type == NULL) return(0x475);
  162.                     break;
  163.                 case SHORT:
  164.                     if (ty->type->type && ty->type->type->u.sym->name &&
  165.                         ty->type->u.sym->name[0] == 'u')
  166.                         return(0x473);
  167.                     return(0x472);
  168.                 case LONGLONG:
  169.                     return 0x476;
  170.                 case VOID:
  171.                     return(0x403);
  172.                 case FUNCTION:
  173.                     return(4096+BuildFunctionPointerRecord(ty,name));
  174.                     break;
  175.                 case ARRAY:
  176.                     return 4096 + BuildPointerType(AddArrayType(ty->type,name));
  177.                 case POINTER:
  178.                     return 4096 + BuildPointerType(GetTypeInternal(ty->type,name));
  179.                 default:
  180.                     warning("Unknown type %s (%d) when generating debug info\n",name,st);
  181.                     break;
  182.  
  183.             }
  184.             break;
  185.     }
  186.     return(0);
  187. }
  188.  
  189. int GetType(Symbol p)
  190. {
  191.     return(GetTypeInternal(p->type,p->name));
  192. }
  193. /*
  194.     17    EAX
  195.     18    ECX
  196.     19    EDX
  197.     20    EBX
  198.     21    ESP
  199.     22    EBP
  200.     23    ESI
  201.     24    EDI
  202. */
  203. static int FindRegisterNumber(char *regName)
  204. {
  205.     if (regName[2] == 'a') return 17;
  206.     else if (regName[2] == 'b') return 20;
  207.     else if (regName[2] == 'c') return 18;
  208.     else if (regName[2] == 's') return 23;
  209.     else if (regName[2] == 'd' && regName[3] == 'x')
  210.         return 19;
  211.     else if (regName[2] == 'd' && regName[3] == 'i')
  212.         return 24;
  213.     return 0;
  214. }
  215.  
  216. void GenLocalDebugInfo(Symbol p)
  217. {
  218.     struct autoDataInfo info;
  219.     int regNumber;
  220.     char buf[150],*pt;
  221.     int i;
  222.  
  223.     if (glevel == 0) return;
  224.     if (p->x.offset == 0 && p->x.regnode) {
  225.     /*
  226.     This symbol record describes a symbol that has been enregistered.  Provisions 
  227.     for enabling future implementation tracking of a symbol into and out of 
  228.     registers is  provided in this symbol.  When the symbol processor is examining 
  229.     a register symbol, the length field of the symbol is compared with the offset of 
  230.     the byte following the symbol name field.  If these are the same, there is no 
  231.     register tracking information.  If the length and offset are different, the byte 
  232.     following the end of the symbol name is examined.  If the byte is zero, there is 
  233.     no register tracking information following the symbol.  If the byte is     not zero,
  234.     then the byte indexes into the list of stack machine implementations and styles 
  235.     of register tracking. Microsoft does not currently emit or process register 
  236.     tracking information. 
  237.     2        2            2        2            *        *
  238.     length    S_REGISTER    @type     register     name    tracking
  239.  
  240.     @type    The type of the symbol
  241.     register    Enumerate  of the registers in which the symbol value is stored.  
  242.     This field is treated as two bytes. The high order byte specifies the register 
  243.     in which the high order  part of the value is stored.  The low byte specifies 
  244.     the register for the low order part of the value.  If the value is not stored 
  245.     in two registers then high order register field contains the enumerate value 
  246.     for no register.   For register enumeration values, see Section 6. The 
  247.     register index enumeration is specific to the processor model for the module.
  248.     name    Length-prefixed name of the symbol stored in the register
  249.     tracking    Register tracking information.  Format unspecified.
  250.     32-bit registers
  251.  
  252.     17    EAX
  253.     18    ECX
  254.     19    EDX
  255.     20    EBX
  256.     21    ESP
  257.     22    EBP
  258.     23    ESI
  259.     24    EDI
  260.  
  261.     */
  262.         regNumber = FindRegisterNumber(p->x.name);
  263.         pt = buf + 2;
  264.         *(unsigned short *)pt = S_REGISTER;
  265.         pt += 2;
  266.         *(unsigned short *)pt = GetType(p);
  267.         pt += 2;
  268.         *(unsigned short *)pt = regNumber;
  269.         pt += 2;
  270.         pt = PutLengthPrefixedName(pt,p->name);
  271.         *pt++ = 0;
  272.         i = pt - buf;
  273.         if (i & 1) {
  274.             *pt++ = 0;
  275.         }
  276.         i = pt - buf;
  277.         pt = buf;
  278.         *(unsigned short *)pt = i-2;
  279.         PutInSymbolBuffer(buf,i);
  280.         return;
  281.     }
  282.     else
  283.         info.offset = p->x.offset;
  284.     info.type = GetType(p);
  285.     PutSymbolRecord(S_BPREL32,(char *)&info,6,p->name);
  286. }
  287. void GenBlockDebugInfo(Code cp)
  288. {
  289.     Symbol         *p = cp->u.block.locals;
  290.     for (; *p; p++) {
  291.         GenLocalDebugInfo(*p);
  292.     }
  293. }
  294.  
  295. ProcList *newProcList(char *name)
  296. {
  297.     ProcList *result;
  298.     result = (ProcList *)malloc(sizeof(ProcList));
  299.     memset(result,0,sizeof(ProcList));
  300.     result->procInfo.u.Name = malloc(strlen(name)+1);
  301.     strcpy(result->procInfo.u.Name,name);
  302.     return(result);
  303. }
  304. DataList *newDataList(int len,char *name)
  305. {
  306.     DataList *result;
  307.  
  308.     result = malloc(sizeof(DataList));
  309.     result->Next = NULL;
  310.     result->data = malloc(len);
  311.     result->len = len;
  312.     result->Name = name;
  313.     return(result);
  314. }
  315.  
  316. #if 0
  317. int FindArgListType(int nrOfArguments,unsigned short *typesVector)
  318. {
  319.     ProcList *pl;
  320.  
  321.     pl = ProceduresList;
  322.     while (pl) {
  323.         if (pl->NrOfArguments == nrOfArguments) {
  324.             if (pl->FunctionRecord) {
  325.                 if (!memcmp(pl->FunctionRecord->data+6,typesVector,nrOfArguments*sizeof(short))) {
  326.                     return(pl->procInfo.procType);
  327.                 }
  328.             }
  329.         }
  330.         pl = pl->Next;
  331.     }
  332.     return(-1);
  333. }
  334. #endif
  335.  
  336. static int BuildFunctionType(ProcList *pl,Symbol f)
  337. {
  338.     char tmpbuffer[12],*p;
  339.  
  340.     p = tmpbuffer;
  341.     *(unsigned short *)p = 10;
  342.     p += 2;
  343.     *(unsigned short *)p = 0x8; /* Procedure */
  344.     p += 2;
  345.     *(unsigned short *)p = GetTypeInternal(f->type,f->x.name);
  346.     p += 2;
  347.     *p++ = 0;    /* no special call flags */
  348.     *p++ = 0;   /* reserved */
  349.     *(unsigned short *)p = pl->NrOfArguments;
  350.     p += 2;
  351.     *(unsigned short *)p = Typesidx+4096 - 1;
  352.     return(AddNewType(tmpbuffer,12,pl->FunctionRecord->Name));
  353. }
  354.  
  355. void WriteFunctionTypeRecord(Symbol f,int nrOfArguments,unsigned short *typesVector)
  356. {
  357.     int len,topad;
  358.     unsigned short *data;
  359.  
  360. //    ti = FindArgListType(nrOfArguments,typesVector);
  361. #if 0
  362.     if (ti != -1) {
  363.         LastProc->procInfo.procType = ti;
  364.         LastProc->FunctionRecord = NULL;
  365.         return;
  366.     }
  367. #endif        
  368.     len = 3 + nrOfArguments;
  369.     topad = 0;
  370.     len = len * sizeof(short);
  371.     data = (unsigned short *)malloc(len);
  372.     data[0] = len-2;
  373.     data[1] = LF_ARGLIST;
  374.     data[2] = nrOfArguments;
  375.     memcpy(&data[3],typesVector,nrOfArguments * sizeof(short));
  376.     if (topad) {
  377.         unsigned char *p;
  378.  
  379.         p = (unsigned char *)data + len - 2;
  380.         *p++ = (unsigned char)0xF2;
  381.         *p++ = (unsigned char)0xF1;
  382.     }
  383.     LastProc->FunctionRecord = newDataList(len,f->x.name);
  384.     LastProc->FunctionRecord->data = (char *)data;
  385.     LastProc->FunctionRecord->len = len;
  386.     /* This points to the type index record */
  387.     LastProc->procInfo.procType = 4096 + Typesidx+1;
  388.     if (LastProc->procInfo.procType  > 8000) {
  389.         fprintf(stderr,"bad synch in debug info\n");
  390.     }
  391.     AddNewType(LastProc->FunctionRecord->data,LastProc->FunctionRecord->len,f->x.name);
  392.     BuildFunctionType(LastProc,f);
  393. }
  394.  
  395. void WriteLocalsDebugInfo(Symbol f,int lineno)
  396. {
  397.     int i,len,nrOfArguments;
  398.     char *p,*pname;
  399.     Symbol *Arguments,sym;
  400.     struct autoDataInfo info;
  401.     unsigned short *typesVector;
  402.     
  403.      if (glevel == 0) return;
  404.     Arguments = f->u.f.callee;
  405.     nrOfArguments = 0;
  406.     while (*Arguments) {
  407.         Arguments++;
  408.         nrOfArguments++;
  409.     }
  410.     if (nrOfArguments)
  411.         typesVector = (unsigned short *)malloc(sizeof(short)*nrOfArguments);
  412.     else
  413.         typesVector = NULL;
  414.     Arguments = f->u.f.callee;
  415.     for (i=0;i<nrOfArguments;i++) {
  416.         sym = *Arguments++;
  417.         info.offset = sym->x.offset;
  418.         info.type = GetType(sym);
  419.         PutSymbolRecord(S_BPREL32,(char *)&info,6,sym->name);
  420.         typesVector[i] = info.type;
  421.     }
  422.     for (i=0,len=0;i<DebugSymbolPtr;i++) {
  423.         len += LocalsTable[i].len;
  424.     }
  425.     pname = f->x.name;
  426.     /* maybe use f->name? */
  427.     if (ProceduresList == NULL) {
  428.         ProceduresList = newProcList(pname);
  429.         LastProc = ProceduresList;
  430.     }
  431.     else {
  432.         LastProc->Next = newProcList(pname);
  433.         LastProc = LastProc->Next;
  434.     }
  435.     LastProc->data = malloc(len);
  436.     p = LastProc->data;
  437.     for (i=0; i<DebugSymbolPtr;i++) {
  438.         memcpy(p,LocalsTable[i].data,LocalsTable[i].len);
  439.         p += LocalsTable[i].len;
  440.     }
  441.     LastProc->len = len;
  442.     LastProc->Sym = f;
  443.     DebugSymbolPtr = 0;
  444.     LastProc->NrOfArguments = nrOfArguments;
  445.     WriteFunctionTypeRecord(f,nrOfArguments,typesVector);
  446.     free(typesVector);
  447. }
  448.  
  449. char *PutLengthPrefixedName(char *dst,char *src)
  450. {
  451.     if (src == NULL) src = "_unnamed";
  452.     *dst++ = strlen(src);
  453.     while (*src) {
  454.         *dst++ = *src++;
  455.     }
  456.     return(dst);
  457. }
  458.  
  459. DataList *AddToCVData(char *data,int len,char *name)
  460. {
  461.     if (DataSymbolsInfo == NULL) {
  462.         DataSymbolsInfo = newDataList(len,name);
  463.         LastDataSymbolsInfo = DataSymbolsInfo;
  464.     }
  465.     else {
  466.         LastDataSymbolsInfo->Next = newDataList(len,name);
  467.         LastDataSymbolsInfo = LastDataSymbolsInfo->Next;
  468.     }
  469.     memcpy(LastDataSymbolsInfo->data,data,len);
  470.     return(LastDataSymbolsInfo);
  471.     
  472. }
  473.  
  474. int AddNewType(char *data,int len,char *name)
  475. {
  476.     if (DataTypesInfo == NULL) {
  477.         DataTypesInfo = newDataList(len,name);
  478.         LastDataTypesInfo = DataTypesInfo;
  479.     }
  480.     else {
  481.         LastDataTypesInfo->Next = newDataList(len,name);
  482.         LastDataTypesInfo = LastDataTypesInfo->Next;
  483.     }
  484.     memcpy(LastDataTypesInfo->data,data,len);
  485.     return(Typesidx++);
  486.     
  487. }
  488.  
  489. extern int NrOfTypes;
  490. /*
  491. (0x0406) Data Member
  492. This leaf specifies nonstatic data members of a class.
  493.   
  494. 2            2        2            *        *
  495. LF_MEMBER    @type    attribute    offset    name
  496.  
  497. @type        Index to type record for field
  498. attribute    Member attribute bit field
  499. offset         Numeric leaf specifying the offset of field in the structure
  500. name        Length-prefixed name of the member field
  501. */
  502. int BuildFieldList(Field flist,int count)
  503. {
  504.     char *buffer,*p;
  505.     int memberType,len,result,padCount;
  506.  
  507.     p = buffer = malloc(16000);
  508.     *(unsigned short *)p = 0;
  509.     p += 2;
  510.     *(unsigned short *)p = 0x204;
  511.     p += 2;
  512.     while (flist) {
  513.         *(unsigned short *)p = LF_MEMBER; /* (0x406) */
  514.         p += 2;
  515.         memberType = GetTypeInternal(flist->type,flist->name);
  516.         *(unsigned short *)p = memberType;
  517.         p += 2;
  518.         *(unsigned short *)p = 0;
  519.         p += 2;
  520.         *(unsigned short *)p = flist->offset;
  521.         p += 2;
  522.         p = PutLengthPrefixedName(p,flist->name);
  523.         flist = flist->link;
  524.         len = (p - buffer);
  525.         /*
  526.         Because of the requirement for natural alignment, there may be padding 
  527.         between elements of the field list.  As a program walks down the field 
  528.         list, the address of the next subfield is calculated by adding the length 
  529.         of the previous field to the address of the previous field.  The byte at 
  530.         the new address is examined and if it is greater than 0xf0, the low four 
  531.         bits are extracted and added to the address to find the address of the next 
  532.         subfield. These padding fields are not included in the count field of the 
  533.         class, structure, union, or enumeration type records.
  534.         */
  535.         padCount = len % 4;
  536.         if (padCount) {
  537.             padCount = 4 - padCount;
  538.             *p++ = (char)(0xF0 | padCount--);
  539.             while (padCount > 0) {
  540.                 *p++ = (char)(0xF0|padCount--);
  541.             }
  542.         }
  543.     }
  544.     len = p - buffer;
  545.     p = buffer;
  546.     *(unsigned short *)p = len-2;
  547.     result = AddNewType(buffer,len,"");
  548.     free(buffer);
  549.     return(result);
  550. }
  551. char *PutNumericValue(char *dst,int size)
  552. {
  553.     if (size < 0x8000) {
  554.         *(unsigned short *)dst = size;
  555.         dst += 2;
  556.     }
  557.     else {
  558.         *(unsigned short *)dst = LF_LONG;
  559.         dst += 2;
  560.         *(unsigned long *)dst = size;
  561.         dst += 4;
  562.     }
  563.     return(dst);
  564. }
  565.  
  566. /*
  567. (0x0004) Classes and Structures
  568. The format for structures and classes is as follows:
  569.   
  570. 2        2        2        2            2        2        *        *
  571.  
  572. leaf    count    @field    property    @dList    @vshape    length    name
  573.  
  574. leaf    LF_CLASS or LF_STRUCTURE
  575. count    Number of elements  in the class or structure.  This count includes direct, 
  576.         virtual, and indirect virtual bases, and methods including overloads, data 
  577.         members, static data members, friends, and so on.
  578. @field    Type index of the field list for this class.    
  579. property    Property bit field
  580.  
  581.     packed    :1    Structure is packed
  582.     ctor    :1    Class has constructors and/or destructors
  583.     overops    :1    Class has overloaded operators
  584.     isnested    :1    Class is a nested class
  585.     cnested    :1    Class contains nested classes
  586.     opassign    :1    Class has overloaded assignment
  587.     opcast    :1    Class has casting methods
  588.     fwdref    :1    Class/structure is a forward (incomplete) reference
  589.     scoped    :1    This is a scoped definition
  590.     reserved    :8
  591. @dList    Type index of the derivation list.  This is output by the compiler as 
  592.         0x0000 and is filled in by the CVPACK utility to a  LF_DERIVED record 
  593.         containing the type indices of those classes which immediately inherit 
  594.         the current class.  A zero index indicates that no derivation information 
  595.         is available.  A LF_NULL index indicates that  the class is not inherited 
  596.         by other classes.
  597. @vshape    Type index of the virtual function table shape descriptor
  598. length    Numeric leaf specifying size in bytes of the structure
  599. name    Length-prefixed name this type
  600.  
  601. (0x0005) Structures
  602. Structures have the same format as classes.  Structure type records are used 
  603. exclusively by the C compiler.  The C++ compiler emits both class and structure 
  604. records depending upon the declaration.
  605. */
  606. int BuildStructType(Type ty,int cvType)
  607. {
  608.     char *name;
  609.     Field flist;
  610.     int size = ty->size;
  611.     int count,len,padCount,result;
  612.     Symbol sym;
  613.     char buffer[200],*p;
  614.  
  615.     sym = ty->u.sym;
  616.     name = sym->name;
  617.     flist = sym->u.s.flist; 
  618.     count  = 0;
  619.     while (flist) {
  620.         count++;
  621.         flist = flist->link;
  622.     }
  623.     flist = sym->u.s.flist;
  624.     memset(buffer,0,200);
  625.     p = buffer + 2;
  626.     *(unsigned short *)p = cvType;
  627.     p += 2;
  628.     *(unsigned short *)p = count;
  629.     p += 2;
  630.     *(unsigned short *)p = 0;
  631.     p += 2;
  632.     if (cvType == LF_STRUCTURE) {
  633.         /* ignore for the moment the problem of knowing if 
  634.         this structure is packed */
  635.         p += 2;
  636.         /* leave the derived field as zero */
  637.         p += 2;
  638.         /* no virtual functions */
  639.         p += 2;
  640.     }
  641.     else if (cvType == LF_UNION) {
  642.         /* Property bit field undocumented */
  643.         p += 2;
  644.     }
  645.     p = PutNumericValue(p,size);
  646.     *p++ = strlen(name);
  647.     while (*name) {
  648.         *p++ = *name++;
  649.     }
  650.     len = (p-buffer);
  651.     padCount = len % 4;
  652.     if (padCount) {
  653.         padCount = 4 - padCount;
  654.         *p++ = (char)(0xF0 | padCount--);
  655.         while (padCount > 0) {
  656.             *p++ = (char)(0xF0|padCount--);
  657.         }
  658.     }
  659.     len = (p - buffer)-2;
  660.     p = buffer;
  661.     *(unsigned short *)p = len;
  662.     result = AddNewType(buffer,len+2,sym->name);
  663.     p = LastDataTypesInfo->data + 6;
  664.     *(unsigned short *)p = BuildFieldList(flist,count)+4096;
  665.     return(result);
  666. }
  667.  
  668. int BuildPointerType(int xrefIdx)
  669. {
  670.     char buffer[8];
  671.     short *p;
  672.  
  673.     p = (short *)buffer;
  674.     p[0] = 6;
  675.     p[1] = LF_POINTER;
  676.     p[2] = 0xA; /* near 32 bit pointer */
  677.     p[3] = xrefIdx;
  678.     return(AddNewType(buffer,8,""));
  679. }
  680. static int AddToEmittedTypes(Type typ,int cvType)
  681. {
  682.     DataList *save;
  683.  
  684.     if (typ == NULL) return(0);
  685.     if (typ->op == POINTER) {
  686.         Type ty;
  687.  
  688.         ty = typ->type;
  689.         assert(ty);
  690.         if (ty->x.marked == 0) {
  691.             if (ty->op != STRUCT && ty->op != UNION) {
  692.                 return(0);
  693.             }
  694.             ty->x.typeno = Typesidx;
  695.             ty->x.marked = 1;
  696.             save = LastDataTypesInfo ;
  697.             if (ty->op == STRUCT) {
  698.                 BuildStructType(ty,LF_STRUCTURE);
  699.             }
  700.             else if (ty->op == UNION) {
  701.                 BuildStructType(ty,LF_UNION);
  702.             }
  703.             else return(0);
  704.         }
  705.         if (ty->x.pointerEmitted) {
  706.             return(ty->x.pointerIndex+4096);
  707.         }
  708.         ty->x.pointerEmitted = 1;
  709.         ty->x.pointerIndex = BuildPointerType(ty->x.typeno+4096);
  710.         return(ty->x.pointerIndex+4096);
  711.     }
  712.     if (typ->x.marked == 0) {
  713.         if (typ->op != STRUCT && typ->op != UNION) {
  714.             return(0);
  715.         }
  716.         typ->x.typeno = Typesidx;
  717.         typ->x.marked = 1;
  718.         save = LastDataTypesInfo;
  719.         if (typ->op == STRUCT) {
  720.             BuildStructType(typ,LF_STRUCTURE);
  721.         }
  722.         else if (typ->op == UNION) {
  723.             BuildStructType(typ,LF_UNION);
  724.         }
  725.     }
  726.     return(typ->x.typeno+4096);
  727. }
  728. /*
  729. (0x0003) Simple Array
  730.   
  731. 2            2            2            *        *
  732.  
  733. LF_ARRAY    @elemtype    @idxtype    length    name
  734.  
  735. @elemtype    Type index of each array element
  736. @idxtype    Type index of indexing variable 
  737. length    Length of array in bytes
  738. name    Length-prefixed name of array
  739.  
  740. */
  741. int AddArrayType(Type ty,char *name)
  742. {
  743.     int len,result;
  744.     char buf[256],*p,*n;
  745.  
  746.     assert(ty->type);
  747.     p = buf;
  748.     p += 2;
  749.     *(unsigned short *)p = LF_ARRAY;
  750.     p += 2;
  751.     n = NULL;
  752.     if (ty->type->u.sym)
  753.         n = ty->type->u.sym->name;
  754.     if (n == NULL) n = "";
  755.     *(unsigned short *)p = GetTypeInternal(ty->type,n);
  756.     p += 2;
  757.     *(unsigned short *)p = 0x74; /* index is signed int... */
  758.     p += 2;
  759.     p = PutNumericValue(p,ty->size);
  760.     p = PutLengthPrefixedName(p,name);
  761.     len = p - buf;
  762.     *(unsigned short *)buf = len - 2;
  763.     result = AddNewType(buf,len,name);
  764.     return result+4096;
  765.  
  766. }
  767.