Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6400 punk_joker 1
/***********************************************************************
2
 *
3
 *  avra - Assembler for the Atmel AVR microcontroller series
4
 *
5
 *  Copyright (C) 1998-2004 Jon Anders Haugum, Tobias Weber
6
 *
7
 * coff.c - Common Object File Format (COFF) support
8
 *
9
 *	This file was developed for the avra assembler in order to produce COFF output files
10
 *  for use with the Atmel AVR Studio.  The Lean C Compiler (LCC) debugging stabs
11
 *	output was used as input to the assembler.  The information used to develop this file
12
 *  was obtained from various sources on the Internet, most notably, the Free Software Foundation,
13
 *  The "stabs" debug format, ??? Chapter 7: Common Object File Format (COFF),
14
 *
15
 *	This software has absolutely no warrantee!  The money you paid for this will be
16
 *  promptly refunded if not fully satisfied.
17
 *
18
 *	Beta release 1/20/2000 by Bob Harris
19
 *
20
 *	This software has not been fully tested and probably has a few software deficiencies.
21
 *  Some software support may be possible by sending a problem description report to
22
 *  rth@mclean.sparta.com
23
 *
24
 *  Made the recommended change in write_coff_program().
25
 *  Fixed an obvious typo in SkipPastDigits().  The if() statement was terminated
26
 *  with a semicolon, which terminated the if(); early.  JEG 4-01-03
27
 */
28
 
29
#include 
30
#include 
31
#include 
32
#include 
33
#include 
34
 
35
#include "misc.h"
36
#include "avra.h"
37
#include "args.h"
38
 
39
#include "coff.h"
40
#include "device.h"	/* device flash and eeprom size */
41
 
42
 
43
struct FundamentalType {
44
 
45
    char const *pString;
46
    int Type;
47
    int Size;
48
};
49
 
50
struct FundamentalType FundamentalTypes[] = {
51
    {"null", T_NULL, 0},
52
    {"void", T_VOID, 0},
53
    {"char", T_CHAR, 1},
54
    {"short", T_SHORT, 1},
55
    {"int", T_INT, 1},
56
    {"long", T_LONG, 2},
57
    {"float", T_FLOAT, 4},
58
    {"double", T_DOUBLE, 4},
59
    {"struct", T_STRUCT, 0},
60
    {"union", T_UNION, 0},
61
    {"enum",  T_ENUM, 0},
62
    {"moe", T_MOE, 0},
63
    {"unsigned char", T_UCHAR, 1},
64
    {"unsigned short", T_USHORT, 1},
65
    {"unsigned int", T_UINT, 1},
66
    {"unsigned long", T_ULONG, 2},
67
    {"long double", T_LNGDBL, 2},
68
    {"long long int", T_LONG, 2},
69
    {"long int", T_LONG, 2},
70
    {"unsigned long long", T_ULONG, 2},
71
    {"signed char", T_CHAR, 1},
72
    {0, 0}
73
};
74
 
75
 
76
struct coff_info *ci;
77
 
78
/****************************************************************************************/
79
 
80
FILE *open_coff_file(struct prog_info *pi, char *filename){
81
 
82
    int ok /*, i*/;
83
    FILE *fp;
84
    //unsigned long *pu4;
85
    char*p;
86
 
87
 
88
    ci = calloc( 1, sizeof(struct coff_info) );
89
    if ( !ci )
90
        return( 0 );
91
 
92
    ok = True;
93
    /* default values */
94
    ci->CurrentFileNumber = 0;
95
    ci->pRomMemory = 0;
96
    ci->pEEPRomMemory = 0;
97
    ci->MaxRomAddress = 0;
98
    ci->MaxEepromAddress = 0;
99
    ci->NeedLineNumberFixup = 0;
100
    ci->GlobalStartAddress = -1;
101
    ci->GlobalEndAddress = 0;
102
 
103
    /* Linked lists start out at zero */
104
    InitializeList( &ci->ListOfSectionHeaders );
105
    InitializeList( &ci->ListOfRawData );
106
    InitializeList( &ci->ListOfRelocations );
107
    InitializeList( &ci->ListOfLineNumbers );
108
    InitializeList( &ci->ListOfSymbols );
109
    InitializeList( &ci->ListOfGlobals );
110
    InitializeList( &ci->ListOfSpecials );
111
    InitializeList( &ci->ListOfUndefined );
112
    InitializeList( &ci->ListOfStrings );
113
    InitializeList( &ci->ListOfTypes );
114
    InitializeList( &ci->ListOfSplitLines );
115
 
116
    /* add two default sections to SectionHeaders */
117
    if (  !AllocateListObject( &ci->ListOfSectionHeaders, sizeof(struct external_scnhdr) ) ||
118
          !AllocateListObject( &ci->ListOfSectionHeaders, sizeof(struct external_scnhdr) ) ) {
119
 
120
        fprintf(stderr, "\nOut of memory allocating section headers!");
121
        return( 0 );
122
    }
123
 
124
    /* add to string table */
125
    p = (char *)AllocateListObject( &ci->ListOfStrings,  4 );
126
    if ( !p ) {
127
        fprintf(stderr, "\nOut of memory allocating string table space!");
128
        return( 0 );
129
    }
130
 
131
    /* Allocate space for binary output into ROM, and EEPROM memory buffers for COFF output */
132
    /* ASSUMES ci->device is accurate */
133
    if ( (ci->pRomMemory = AllocateListObject( &ci->ListOfRawData, pi->device->flash_size * 2 ) ) != 0) {
134
        if ( (ci->pEEPRomMemory = AllocateListObject( &ci->ListOfRawData, pi->device->eeprom_size )) != 0) {
135
            ok = True; /* only true if both buffers are properly allocated */
136
            /* now fill them with 0xff's to simulate flash erasure */
137
            memset( (void *)ci->pRomMemory, 0xff, pi->device->flash_size * 2 );
138
            memset(    (   void    *)ci->pEEPRomMemory,    0xff,    pi->device->eeprom_size    );
139
        }
140
    }
141
    if ( ok != True )
142
        return( 0 );
143
 
144
    fp = fopen(filename,"wb");
145
    if ( fp == NULL ) {
146
        fprintf(stderr,"Error: cannot write coff file\n");
147
        return( fp );
148
    }
149
    /* simulate void type .stabs void:t15=r1;*/
150
    stab_add_local_type( "void", "15=r1;0;0;" );
151
 
152
    return( fp );
153
}
154
 
155
/****************************************************************************************/
156
void write_coff_file(struct prog_info *pi){
157
 
158
    //FILE *fp;
159
    //struct label *label;
160
    char /* File[256],*/*p;
161
    struct external_scnhdr *pSectionHdr;
162
    struct syment *pEntry;
163
    union auxent *pAux;
164
    unsigned long *plong;
165
    int NumberOfSymbols, SymbolIndex, LastFileIndex, LastFunctionIndex, LastFunctionAddress;
166
    LISTNODE *pNode;
167
    int LinesOffset, SymbolsOffset, StringsOffset, RawOffset;
168
    struct lineno *pLine;
169
 
170
    /* add two special sections */
171
    /* one for .text */
172
    if (  ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfSpecials, sizeof(struct syment) * 2 ) ) == 0 ) {
173
        fprintf(stderr, "\nOut of memory allocating special headers for .text!");
174
        return;
175
    }
176
    memset( pEntry->n_name, 0, 8 );
177
    strcpy( pEntry->n_name, ".text" );
178
    pEntry->n_value = 0;
179
    pEntry->n_scnum = 1;
180
    pEntry->n_type = 0;
181
    pEntry->n_sclass = C_STAT;
182
    pEntry->n_numaux = 1;
183
    pEntry++;
184
    pAux = (union auxent *)pEntry;
185
    pAux->x_scn.x_scnlen = ci->MaxRomAddress + 2;
186
    pAux->x_scn.x_nreloc = 0;
187
    pAux->x_scn.x_nlinno = ci->ListOfLineNumbers.TotalItems;
188
    /* one for .bss */
189
    if (  ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfSpecials, sizeof(struct syment) * 2 ) ) == 0 ) {
190
        fprintf(stderr, "\nOut of memory allocating special header for .bss!");
191
        return;
192
    }
193
    memset( pEntry->n_name, 0, 8 );
194
    strcpy( pEntry->n_name, ".bss" );
195
    if ( ci->GlobalStartAddress == -1 ) {
196
        ci->GlobalEndAddress = ci->GlobalStartAddress = 0x60;
197
    }
198
    pEntry->n_value = ci->GlobalStartAddress;
199
    pEntry->n_scnum = 2;
200
    pEntry->n_type = 0;
201
    pEntry->n_sclass = C_STAT;
202
    pEntry->n_numaux = 1;
203
    pEntry++;
204
    pAux = (union auxent *)pEntry;
205
    pAux->x_scn.x_scnlen = 0; /* we don't store any data here */
206
    pAux->x_scn.x_nreloc = 0;
207
    pAux->x_scn.x_nlinno = 0;
208
 
209
    /* one more for .data - eeprom ??? */
210
 
211
    /* Calculate common offsets into the file */
212
    RawOffset = sizeof(struct external_filehdr) + ci->ListOfSectionHeaders.TotalBytes;
213
    LinesOffset = RawOffset + ci->MaxRomAddress + 2; /* ignore eeprom for now */
214
    SymbolsOffset = LinesOffset + ci->ListOfLineNumbers.TotalBytes;
215
    StringsOffset = SymbolsOffset + ci->ListOfSymbols.TotalBytes + ci->ListOfSpecials.TotalBytes + ci->ListOfGlobals.TotalBytes;
216
 
217
    /* Clean up loose ends in string table */
218
    if ( !(plong  = (unsigned long *)FindFirstListObject(&ci->ListOfStrings))  ) {
219
        fprintf(stderr,"\nInternal error in string table!");
220
        return;
221
    }
222
    *plong = ci->ListOfStrings.TotalBytes; /* Size of string table */
223
 
224
    /* Clean up loose ends in symbol table */
225
 
226
    /*	symbol table - Filename value - index to next .file or global symbol */
227
    /* The value of that symbol equals the symbol table entry index of the next .file symbol or .global */
228
    LastFunctionAddress = ci->MaxRomAddress;
229
    NumberOfSymbols = ci->ListOfSymbols.TotalItems + ci->ListOfSpecials.TotalItems + ci->ListOfGlobals.TotalItems;
230
    SymbolIndex = LastFileIndex = NumberOfSymbols;
231
    LastFunctionIndex = 0; /* set to zero on last function */
232
    for ( pEntry = (struct syment *)FindLastListObject(&ci->ListOfSymbols);
233
        pEntry != 0;
234
        pEntry = (struct syment *)FindNextLastListObject(&ci->ListOfSymbols) ) {
235
 
236
        /* Search for .file entries designated by C_FILE */
237
        if ( pEntry->n_sclass == C_FILE ) {
238
            pEntry->n_value = LastFileIndex;
239
            LastFileIndex = SymbolIndex; /* save current index */
240
        }
241
        /* Search for Function entries C_EXT */
242
        else if (  pEntry->n_sclass == C_EXT ) {
243
            pEntry++;
244
            pAux = (union auxent *)pEntry;
245
            pAux->x_sym.x_misc.x_fsize = LastFunctionAddress - pEntry->n_value; /* function updated size */
246
            pAux->x_sym.x_fcnary.x_fcn.x_lnnoptr += LinesOffset;
247
            LastFunctionAddress = pEntry->n_value;
248
            pAux->x_sym.x_fcnary.x_fcn.x_endndx = LastFunctionIndex; /* point to next function index */
249
            pAux->x_sym.x_tvndx = 0; /* ??? */
250
            LastFunctionIndex = SymbolIndex;
251
        } else if (  (pEntry->n_sclass == C_FCN ) || ( pEntry->n_sclass == C_BLOCK) ) {
252
            if ( pEntry->n_name[1] == 'b' ) {
253
                /* .bf and .bb */
254
                pEntry++;
255
                pAux = (union auxent *)pEntry;
256
                pAux->x_sym.x_fcnary.x_fcn.x_endndx = LastFunctionIndex;
257
            }
258
        }
259
        /* else do nothing */
260
 
261
        /* update current symbol index */
262
        pNode = GetCurrentNode( &ci->ListOfSymbols );
263
        SymbolIndex -= ( pNode->Size / sizeof(struct syment) );
264
    }
265
 
266
    // File Header
267
    ci->FileHeader.f_magic = MAGIC_NUMBER_AVR;
268
    ci->FileHeader.f_nscns = 2;
269
//    ci->FileHeader.f_timdat = time( (time_t *)&ci->FileHeader.f_timdat);
270
    ci->FileHeader.f_timdat = pi->time;
271
    ci->FileHeader.f_symptr = SymbolsOffset;
272
    ci->FileHeader.f_nsyms = NumberOfSymbols;
273
    ci->FileHeader.f_opthdr = 0;
274
    ci->FileHeader.f_flags = 0xff; /*F_RELFLG;*/ /* No relocation information available */
275
 
276
    /* write it out */
277
    if ( fwrite(&ci->FileHeader, 1, sizeof(struct external_filehdr), pi->coff_file ) !=  sizeof(struct external_filehdr) ) {
278
        fprintf(stderr,"\nFile error writing header ...(disk full?)");
279
        return;
280
    }
281
 
282
    // Optional Information
283
 
284
    // Section 1 Header
285
    pSectionHdr = (struct external_scnhdr *)FindFirstListObject(&ci->ListOfSectionHeaders);
286
    if ( !pSectionHdr ) {
287
        fprintf(stderr, "\nInternal Coff error - cannot find section header .text!");
288
        return;
289
    }
290
    memset( &pSectionHdr->s_name[0], 0, sizeof(struct external_scnhdr) );
291
    strcpy( &pSectionHdr->s_name[0], ".text");
292
    pSectionHdr->s_paddr = 0;
293
    pSectionHdr->s_vaddr = 0;
294
    pSectionHdr->s_size = ci->MaxRomAddress + 2; /* remember the last instruction */
295
    pSectionHdr->s_scnptr = RawOffset;
296
    pSectionHdr->s_relptr = 0;
297
    pSectionHdr->s_lnnoptr = LinesOffset;
298
    pSectionHdr->s_nreloc = 0;
299
    pSectionHdr->s_nlnno = ci->ListOfLineNumbers.TotalBytes/sizeof(struct lineno);
300
    pSectionHdr->s_flags = STYP_TEXT;
301
 
302
    /* write it out */
303
    if ( fwrite(&pSectionHdr->s_name[0], 1, sizeof(struct external_scnhdr), pi->coff_file ) !=  sizeof(struct external_scnhdr) ) {
304
        fprintf(stderr,"\nFile error writing section header ...(disk full?)");
305
        return;
306
    }
307
 
308
    // Section 2 Header
309
    pSectionHdr = (struct external_scnhdr *)FindNextListObject(&ci->ListOfSectionHeaders);
310
    if ( !pSectionHdr ) {
311
        fprintf(stderr, "\nInternal Coff error - cannot find section header .bss!");
312
        return;
313
    }
314
    memset( &pSectionHdr->s_name[0], 0, sizeof(struct external_scnhdr) );
315
    strcpy( &pSectionHdr->s_name[0], ".bss");
316
    /* later expansion */
317
    pSectionHdr->s_paddr = ci->GlobalStartAddress;
318
    pSectionHdr->s_vaddr = ci->GlobalStartAddress;
319
    pSectionHdr->s_flags = STYP_DATA; /* seems it should be STYP_BSS */
320
 
321
    /* write it out */
322
    if ( fwrite(&pSectionHdr->s_name[0], 1, sizeof(struct external_scnhdr), pi->coff_file ) !=  sizeof(struct external_scnhdr) ) {
323
        fprintf(stderr,"\nFile error writing section header ...(disk full?)");
324
        return;
325
    }
326
 
327
    /* Section N Header - .data or eeprom */
328
 
329
    // Raw Data for Section 1
330
    if ( (p = FindFirstListObject(&ci->ListOfRawData) ) == 0 ) {
331
        fprintf(stderr,"\nInternal error - unable to find binary data!");
332
        return;
333
    }
334
 
335
    /* write it out */
336
    if ( fwrite( p, 1, ci->MaxRomAddress + 2, pi->coff_file ) != (size_t)(ci->MaxRomAddress + 2) ) {
337
        fprintf(stderr,"\nFile error writing raw .text data ...(disk full?)");
338
        return;
339
    }
340
    // Raw data for section n
341
 
342
    // Relocation Info for section 1
343
 
344
    // Relocation info for section n
345
 
346
    // Line numbers for section 1
347
    for ( pLine = (struct lineno *)FindFirstListObject( &ci->ListOfLineNumbers );
348
        pLine != 0;
349
        pLine = (struct lineno *)FindNextListObject( &ci->ListOfLineNumbers ) ) {
350
 
351
        pNode = GetCurrentNode( &ci->ListOfLineNumbers );
352
 
353
        /* write it out */
354
        if ( fwrite( pLine, 1, pNode->Size, pi->coff_file ) != pNode->Size ) {
355
            fprintf(stderr,"\nFile error writing line numbers ...(disk full?)");
356
            return;
357
        }
358
    }
359
 
360
 
361
    // Line numbers for section n
362
 
363
    // Symbol table
364
    for ( pEntry = (struct syment *)FindFirstListObject( &ci->ListOfSymbols );
365
        pEntry != 0;
366
        pEntry = (struct syment *)FindNextListObject( &ci->ListOfSymbols ) ) {
367
 
368
        pNode = GetCurrentNode( &ci->ListOfSymbols );
369
 
370
        /* write it out */
371
        if ( fwrite( pEntry, 1, pNode->Size, pi->coff_file ) != pNode->Size ) {
372
            fprintf(stderr,"\nFile error writing symbol table ...(disk full?)");
373
            return;
374
        }
375
    }
376
 
377
    // Symbol table of Globals
378
    for ( pEntry = (struct syment *)FindFirstListObject( &ci->ListOfGlobals );
379
        pEntry != 0;
380
        pEntry = (struct syment *)FindNextListObject( &ci->ListOfGlobals ) ) {
381
 
382
        pNode = GetCurrentNode( &ci->ListOfGlobals );
383
 
384
        /* write it out */
385
        if ( fwrite( pEntry, 1, pNode->Size, pi->coff_file ) != pNode->Size ) {
386
            fprintf(stderr,"\nFile error writing global symbols ...(disk full?)");
387
            return;
388
        }
389
    }
390
 
391
    /* Specials .text, .bss, .data */
392
 
393
    for ( pEntry = (struct syment *)FindFirstListObject( &ci->ListOfSpecials );
394
        pEntry != 0;
395
        pEntry = (struct syment *)FindNextListObject( &ci->ListOfSpecials ) ) {
396
 
397
        pNode = GetCurrentNode( &ci->ListOfSpecials );
398
 
399
        /* write it out */
400
        if ( fwrite( pEntry, 1, pNode->Size, pi->coff_file ) != pNode->Size ) {
401
            fprintf(stderr,"\nFile error writing special symbols ...(disk full?)");
402
            return;
403
        }
404
    }
405
 
406
    // String Table
407
    for ( p = (char *)FindFirstListObject( &ci->ListOfStrings );
408
        p != 0;
409
        p = (char *)FindNextListObject( &ci->ListOfStrings ) ) {
410
 
411
        pNode = GetCurrentNode( &ci->ListOfStrings );
412
 
413
        /* write it out */
414
        if ( fwrite( p, 1, pNode->Size, pi->coff_file ) != pNode->Size ) {
415
            fprintf(stderr,"\nFile error writing strings data ...(disk full?)");
416
            return;
417
        }
418
    }
419
 
420
    return;
421
}
422
 
423
/****************************************************************************************/
424
 
425
void write_coff_eeprom( struct prog_info *pi, int address, unsigned char data){
426
 
427
    if ( !GET_ARG(pi->args, ARG_COFF) )
428
        return;
429
 
430
    /* Coff output keeps track of binary data in memory buffers */
431
    if ( ci->pEEPRomMemory ) {
432
        if ( address <= pi->device->eeprom_size ) {
433
            *(ci->pEEPRomMemory + address) = data;
434
            if ( address >= ci->MaxEepromAddress )
435
                ci->MaxEepromAddress = address;   /* keep high water mark */
436
        } else {
437
            pi->error_count++;
438
            fprintf(stderr, "Error: EEPROM address %d exceeds max range %d", address, pi->device->eeprom_size );
439
        }
440
    }
441
}
442
/****************************************************************************************/
443
 
444
void write_coff_program( struct prog_info *pi, int address, unsigned int data){
445
 
446
    unsigned char *pByte;
447
 
448
    if ( !GET_ARG(pi->args, ARG_COFF) )
449
        return;
450
 
451
    /* Coff output keeps track of binary data in memory buffers, address is in bytes not words */
452
    if ( ci->pRomMemory ) {
453
/* JEG	if ( address <= pi->device->flash_size ) {  */  /* JEG 4-23-03 */
454
		if ( address <= pi->device->flash_size*2 ) {
455
            pByte = (unsigned char *)(ci->pRomMemory + address); /* point to low byte in memory */
456
            *pByte++ = (data & 0xff);   /* low byte */
457
            *pByte = ((data >> 8) & 0xff); /* high byte */
458
 
459
            if ( address >= ci->MaxRomAddress )
460
                ci->MaxRomAddress = address;   /* keep high water mark */
461
        } else {
462
            pi->error_count++;
463
/* JEG		fprintf(stderr, "Error: FLASH address %d exceeds max range %d", address, pi->device->flash_size ); */
464
			fprintf(stderr, "Error: FLASH address %d exceeds max range %d", address, pi->device->flash_size*2 );
465
        }
466
    }
467
}
468
 
469
/****************************************************************************************/
470
 
471
void close_coff_file(struct prog_info *pi, FILE *fp){
472
 
473
    /* close the output file */
474
    fclose( fp );
475
    pi->coff_file = 0;
476
 
477
    /* free all the internal memory buffers used by ci */
478
 
479
    FreeList( &ci->ListOfSectionHeaders );
480
    FreeList( &ci->ListOfRawData );
481
    FreeList( &ci->ListOfRelocations );
482
    FreeList( &ci->ListOfLineNumbers );
483
    FreeList(    &ci->ListOfSymbols    );
484
    FreeList( &ci->ListOfGlobals );
485
    FreeList( &ci->ListOfUndefined );
486
    FreeList( &ci->ListOfStrings );
487
    FreeList( &ci->ListOfTypes );
488
    FreeList( &ci->ListOfSplitLines );
489
 
490
    /* now free ci */
491
    free( ci );
492
    ci = 0;
493
}
494
 
495
/****************************************************************************************/
496
 
497
int parse_stabs( struct prog_info *pi, char *p ){
498
 
499
    int ok = True;
500
    int TypeCode, n;
501
    char *pString, *p2, *p3, *p4, *p5, *pType, *pEnd, *pp, *pJoined;
502
 
503
 
504
    if ( !GET_ARG(pi->args, ARG_COFF) || ( pi->pass == PASS_1 ) )
505
        return(True);
506
 
507
    /* stabs debugging information is in the form:
508
    .stabs "symbolic info string", HexorDecimalTypecode, parm3, parm4, parm5
509
    parm1, parm2, parm3 depend on typecode
510
 
511
    N_LSYM	0x80		local sym: name,,0,type,offset
512
    N_OPT	0x3c		compiler options
513
    N_SO	0x64		source file name: name,,0,0,address
514
    N_SOL	0x84		#included file name: name,,0,0,address
515
    N_FUN	0x24		procedure: name,,0,linenumber,address
516
    N_GSYM	0x20		global symbol: name,,0,type,0
517
    N_LCSYM	0x28		.lcomm symbol: name,,0,type,address
518
    N_STSYM	0x26		static symbol: name,,0,type,address
519
    N_RSYM	0x40		register sym: name,,0,type,register
520
    N_PSYM	0xa0		parameter: name,,0,type,offset
521
 
522
    */
523
 
524
    /* Look for multiple commands per line */
525
 
526
    /* .stabs "linktag:T19=s46next:20=*19,0,16;last:20,16,16;a:21=ar1;0;2;22=ar1;0;3;1,32,96;\\",128,0,0,0 */
527
    /* .stabs "b:23=ar1;0;4;24=ar1;0;5;2,128,240;;",128,0,0,0 */
528
 
529
 
530
    /* Look for continuation lines per line */
531
 
532
    /* Get String information as a token */
533
    /* Parse the tokens in the stabn line buffer */
534
    pString = get_next_token(p, TERM_DOUBLEQUOTE );     /* zap first doublequote */
535
    p2 = get_next_token(pString, TERM_DOUBLEQUOTE );    /* zap last doublequote */
536
    p2 = get_next_token(p2, TERM_COMMA );               /* zap comma */
537
    p3 = get_next_token(p2, TERM_COMMA );
538
    p4 = get_next_token(p3, TERM_COMMA );
539
    p5 = get_next_token(p4, TERM_COMMA );
540
    pEnd = get_next_token(p5, TERM_END ); /* zap CR LF, make ASCIIZ */
541
 
542
    if ( !pString || !p2 || !p3 || !p4 || !p5 )
543
        return( False );
544
 
545
    /* Check for split lines */
546
    n = strlen( pString );
547
    if ( ( pString[n - 1] == '\\' ) && (pString[n - 2] == '\\') ) {
548
        /* We have a continuation string here */
549
        pString[n - 2] = 0;
550
        n -= 2;
551
        if ( !(pp = (char *)AllocateListObject( &ci->ListOfSplitLines, n + 1 ))  ) {
552
            fprintf(stderr, "\nOut of memory allocating continuation line!");
553
            return( False );
554
        }
555
        strcpy( pp, pString ); /* loose the continuation characters */
556
        return(True);
557
    }
558
    if ( ci->ListOfSplitLines.TotalItems > 0 ) {
559
        /* Join lines together and process */
560
        if ( !(pJoined = calloc( 1, n + ci->ListOfSplitLines.TotalBytes ) ) ) {
561
            fprintf(stderr, "\nOut of memory joining continuation lines!");
562
            return( False );
563
        }
564
        for ( pp = (char *)FindFirstListObject( &ci->ListOfSplitLines );
565
            pp != 0;
566
            pp = (char *)FindNextListObject( &ci->ListOfSplitLines ) ) {
567
 
568
            strcat( pJoined, pp ); /* connect the lines */
569
        }
570
        strcat( pJoined, pString );
571
        FreeList( &ci->ListOfSplitLines );
572
        if ( !AddListObject( &ci->ListOfSplitLines, pJoined, n + ci->ListOfSplitLines.TotalBytes )  ) {
573
            fprintf(stderr, "\nUnable to add joined continuation line");
574
            return( False );
575
        }
576
        pString = pJoined;
577
    }
578
 
579
 
580
    if ( *p2 == '0' )
581
        TypeCode = atox(p2);    /* presume to be hex 0x */
582
    else
583
        TypeCode = atoi(p2);
584
 
585
    switch ( TypeCode ) {
586
 
587
    case N_OPT:     /* compiler options */
588
        break;      /* nothing used here */
589
 
590
    case N_SO:      /* source file name: name,,0,0,address */
591
        ok = stab_add_filename( pString, p5 );
592
        break;
593
 
594
    case N_GSYM:    /* global symbol: name,,0,type,0 */
595
        pType = get_next_token(pString, TERM_COLON );   /* separate at colon */
596
        ok = stab_add_global( pi, pString, pType );
597
        break;
598
 
599
    case N_FUN:     /* procedure: name,,0,linenumber,address */
600
        ok = stab_add_function( pi, pString, p5 );
601
        break;
602
 
603
    case N_LSYM:    /* local sym: name,,0,type,offset */
604
        /* pString, p2 = TypeCode, p3 = 0, p4 = 0, p5 = offset */
605
        pType = get_next_token(pString, TERM_COLON );   /* pType = symbol descriptor (character after the colon) */
606
        if ( *pType == 't')
607
            ok = stab_add_local_type( pString, ++pType );
608
        else if (*pType == 'T')
609
            ok = stab_add_tag_type( pString, ++pType );
610
        else
611
            ok = stab_add_local( pi, pString, pType, p5 );
612
        break;
613
 
614
    case N_RSYM:    /* Symbol:[P|r]type,0,size,register */
615
        pType = get_next_token(pString, TERM_COLON );   /* separate at colon */
616
        ok = stab_add_local_register( pi, pString, pType, p5 );
617
        break;
618
 
619
    case N_LCSYM:   /* .lcomm symbol: name,,0,type,address */
620
        ok = True;
621
        break;  /* ignore constants */
622
 
623
    case N_STSYM:   /* static symbol: name,,0,type,address */
624
        pType = get_next_token(pString, TERM_COLON );   /* separate at colon */
625
        ok = stab_add_static_symbol( pi, pString, pType, p5 );
626
        break;
627
 
628
    case N_PSYM:    /* parameter: name,,0,type,offset */
629
        pType = get_next_token(pString, TERM_COLON );   /* separate at colon */
630
        ok = stab_add_parameter_symbol( pi, pString, pType, p5 );
631
        break;
632
 
633
    case N_SOL:     /* #included file name: name,,0,0,address */
634
        ok = True;
635
        break;  /* ignore include files */
636
 
637
    default:
638
        ok = False;
639
    }
640
 
641
    if ( ci->ListOfSplitLines.TotalItems > 0 )
642
        FreeList( &ci->ListOfSplitLines );
643
 
644
    return( ok );
645
}
646
/****************************************************************************************/
647
 
648
int parse_stabn( struct prog_info *pi, char *p ){
649
 
650
    int ok = True;
651
    int TypeCode /* , LineNumber */, Level;
652
    char *p1, *p2, *p3, *p4, *pLabel, *pFunction, *pEnd;
653
 
654
    /* stabn debugging information is in the form:
655
    .stabn TypeCode, 0, parm1, parm2
656
    parm1 is level
657
    parm2 is Label-Function
658
 
659
    compiler currently produces the following TypeCodes:
660
    N_LBRAC	0xc0		left bracket: 0,,0,nesting level,address
661
    N_RBRAC	0xe0		right bracket: 0,,0,nesting level,address
662
    N_SLINE	0x44		src line: 0,,0,linenumber,address
663
    */
664
 
665
    if ( !GET_ARG(pi->args, ARG_COFF) || ( pi->pass == PASS_1 ) )
666
        return(True);
667
 
668
    /* Parse the tokens in the stabn line buffer */
669
    p1 = get_next_token(p, TERM_SPACE );
670
    p2 = get_next_token(p1, TERM_COMMA );
671
    p3 = get_next_token(p2, TERM_COMMA );
672
    p4 = get_next_token(p3, TERM_COMMA );
673
    pEnd = get_next_token(p4, TERM_END ); /* zap CR LF, make ASCIIZ */
674
 
675
    if ( !p1 || !p2 || !p3 || !p4 )
676
        return( False );
677
 
678
    /* first convert TypeCode to binary */
679
    if ( *p1 == '0' )
680
        TypeCode = atox(p1);    /* presume to be hex 0x */
681
    else
682
        TypeCode = atoi(p1);
683
 
684
    Level = atoi(p3);   /* line number or level */
685
    pLabel = p4;                /* Assembly label */
686
    pFunction = get_next_token( pLabel, TERM_DASH ); /* Function */
687
 
688
    switch ( TypeCode ) {
689
    case N_SLINE:           /* src line: 0,,0,linenumber,address */
690
        ok = stab_add_lineno( pi, Level, pLabel, pFunction );
691
        break;
692
 
693
    case N_LBRAC:           /* left bracket: 0,,0,nesting level,address */
694
        ok = stab_add_lbracket( pi, Level, pLabel, pFunction );
695
        break;
696
 
697
    case N_RBRAC:           /* right bracket: 0,,0,nesting level,address */
698
        ok = stab_add_rbracket( pi, Level, pLabel, pFunction );
699
        break;
700
 
701
    default:
702
        fprintf(stderr, "\nUnknown .stabn TypeCode = 0x%x", TypeCode );
703
        ok = False;
704
    }
705
    return( ok );
706
}
707
 
708
/****************************************************************************************/
709
int stab_add_lineno(  struct prog_info *pi, int LineNumber, char *pLabel, char *pFunction ){
710
 
711
    int Address;
712
    struct lineno *pln;
713
    struct syment *pEntry;
714
    union auxent *pAux;
715
 
716
    /* Allocate LineNumber Table entry and fill it in */
717
    pln = (struct lineno *)AllocateListObject(&ci->ListOfLineNumbers, sizeof(struct lineno)  );
718
    if ( !pln ) {
719
        fprintf(stderr, "\nOut of memory allocating lineno table for function %s", pFunction );
720
        return( False );
721
    }
722
    /* set value field to be address of label in bytes */
723
    if ( !get_symbol(pi, pLabel, &Address) ) {
724
        fprintf(stderr, "\nUnable to locate label %s", pLabel );
725
        return( False );
726
    }
727
    pln->l_addr.l_paddr = Address * 2; /* need byte quanities */
728
 
729
    /* Line number is relative to beginning of function, starts at 1 */
730
    if ( ci->FunctionStartLine == 0 ) {
731
        /* This line number is that same as the function start */
732
        ci->FunctionStartLine = LineNumber;
733
    }
734
    pln->l_lnno = LineNumber - ci->FunctionStartLine + 1;
735
    ci->CurrentSourceLine = LineNumber; /* keep track of source line for .eb .ef arrays */
736
    if ( ci->NeedLineNumberFixup ) {
737
        /* need to go into symbol table and fix last NeedLineNumberFixup entries */
738
        for ( pEntry = (struct syment *)FindLastListObject(&ci->ListOfSymbols);
739
            (pEntry != 0) && ( ci->NeedLineNumberFixup != 0);
740
            pEntry = (struct syment *)FindNextLastListObject(&ci->ListOfSymbols) ) {
741
 
742
            /* Fix up line number entries */
743
            if ( (pEntry->n_sclass == C_FCN ) || ( pEntry->n_sclass == C_BLOCK ) || ( pEntry->n_sclass == C_EXT) ) {
744
                pEntry++;
745
                pAux = (union auxent *)pEntry;
746
                pAux->x_sym.x_misc.x_lnsz.x_lnno = LineNumber;
747
                ci->NeedLineNumberFixup--;
748
            }
749
        }
750
    }
751
 
752
    return(True);
753
}
754
/****************************************************************************************/
755
 
756
int stab_add_lbracket( struct prog_info *pi, int Level, char *pLabel, char *pFunction ){
757
 
758
    int Address;
759
    struct syment *pEntry;
760
    union auxent *pAux;
761
    //char *p;
762
    //struct lineno *pln;
763
 
764
    if ( !get_symbol(pi, pLabel, &Address) ) {
765
        fprintf(stderr, "\nUnable to locate label %s", pLabel );
766
        return( False );
767
    }
768
 
769
    /* Now create a .bb symbol table entry and aux entry too */
770
    pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols,  sizeof(struct syment) * 2 );
771
    if ( !pEntry ) {
772
        fprintf(stderr, "\nOut of memory allocating symbol table entry for .bb %s", pLabel );
773
        return( False );
774
    }
775
    /* n_name */
776
    memset( pEntry->n_name, 0, 8 );
777
    strcpy( pEntry->n_name, ".bb" );
778
 
779
    pEntry->n_value = Address * 2;  /* bytes not words */
780
    pEntry->n_scnum = 1;    /* .text */
781
    pEntry->n_type = 0;
782
    pEntry->n_sclass = C_BLOCK;
783
    pEntry->n_numaux = 1;
784
    pEntry++;   /* point to aux entry */
785
    pAux = (union auxent *)pEntry;
786
    pAux->x_sym.x_misc.x_lnsz.x_lnno = 0;   /* UNKNOWN - post process */
787
    pAux->x_sym.x_misc.x_lnsz.x_size = 0;   /* UNKNOWN - post process */
788
    ci->NeedLineNumberFixup++; /* once for .bb block */
789
    return(True);
790
}
791
 
792
/****************************************************************************************/
793
int stab_add_rbracket( struct prog_info *pi, int Level, char *pLabel, char *pFunction ){
794
 
795
    int Address;
796
    struct syment *pEntry;
797
    union auxent *pAux;
798
    //char *p;
799
    //struct lineno *pln;
800
 
801
    if ( !get_symbol(pi, pLabel, &Address) ) {
802
        fprintf(stderr, "\nUnable to locate label %s", pLabel );
803
        return( False );
804
    }
805
 
806
    /* Now create a .eb symbol table entry */
807
    pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols,  sizeof(struct syment) * 2 );
808
    if ( !pEntry ) {
809
        fprintf(stderr, "\nOut of memory allocating symbol table entry for .eb %s", pLabel );
810
        return( False );
811
    }
812
    /* n_name */
813
    memset( pEntry->n_name, 0, 8 );
814
    strcpy( pEntry->n_name, ".eb" );
815
    pEntry->n_sclass = C_BLOCK;
816
    pEntry->n_value = Address * 2;  /* bytes not words */
817
    pEntry->n_scnum = 1;    /* .text */
818
    pEntry->n_type = 0;
819
    pEntry->n_numaux = 1;
820
    pEntry++;   /* point to aux entry */
821
    pAux = (union auxent *)pEntry;
822
    pAux->x_sym.x_misc.x_lnsz.x_lnno = ci->CurrentSourceLine;
823
 
824
    /* create an .ef if at level 0 */
825
    if ( Level == 0 ) {
826
 
827
        /* Now create a .ef symbol table entry */
828
        pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols,  sizeof(struct syment) * 2 );
829
        if ( !pEntry ) {
830
            fprintf(stderr, "\nOut of memory allocating symbol table entry for .ef %s", pLabel );
831
            return( False );
832
        }
833
        /* n_name */
834
        memset( pEntry->n_name, 0, 8 );
835
        strcpy( pEntry->n_name, ".ef" );
836
        pEntry->n_sclass = C_FCN;
837
        pEntry->n_value = Address * 2;  /* bytes not words */
838
        pEntry->n_scnum = 1;    /* .text */
839
        pEntry->n_type = 0;
840
        pEntry->n_numaux = 1;
841
        pEntry++;   /* point to aux entry */
842
        pAux = (union auxent *)pEntry;
843
        pAux->x_sym.x_misc.x_lnsz.x_lnno = ci->CurrentSourceLine;
844
    }
845
    return(True);
846
}
847
 
848
/****************************************************************************************/
849
int stab_add_filename( char *pName, char *pLabel ){
850
 
851
    int ok, n;
852
    struct syment *pEntry;
853
    union auxent *pAux;
854
    char *p;
855
 
856
    /* if( pLabel == "Ltext0" ) then beginning of .text, pName = cwd, next pName = file */
857
 
858
    /* if( pLabel == "Letext" ) then end of .text , pName == NULL */
859
 
860
    /* we only need the one not ending in Slash */
861
    ok = True;
862
    n = strlen(pName);
863
    if ( n > 0 ) {
864
        if ( ( pName[ n - 1] == '\\') || (pName[ n - 1] == '/') )
865
            return(True); /* ignore */
866
    } else
867
        return(True);
868
 
869
 
870
    /* allocate entry in symbol table list */
871
    pEntry = (struct syment *)AllocateTwoListObjects(
872
                                                    &ci->ListOfSymbols,  sizeof(struct syment) * 2 ); /* aux entry too */
873
    if ( !pEntry ) {
874
        fprintf(stderr, "\nOut of memory allocating symbol table entry for global %s", pName );
875
        return( False );
876
    }
877
    /* n_name */
878
    memset( pEntry->n_name, 0, 8 );
879
    strcpy( pEntry->n_name, ".file" );
880
    /* n_value is determined after processing done UNKNOWN - post process */
881
    /* The value of that symbol equals the symbol table entry index of the next .file symbol or .global */
882
    /* post process */
883
    pEntry->n_scnum = N_DEBUG;
884
    pEntry->n_sclass = C_FILE;
885
    pEntry->n_numaux = 1;
886
    pEntry++;   /* point to aux entry */
887
    pAux = (union auxent *)pEntry;
888
 
889
    /* Add Label name to symbol table */
890
    if ( n <= FILNMLEN ) {
891
        /* inline filename */
892
        memset( pAux->x_file.x_fname, 0, FILNMLEN );
893
        strncpy( pAux->x_file.x_fname, pName, n ); /* might not be zero terminated */
894
    } else {
895
        pAux->x_file.x_n.x_zeroes = 0;  /* symbol name is in string table */
896
        pAux->x_file.x_n.x_offset = ci->ListOfStrings.TotalBytes;
897
 
898
        /* add to string table */
899
        p = (char *)AllocateListObject( &ci->ListOfStrings,  n + 1 );
900
        if ( !p ) {
901
            fprintf(stderr, "\nOut of memory allocating string table space!");
902
            return( False );
903
        }
904
        strcpy( p, pName );
905
    }
906
    return( ok );
907
}
908
 
909
/****************************************************************************************/
910
int stab_add_function( struct prog_info *pi, char *pName, char *pLabel ){
911
 
912
    int n, Address;
913
    unsigned short CoffType, Type;
914
    struct syment *pEntry;
915
    char *pType;
916
    struct lineno *pln;
917
    union auxent *pAux;
918
    int SymbolIndex;
919
 
920
    pType = get_next_token(pName, TERM_COLON ); /* pType = symbol descriptor (character after the colon) */
921
    Type = atoi(pType + 1);     /* skip past F, predefined variable type */
922
    if ( (CoffType = GetCoffType( Type )) == 0 ) {
923
        fprintf(stderr, "\nUnrecognized return type found for function %s = %d", pName, Type );
924
        return(False);
925
    }
926
    /* Get Current Symbol Index, Allocate Symbol Table entry and fill it in */
927
    SymbolIndex = ci->ListOfSymbols.TotalItems;
928
    pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 );
929
    if ( !pEntry ) {
930
        fprintf(stderr, "\nOut of memory allocating symbol table entry for function %s", pName );
931
        return( False );
932
    }
933
    if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) {
934
        fprintf(stderr,"\nOut of memory adding local %s to string table", pName );
935
    }
936
    if ( !get_symbol(pi, pLabel, &Address) ) {
937
        fprintf(stderr, "\nUnable to locate function %s", pName );
938
        return( False );
939
    }
940
    pEntry->n_value = Address * 2;  /* convert words to bytes */
941
    pEntry->n_scnum = 2;    /* .bss */
942
    if ( (CoffType = GetCoffType( Type )) == 0 ) {
943
        fprintf(stderr, "\nUnrecognized type found for function %s = %d", pName, Type );
944
        return(False);
945
    }
946
    pEntry->n_type = (unsigned short)(CoffType | (DT_FCN << 4));
947
    pEntry->n_sclass = C_EXT;
948
    pEntry->n_numaux = 1;
949
    pEntry++;   /* point to aux entry */
950
    pAux = (union auxent *)pEntry;
951
    pAux->x_sym.x_tagndx = SymbolIndex + 1; /* point to the .bf entry index */
952
    // wrong!
953
    //	pAux->x_sym.x_misc.x_lnsz.x_lnno = ci->ListOfLineNumbers.TotalBytes; /* Relative Fixup point to where line numbers start */
954
    //	pAux->x_sym.x_misc.x_lnsz.x_size = 0; /* UNKNOWN till next function called */
955
    pAux->x_sym.x_misc.x_fsize = 0; /* unknown till end */
956
    pAux->x_sym.x_fcnary.x_fcn.x_lnnoptr = ci->ListOfLineNumbers.TotalBytes; /* relative offset to line number entry */
957
    pAux->x_sym.x_fcnary.x_fcn.x_endndx = 0; /* index to next entry */
958
 
959
    /* Now add function entry into the line number table */
960
    /* Allocate Symbol Table entry and fill it in */
961
    pln = (struct lineno *)AllocateListObject(&ci->ListOfLineNumbers, sizeof(struct lineno)  );
962
    if ( !pln ) {
963
        fprintf(stderr, "\nOut of memory allocating lineno table for function %s", pName );
964
        return( False );
965
    }
966
    pln->l_lnno = 0;
967
    pln->l_addr.l_symndx = SymbolIndex;
968
 
969
    /* Initialize the FunctionStartLine from the beginning of the function */
970
    ci->FunctionStartLine = 0;
971
 
972
    /* Allocate Symbol Table entry and fill it in */
973
    pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 );
974
    if ( !pEntry ) {
975
        fprintf(stderr, "\nOut of memory allocating symbol table entry .bf for function %s", pName );
976
        return( False );
977
    }
978
    memset( pEntry->n_name, 0, 8 );
979
    strcpy( pEntry->n_name, ".bf" );
980
    pEntry->n_value = Address * 2;  /* bytes not words */
981
    pEntry->n_scnum = 1;    /* .text */
982
    pEntry->n_type = 0;
983
    pEntry->n_sclass = C_FCN;
984
    pEntry->n_numaux = 1;
985
    pEntry++;   /* point to aux entry */
986
    pAux = (union auxent *)pEntry;
987
    pAux->x_sym.x_misc.x_lnsz.x_lnno = 0;   /* UNKNOWN - post process */
988
    pAux->x_sym.x_misc.x_lnsz.x_size = 0;   /* UNKNOWN - post process */
989
 
990
    ci->NeedLineNumberFixup++; /* once for function C_EXT symbol */
991
    ci->NeedLineNumberFixup++; /* once for .bf block */
992
    return( True );
993
}
994
/****************************************************************************************/
995
 
996
int stab_add_global( struct prog_info *pi, char *pName, char *pType ){
997
 
998
    int n, Address, IsArray, SymbolIndex;
999
    unsigned short CoffType, Type;
1000
    struct syment *pEntry;
1001
    char *p;
1002
    STABCOFFMAP *pMap;
1003
 
1004
 
1005
    n = strlen( pName );    /* see if it's 8 bytes or less */
1006
    Type = atoi(pType + 1);     /* skip past G, predefined variable type */
1007
    if ( (CoffType = GetCoffType( Type )) == 0 ) {
1008
        fprintf(stderr, "\nUnrecognized type found for global %s = %d", pName, Type );
1009
        return(False);
1010
    }
1011
    pMap = (STABCOFFMAP *)GetCurrentListObject( &ci->ListOfTypes );
1012
 
1013
    SymbolIndex = ci->ListOfSymbols.TotalItems;
1014
    /* Allocate Symbol Table entry and fill it in, Auxiliary table if its an array */
1015
    if ( IsTypeArray( CoffType ) == True ) {
1016
        IsArray = True;
1017
        pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 );
1018
    } else {
1019
        IsArray = False;
1020
        pEntry = (struct syment *)AllocateListObject( &ci->ListOfGlobals, sizeof(struct syment) );
1021
    }
1022
    if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) {
1023
        fprintf(stderr,"\nOut of memory adding local %s to string table", pName );
1024
    }
1025
    /* set value field to be address of label in bytes */
1026
    /* add underscore to lookup label */
1027
    if ( (p = calloc( 1, n + 2)) == 0 ) {
1028
        fprintf(stderr,"\nOut of memory adding global %s", pName );
1029
        return(False);
1030
    }
1031
    *p = '_';
1032
    strcpy( p + 1, pName );
1033
    if ( !get_symbol(pi, p, &Address) ) {
1034
        fprintf(stderr, "\nUnable to locate global %s", p );
1035
        free( p );
1036
        return( False );
1037
    }
1038
    free( p );
1039
    pEntry->n_value = Address;  /* already in bytes */
1040
    if ( ci->GlobalStartAddress == -1 ) {
1041
        ci->GlobalStartAddress = Address;
1042
    }
1043
    if ( Address < ci->GlobalStartAddress )
1044
        ci->GlobalStartAddress = Address;
1045
    if ( Address > ci->GlobalEndAddress )
1046
        ci->GlobalEndAddress = Address;
1047
 
1048
    pEntry->n_scnum = 2;    /* .bss */
1049
    pEntry->n_type = CoffType;
1050
    pEntry->n_sclass = C_STAT;
1051
    if ( IsArray == False )
1052
        pEntry->n_numaux = 0;
1053
    else {
1054
        pEntry->n_numaux = 1;
1055
        pEntry++;
1056
        AddArrayAuxInfo( (union auxent *)pEntry, (unsigned short)SymbolIndex, pMap );
1057
    }
1058
    return( True );
1059
}
1060
 
1061
/****************************************************************************************/
1062
int stab_add_local(  struct prog_info *pi, char *pName, char *pType, char *pOffset  ){
1063
 
1064
    int n, Offset, IsArray;
1065
    unsigned short CoffType, Type, SymbolIndex;
1066
    struct syment *pEntry;
1067
    STABCOFFMAP *pMap;
1068
 
1069
    n = strlen( pName );    /* see if it's 8 bytes or less */
1070
    Type = atoi(pType);     /* predefined variable type */
1071
    Offset = atoi(pOffset); /* offset in stack frame */
1072
    if ( (CoffType = GetCoffType( Type )) == 0 ) {
1073
        fprintf(stderr, "\nUnrecognized type found for local %s = %d", pName, Type );
1074
        return(False);
1075
    }
1076
    pMap = (STABCOFFMAP *)GetCurrentListObject( &ci->ListOfTypes );
1077
    SymbolIndex = ci->ListOfSymbols.TotalItems;
1078
    /* Allocate Symbol Table entry and fill it in, Auxiliary table if its an array */
1079
    if ( IsTypeArray( CoffType ) == True ) {
1080
        IsArray = True;
1081
        pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 );
1082
    } else {
1083
        IsArray = False;
1084
        pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) );
1085
    }
1086
    if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) {
1087
        fprintf(stderr,"\nOut of memory adding local %s to string table", pName );
1088
    }
1089
    pEntry->n_type = CoffType;
1090
    pEntry->n_sclass = C_AUTO;
1091
    pEntry->n_scnum = N_ABS;
1092
    pEntry->n_value = Offset + 1; /* Silly avr studio is set in its ways */
1093
    if ( IsArray == False )
1094
        pEntry->n_numaux = 0;
1095
    else {
1096
        pEntry->n_numaux = 1;
1097
        pEntry++;
1098
        AddArrayAuxInfo( (union auxent *)pEntry, SymbolIndex, pMap );
1099
    }
1100
    return( True );
1101
}
1102
 
1103
/****************************************************************************************/
1104
int stab_add_parameter_symbol( struct prog_info *pi, char *pName, char *pType, char *pOffset  ){
1105
 
1106
    int n, Offset;
1107
    unsigned short CoffType, Type;
1108
    struct syment *pEntry;
1109
 
1110
    n = strlen( pName );    /* see if it's 8 bytes or less */
1111
    Type = atoi(pType);     /* predefined variable type */
1112
    Offset = atoi(pOffset); /* offset in stack frame */
1113
    if ( (CoffType = GetCoffType( Type )) == 0 ) {
1114
        fprintf(stderr, "\nUnrecognized type found for %s = %d", pName, Type );
1115
        return(False);
1116
    }
1117
    /* Allocate Symbol Table entry and fill it in */
1118
    pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) );
1119
    if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) {
1120
        fprintf(stderr,"\nOut of memory adding local %s to string table", pName );
1121
    }
1122
    pEntry->n_type = CoffType;
1123
    pEntry->n_sclass = C_ARG;
1124
    pEntry->n_scnum = N_ABS;
1125
    pEntry->n_value = Offset;
1126
    pEntry->n_numaux = 0;
1127
    return( True );
1128
}
1129
/****************************************************************************************/
1130
int stab_add_static_symbol(  struct prog_info *pi, char *pName, char *pType, char *pLabel  ){
1131
 
1132
    int n, Address;
1133
    unsigned short CoffType, Type;
1134
    struct syment *pEntry;
1135
 
1136
    n = strlen( pName );    /* see if it's 8 bytes or less */
1137
    Type = atoi(pType + 1);     /* skip past S, predefined variable type */
1138
    if ( (CoffType = GetCoffType( Type )) == 0 ) {
1139
        fprintf(stderr, "\nUnrecognized type found for %s = %d", pName, Type );
1140
        return(False);
1141
    }
1142
    /* Allocate Symbol Table entry and fill it in */
1143
    pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) );
1144
    if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) {
1145
        fprintf(stderr,"\nOut of memory adding local %s to string table", pName );
1146
    }
1147
    pEntry->n_type = CoffType;
1148
    pEntry->n_sclass = C_STAT;
1149
    pEntry->n_scnum = N_ABS;
1150
    if ( !get_symbol(pi, pLabel, &Address) ) {
1151
        fprintf(stderr, "\nUnable to locate label %s", pLabel );
1152
        return( False );
1153
    }
1154
    pEntry->n_value = Address * 2;  /* find address of variable in bytes */
1155
    pEntry->n_numaux = 0;
1156
    return( True );
1157
}
1158
/****************************************************************************************/
1159
 
1160
int stab_add_local_register(  struct prog_info *pi, char *pName, char *pType, char *pRegister  ){
1161
 
1162
    int n, Register, Size;
1163
    unsigned short CoffType, Type;
1164
    struct syment *pEntry;
1165
 
1166
    n = strlen( pName );    /* see if it's 8 bytes or less */
1167
    Type = (unsigned short)atoi(pType + 1);     /* skip past P, predefined variable type */
1168
    Register = atoi(pRegister); /* offset in stack frame */
1169
    if ( (CoffType = GetCoffType( Type )) == 0 ) {
1170
        fprintf(stderr, "\nUnrecognized type found for %s = %d", pName, Type );
1171
        return(False);
1172
    }
1173
    Size = GetCoffTypeSize( Type ); /* Silly requirement for avr studio */
1174
    /* Allocate Symbol Table entry and fill it in */
1175
    pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) );
1176
    if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) {
1177
        fprintf(stderr,"\nOut of memory adding local %s to string table", pName );
1178
        return(False);
1179
    }
1180
    pEntry->n_type = CoffType;
1181
    //	if( (*pType == 'r') || (*pType == 'R') )
1182
    //		pEntry->n_sclass = C_REG;
1183
    //	else if( (*pType == 'p') || (*pType == 'P') )
1184
    pEntry->n_sclass = C_REGPARM;   /* Silly avr studio only accepts this for registers */
1185
    //	else{
1186
    //	    fprintf(stderr,"\nUnknown register type -> %s", pType );
1187
    //		return(False);
1188
    //	}
1189
    pEntry->n_scnum = N_ABS;
1190
    pEntry->n_numaux = 0;
1191
    if ( Size == 1 )
1192
        pEntry->n_value = 0xffffff00 | Register; /* Silly requirement for avr studio */
1193
    else if ( Size == 2 )
1194
        pEntry->n_value = 0xffff0000 | ((Register + 1) << 8) | Register; /* Silly requirement for avr studio */
1195
    else if ( Size == 4 )
1196
        pEntry->n_value = ((Register + 3) << 24) | ((Register + 3) << 16) | ((Register + 1) << 8) | Register; /* Silly requirement for avr studio */
1197
    else {
1198
        fprintf(stderr,"\nUnknown register size (%d) and coff type (%d)", Size, CoffType );
1199
        return(False);
1200
    }
1201
    return( True );
1202
}
1203
 
1204
/****************************************************************************************/
1205
 
1206
int stab_add_local_type( char *pName, char *pType ){
1207
 
1208
    char *p;
1209
    unsigned short StabType;
1210
 
1211
    /* .stabs "int:t1=r1;-128;127;",128,0,0,0 */
1212
    /* .stabs ":t20=ar1;0;1;21=ar1;0;1;2",128,0,0,0 */
1213
    /* pType-----^                                   */
1214
    /* Stab Type - convert to Coff type at end (after inline assignments */
1215
    if ( GetStabType( pType, &StabType, &p ) != True ) {
1216
        fprintf(stderr,"\nInvalid tag type found in structure item -> %s", p);
1217
        return(False);
1218
    }
1219
 
1220
    return(True);
1221
}
1222
 
1223
/****************************************************************************************/
1224
 
1225
int GetStructUnionTagItem( char *p, char **pEnd, char **pName, unsigned short *pType, unsigned short *pBitOffset, unsigned short *pBitSize) {
1226
 
1227
    unsigned short StabType;
1228
    /* Structure or Union Tag Item consists of -> name:type,bitoffset,bitsize; */
1229
 
1230
    /* name */
1231
    *pName = p;
1232
    while ( *p && (*p != ':') ) p++; // locate colon
1233
    if ( *p != ':' ) {
1234
      fprintf(stderr,"\nNo colon found in structure item -> %s", *pName);
1235
      return(False);
1236
    }
1237
    *p++ = 0; // Asciiz
1238
 
1239
    /* Stab Type - convert to Coff type at end (after inline assignments */
1240
    if ( GetStabType( p, &StabType, &p ) != True ) {
1241
        fprintf(stderr,"\nInvalid tag type found in structure item -> %s", p);
1242
        return(False);
1243
    }
1244
 
1245
    /* BitSize */
1246
    if ( *p != ',' ) {
1247
        fprintf(stderr,"\nNo Bit size found in structure item -> %s", p );
1248
        return(False);
1249
    }
1250
    *pBitOffset = (unsigned short)atoi( ++p );
1251
    while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits
1252
 
1253
    /* BitOffset */
1254
    if ( *p != ',' ) {
1255
        fprintf(stderr,"\nNo Bit offset found in structure item -> %s", p );
1256
        return(False);
1257
    }
1258
    *pBitSize =  (unsigned short)atoi( ++p );
1259
    while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits
1260
 
1261
    /* Now convert stab type to COFF */
1262
    if ( (*pType = GetCoffType( (unsigned short)StabType)) == 0 ) {
1263
        fprintf(stderr,"\nNo COFF type found for stab type %d", StabType );
1264
        return(   False);
1265
    }
1266
    if ( *++p == ';' ) /* Now eat last semicolon(s) */
1267
        p++;
1268
    *pEnd = p;
1269
 
1270
    return( True );
1271
}
1272
/****************************************************************************************/
1273
 
1274
int GetEnumTagItem( char *p, char **pEnd, char **pEnumName, int *pEnumValue ) {
1275
 
1276
    /* Enum Tag Item consists of -> member1:value,member2:value2,; */
1277
    *pEnumName = p;
1278
    while ( *p && (*p != ':') ) p++; // locate colon
1279
    if ( *p != ':' ) {
1280
      fprintf(stderr,"\nNo colon found in enum item -> %s", *pEnumName);
1281
      return(False);
1282
    }
1283
    *p++ = 0; // Asciiz
1284
    *pEnumValue = atoi(p);
1285
 
1286
    while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits
1287
    if ( *p != ',' ) {
1288
        fprintf(stderr,"\nNo comma found after enum value -> %s", p );
1289
        return(False);
1290
    }
1291
    if ( *++p ==';' )
1292
        p++; /* eat last semicolon */
1293
    *pEnd = p;
1294
    return( True );
1295
}
1296
 
1297
/****************************************************************************************/
1298
int GetArrayType( char *p, char **pEnd, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels ){
1299
 
1300
    int MinIndex, MaxIndex, Result, Size, i;
1301
    char *pMinIndex, *pMaxIndex, *pType;
1302
    unsigned short Type;
1303
 
1304
    Result = True;
1305
 
1306
    pMinIndex = pMaxIndex = pType = 0;
1307
    while ( *p && (*p != ';') ) p++;   /* find min index */
1308
    pMinIndex = ++p;
1309
    while ( *p && (*p != ';') ) p++;   /* find max index */
1310
    pMaxIndex = ++p;
1311
    while ( *p && (*p != ';') ) p++;   /* find type index */
1312
    pType = ++p;
1313
 
1314
    /* bump the pointers to the digits */
1315
    if ( !isdigit(*pMinIndex) )
1316
        Result = False;
1317
    if ( !isdigit(*pMaxIndex) )
1318
        Result = False;
1319
    if ( !isdigit(*pType) )
1320
        Result = False;
1321
    /* Is syntax ok ? */
1322
    if ( Result != True ) {
1323
        fprintf(stderr,"\nSyntax error on array parameters %s%s%s", pMinIndex, pMaxIndex, pType );
1324
        return(False);
1325
    }
1326
    MinIndex = atoi(pMinIndex);
1327
    MaxIndex = atoi(pMaxIndex);
1328
 
1329
    if ( GetStabType( p, &Type, &p ) != True )
1330
        return(False);
1331
 
1332
    if ( !SetupDefinedType( Type, pMap, DerivedBits, ExtraLevels ) )
1333
        return( False );
1334
 
1335
    /* Now update the size based on the indicies */
1336
    Size = (MaxIndex - MinIndex) + 1;
1337
    pMap->ByteSize *= Size;
1338
    pMap->Line = ci->CurrentSourceLine;
1339
    /* add the dimension information */
1340
    for ( i = 5; i >= 0; i-- ) {
1341
        if ( pMap->Dimensions[i] != 0 ) {
1342
            i++;
1343
            pMap->Dimensions[i] = Size;
1344
            break;
1345
        }
1346
    }
1347
 
1348
    *pEnd = p;
1349
    return(True);
1350
}
1351
 
1352
/****************************************************************************************/
1353
int GetStabType( char *p, unsigned short *pType, char **pEnd ) {
1354
 
1355
    STABCOFFMAP *pMap;
1356
    int extra, ok;
1357
    unsigned short derivedbits[6];
1358
    unsigned short LStabType, RStabType;
1359
    char *pHigh, *pLow;
1360
 
1361
 
1362
    LStabType = atoi( p );
1363
    while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits
1364
 
1365
    *pType = LStabType;
1366
 
1367
    if ( GetCoffType( LStabType ) != 0 ) {
1368
        *pEnd = p;
1369
        return(True);
1370
    }
1371
    if ( *p != '=' ) {
1372
        fprintf(stderr, "\nSyntax error in type assignment -> %s", p );
1373
        return(False);
1374
    }
1375
    p++;
1376
 
1377
    /* Allocate space for new internal type */
1378
    if ( !(pMap = (STABCOFFMAP *)AllocateListObject(&ci->ListOfTypes, sizeof(STABCOFFMAP)) ) ) {
1379
        fprintf(stderr, "\nOut of memory allocating type info!");
1380
        return(False);
1381
    }
1382
    pMap->StabType = LStabType;
1383
 
1384
    /* process items to right of equals */
1385
    for ( extra = 0; extra < 6; extra++ ) {
1386
 
1387
        if ( isdigit( *p ) ) {
1388
            /* Finally found base type, try to terminate loop */
1389
            GetStabType( p, &RStabType, &p );
1390
            //			RStabType = atoi( p );
1391
            while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits
1392
            if ( SetupDefinedType( RStabType, pMap, &derivedbits[0], extra ) != True )
1393
                return( False );
1394
            break;
1395
        } else if ( *p == 'a' ) {
1396
            derivedbits[extra] = DT_ARY;
1397
            p++;
1398
            /* Calculate size */
1399
            /* Since type assignment will be made we need to set extra bits here */
1400
            extra++;
1401
            /* =ar1;MinIndex;MaxIndex;BaseType */
1402
            if ( GetArrayType( p, &p, pMap, &derivedbits[0], extra  ) != True )
1403
                return(False);
1404
            break;
1405
 
1406
        } else if ( *p == 'f' ) {
1407
            derivedbits[extra] = DT_FCN;
1408
            p++;
1409
        } else if ( *p == '*' ) {
1410
            derivedbits[extra] = DT_PTR;
1411
            p++;
1412
        } else if ( *p == 'r' ) {
1413
            //			if( LStabType < 15 )
1414
            //				ok = GetInternalType( pString, pMap ); /* internal types not yet installed */
1415
            //			else
1416
            while ( *p && (*p != ';' ) ) p++;
1417
            pLow = p++;
1418
            while ( *p && (*p != ';' ) ) p++;
1419
            pHigh = p++;
1420
            ok = GetSubRangeType( LStabType, pMap, pLow, pHigh );
1421
            if ( ok != True )
1422
                return(False);
1423
            while ( *p && (*p != ';' ) ) p++; /* find end of range */
1424
            p++;
1425
            break;
1426
        } else {
1427
            fprintf(stderr, "\nUnrecognized Type modifier %c!", *p );
1428
            return(False);
1429
        }
1430
    }
1431
    *pEnd = p; /* Update return pointer */
1432
 
1433
    return(True);
1434
}
1435
 
1436
 
1437
/****************************************************************************************/
1438
int stab_add_tag_type( char *pName, char *pString ){
1439
 
1440
    int SymbolIndex, StabType, TotalSize, n, EnumValue;
1441
    unsigned short TagType, ItemType, BitOffset, BitSize;
1442
    char *p;
1443
    struct syment* pEntry;
1444
    union auxent *pAux;
1445
    STABCOFFMAP *pMap;
1446
 
1447
    /* We arrived here due to :T defining either a structure, union or enumeration */
1448
    /* store the basic type as for internals and emit coff structures for debugging */
1449
    /* .stabs "stag:T17=s2i:1,0,8;c:2,8,8;;",128,0,0,0 */
1450
    /* .stabs "2:T18=u2a:2,0,8;b:1,0,8;c:6,0,16;;",128,0,0,0 */
1451
    /* .stabs "1:T19=eenum1:1,enum2:2,enum3:3,;",128,0,0,0 */
1452
    /* we don't care about the name */
1453
 
1454
 
1455
    /* check for bogus errors */
1456
    if ( !pName || !pString ) {
1457
        fprintf(stderr,"\nInvalid .stabs type format - no information!");
1458
        return(False);
1459
    }
1460
 
1461
    p = pString;
1462
    /* Stab Type - convert to Coff type at end (after inline assignments */
1463
    if ( (StabType = (unsigned short)atoi(p)) == 0 ) {
1464
        fprintf(stderr,"\nInvalid .stabs type format - no information! - > %s", p );
1465
        return(False);
1466
    }
1467
    while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits
1468
    if ( *p != '=' ) {
1469
        fprintf(stderr,"\nInvalid .stabs type format - no equals - > %s", p );
1470
        return(False);
1471
    }
1472
    SymbolIndex = ci->ListOfSymbols.TotalItems;
1473
    if (  ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ) ) == 0 ) {
1474
        fprintf(stderr, "\nOut of memory allocating symbol tag entries");
1475
        return(False);
1476
    }
1477
    /* Prepare Tag Header */
1478
    if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) {
1479
        fprintf(stderr,"\nOut of memory adding local %s to string table", pString );
1480
        return(False);
1481
    }
1482
    if ( !(pMap = (STABCOFFMAP *)AllocateListObject(&ci->ListOfTypes, sizeof(STABCOFFMAP)) ) ) {
1483
        fprintf(stderr, "\nOut of memory allocating type info!");
1484
        return(False);
1485
    }
1486
    pMap->StabType = StabType;
1487
    pEntry->n_value = 0;
1488
    pEntry->n_scnum = N_DEBUG;
1489
    pEntry->n_numaux = 1;
1490
    if ( *++p == 's' ) {
1491
        TagType = pEntry->n_type = pMap->CoffType = T_STRUCT;
1492
        pEntry->n_sclass = C_STRTAG;
1493
        TotalSize = (unsigned short)atoi(++p);
1494
    } else if ( *p == 'u' ) {
1495
        TagType = pEntry->n_type = pMap->CoffType = T_UNION;
1496
        pEntry->n_sclass = C_UNTAG;
1497
        TotalSize = (unsigned short)atoi(++p);
1498
    } else if ( *p == 'e' ) {
1499
        TagType = pEntry->n_type = pMap->CoffType = T_ENUM;
1500
        pEntry->n_sclass = C_ENTAG;
1501
        TotalSize = FundamentalTypes[T_INT].Size; /* use size of int for enums */
1502
    } else {
1503
        fprintf(stderr,"\nUnknown tag type -> %s", p );
1504
        return(False);
1505
    }
1506
    while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits
1507
    pEntry++;   /* point to aux entry */
1508
    pAux = (union auxent *)pEntry;
1509
    pAux->x_sym.x_tagndx = SymbolIndex;
1510
    pAux->x_sym.x_misc.x_lnsz.x_size = TotalSize;
1511
 
1512
    /* update our local knowledge of tag type */
1513
    pMap->CoffType = TagType;
1514
    pMap->ByteSize = TotalSize;
1515
    pMap->Line = ci->CurrentSourceLine;
1516
 
1517
    /* Process the items until the end of the line */
1518
    while ( *pName ) {
1519
 
1520
        if (  ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ) ) == 0 ) {
1521
            fprintf(stderr, "\nOut of memory allocating symbol tag member entries");
1522
            return(False);
1523
        }
1524
 
1525
        if ( TagType == T_STRUCT ) {
1526
            if ( GetStructUnionTagItem( p, &p, &pName, &ItemType, &BitOffset, &BitSize) != True ) {
1527
                return(False);
1528
            }
1529
            pEntry->n_value = BitOffset/8;
1530
            pEntry->n_type = ItemType;
1531
            pEntry->n_sclass = C_MOS;
1532
        } else if ( TagType == T_UNION ) {
1533
            if ( GetStructUnionTagItem(  p, &p, &pName, &ItemType, &BitOffset, &BitSize) != True ) {
1534
                return(False);
1535
            }
1536
            pEntry->n_value = BitOffset/8;
1537
            pEntry->n_type = ItemType;
1538
            pEntry->n_sclass = C_MOU;
1539
        } else { /* T_ENUM */
1540
            if ( GetEnumTagItem( p, &p, &pName, &EnumValue ) != True ) {
1541
                return(False);
1542
            }
1543
            pEntry->n_value = EnumValue;
1544
            pEntry->n_type = TotalSize;
1545
            pEntry->n_sclass = C_MOE;
1546
        }
1547
 
1548
        /* Prepare Common Tag Header items */
1549
        if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) {
1550
            fprintf(stderr,"\nOut of memory adding local %s to string table", pString );
1551
            return(False);
1552
        }
1553
        pEntry->n_scnum = N_ABS;
1554
        pEntry->n_numaux = 1;
1555
        pEntry++;   /* point to aux entry */
1556
        pAux = (union auxent *)pEntry;
1557
        pAux->x_sym.x_tagndx = SymbolIndex;
1558
        pAux->x_sym.x_misc.x_lnsz.x_size = TotalSize;
1559
        pName = p;
1560
    }
1561
 
1562
    /* End of Structures/Unions/Enumberations */
1563
    if (  ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ) ) == 0 ) {
1564
        fprintf(stderr, "\nOut of memory allocating special headers for structure!");
1565
        return(False);
1566
    }
1567
    strcpy( pEntry->n_name, ".eos" );
1568
    pEntry->n_value = TotalSize;
1569
    pEntry->n_scnum = N_ABS;
1570
    pEntry->n_type = 0;
1571
    pEntry->n_sclass = C_EOS;
1572
    pEntry->n_numaux = 1;
1573
    pEntry++;   /* point to aux entry */
1574
    pAux = (union auxent *)pEntry;
1575
    pAux->x_sym.x_tagndx = SymbolIndex; /* point to the .bf entry index */
1576
    pAux->x_sym.x_misc.x_lnsz.x_size = TotalSize;
1577
 
1578
    return(True);
1579
}
1580
 
1581
/****************************************************************************************/
1582
int SetupDefinedType( unsigned short Type, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels ){
1583
 
1584
    int i, Dlimit, Dstart;
1585
    unsigned short StabType;
1586
 
1587
    StabType = pMap->StabType; /* save the new type we found earlier */
1588
    if ( CopyStabCoffMap( Type, pMap ) != True ) {
1589
        fprintf(stderr, "\nCould not find defined type %d", Type );
1590
        return(False);
1591
    }
1592
    pMap->StabType = StabType; /* save the new type we found earlier */
1593
 
1594
    /* Determine existing derived types for base class */
1595
    for ( i = 0; i < 6; i++ ) {
1596
        if ( (pMap->CoffType & ( 3 << (4 + i + i))) == 0 )
1597
            break;
1598
    }
1599
    Dstart = i;
1600
    Dlimit = i + ExtraLevels;
1601
    if ( (Dlimit) >= 6 ) {
1602
        fprintf(stderr, "\nStab Type %d has too many derived (%d) types!", pMap->StabType, Dlimit );
1603
        return(False);
1604
    }
1605
    /* Add the new derived levels */
1606
    for ( ; i < Dlimit; i++ ) {
1607
        pMap->CoffType |= ( ( DerivedBits[i - Dstart] & 3) << (4 + i + i) ); /* add in the derived bits */
1608
    }
1609
    return(True);
1610
}
1611
 
1612
/****************************************************************************************/
1613
int GetArrayDefinitions( STABCOFFMAP *pMap , char *pMinIndex, char *pMaxIndex, char *pType, unsigned short *DerivedBits, int ExtraLevels ){
1614
 
1615
    int MinIndex, MaxIndex, Result, Size, i;
1616
    unsigned short Type;
1617
 
1618
    Result = True;
1619
    if ( (*pMinIndex != ';') || (*pMaxIndex != ';') || (*pType != ';') )
1620
        Result = False;
1621
    /* bump the pointers to the digits */
1622
    pMinIndex++;
1623
    if ( !isdigit(*pMinIndex) )
1624
        Result = False;
1625
    pMaxIndex++;
1626
    if ( !isdigit(*pMaxIndex) )
1627
        Result = False;
1628
    pType++;
1629
    if ( !isdigit(*pType) )
1630
        Result = False;
1631
    /* Is syntax ok ? */
1632
    if ( Result != True ) {
1633
        fprintf(stderr,"\nSyntax error on array parameters %s%s%s", pMinIndex, pMaxIndex, pType );
1634
        return(False);
1635
    }
1636
    MinIndex = atoi(pMinIndex);
1637
    MaxIndex = atoi(pMaxIndex);
1638
    Type = (unsigned short)atoi(pType);
1639
    if (    SetupDefinedType(    Type,    pMap,    DerivedBits,    ExtraLevels    )    !=    True    )
1640
        return( False );
1641
    /* Now update the size based on the indicies */
1642
    Size = (MaxIndex - MinIndex) + 1;
1643
    pMap->ByteSize *= Size;
1644
    pMap->Line = ci->CurrentSourceLine;
1645
    /* add the dimension information */
1646
    for ( i = 5; i >= 0; i-- ) {
1647
        if ( pMap->Dimensions[i] != 0 ) {
1648
            i++;
1649
            pMap->Dimensions[i] = Size;
1650
            break;
1651
        }
1652
    }
1653
    return(True);
1654
}
1655
 
1656
/****************************************************************************************/
1657
 
1658
int GetInternalType( char *pName, STABCOFFMAP *pMap ){
1659
 
1660
    int n, found, i;
1661
 
1662
    if ( !pName ) {
1663
        return(False);
1664
    }
1665
 
1666
    found = False;
1667
    n = strlen(pName);
1668
    /* Find out if it is a local type */
1669
    for (i = 0; FundamentalTypes[i].pString != 0; i++) {
1670
        if ( !strncmp(pName, FundamentalTypes[i].pString, n) ) {
1671
            /* found an internal type */
1672
            pMap->CoffType = FundamentalTypes[i].Type;
1673
            pMap->ByteSize = FundamentalTypes[i].Size;
1674
            found = True;
1675
        }
1676
    }
1677
    return(found);
1678
}
1679
 
1680
/****************************************************************************************/
1681
int GetSubRangeType( unsigned short Type, STABCOFFMAP *pMap , char *pLow, char *pHigh ){
1682
 
1683
    int Result, i;
1684
    long High, Low;
1685
    unsigned long Test;
1686
 
1687
    Result = True;
1688
    if ( (*pLow != ';') || (*pHigh != ';') || (Type <= 0) )
1689
        Result = False;
1690
 
1691
    /* Is syntax ok ? */
1692
    if ( Result != True ) {
1693
        fprintf(stderr,"\nSyntax error on sub range parameters!" );
1694
        return(False);
1695
    }
1696
    Low = atol(++pLow);
1697
    High = atol(++pHigh);
1698
 
1699
    /* Special handling of type void */
1700
    if ( (Low == 0) && (High == 0) ) {
1701
        /* Declare type void */
1702
        pMap->ByteSize =0;
1703
        pMap->CoffType = T_VOID;
1704
        pMap->Line = ci->CurrentSourceLine;
1705
        return(True);
1706
    }
1707
 
1708
    if ( (pMap->CoffType = GetCoffType( Type )) != 0 ) {
1709
        pMap->ByteSize = GetCoffTypeSize( Type );
1710
    } else {
1711
        /* Try to base everything off integer */
1712
        pMap->ByteSize = FundamentalTypes[T_INT].Size;
1713
    }
1714
 
1715
    /* Now calculate the byte size */
1716
    if ( High == 0 ) {
1717
        pMap->ByteSize = (unsigned short)Low; /* floating point */
1718
    } else {
1719
        if ( Low == 0 ) {
1720
            /* Unsigned */
1721
            Test = (unsigned long)High;
1722
        } else if ( Low < 0 ) {
1723
            /* signed */
1724
            Test = (unsigned long)High << 1;
1725
        } else {
1726
            if ( Low <= High )
1727
                Test = (unsigned long)High;
1728
            else
1729
                Test = (unsigned long)Low;
1730
        }
1731
        if ( pMap->ByteSize == 0 ) {
1732
            fprintf(stderr,"\nType Range Error 1, need previous type %d size!", pMap->CoffType );
1733
            return(False);
1734
        }
1735
        for ( i = 0; i < sizeof(unsigned long); i++ ) {
1736
            if ( !(Test & (0xff << (i * 8))) )
1737
                break;
1738
        }
1739
        pMap->ByteSize = i;
1740
    }
1741
    /* Now determine the best fit based on byte size, compare against IAR Compiler */
1742
    if ( pMap->ByteSize == 1 ) {
1743
        if ( Low < 0 )
1744
            pMap->CoffType = T_CHAR;
1745
        else
1746
            pMap->CoffType = T_UCHAR;
1747
    } else if ( pMap->ByteSize == 2 ) {
1748
        if ( Low < 0 )
1749
            pMap->CoffType = T_INT;
1750
        else
1751
            pMap->CoffType = T_UINT;
1752
    } else if ( pMap->ByteSize == 4 ) {
1753
        if ( Low == 0 )
1754
            pMap->CoffType = T_FLOAT;
1755
        if ( Low < 0 )
1756
            pMap->CoffType = T_LONG;
1757
        else
1758
            pMap->CoffType = T_ULONG;
1759
    } else {
1760
        fprintf(stderr,"\nGetSubRangeType failure - byte size %d", pMap->ByteSize );
1761
        return(False);
1762
    }
1763
    return(True);
1764
}
1765
 
1766
/****************************************************************************************/
1767
int CopyStabCoffMap( unsigned short StabType, STABCOFFMAP *pMap ){
1768
 
1769
    STABCOFFMAP *p;
1770
 
1771
    for ( p = FindFirstListObject( &ci->ListOfTypes ); p != 0; p = FindNextListObject( &ci->ListOfTypes) ) {
1772
        if ( p->StabType == StabType ) {
1773
            memcpy( pMap, p, sizeof(STABCOFFMAP) );
1774
            return(True);
1775
        }
1776
    }
1777
    return( False ); /* Nothing found */
1778
}
1779
 
1780
/****************************************************************************************/
1781
unsigned short GetCoffType( unsigned short StabType ){
1782
 
1783
    STABCOFFMAP *p;
1784
 
1785
    for ( p = FindFirstListObject( &ci->ListOfTypes ); p != 0; p = FindNextListObject( &ci->ListOfTypes) ) {
1786
        if ( p->StabType == StabType )
1787
            return( p->CoffType );
1788
    }
1789
    return( 0 ); /* Nothing found */
1790
}
1791
 
1792
/****************************************************************************************/
1793
unsigned short GetCoffTypeSize( unsigned short StabType ){
1794
 
1795
    STABCOFFMAP *p;
1796
 
1797
    for ( p = FindFirstListObject( &ci->ListOfTypes ); p != 0; p = FindNextListObject( &ci->ListOfTypes) ) {
1798
        if ( p->StabType == StabType )
1799
            return( p->ByteSize );
1800
    }
1801
    return( 0 ); /* Nothing found */
1802
}
1803
 
1804
 
1805
/****************************************************************************************/
1806
int GetDigitLength( char *p ){
1807
 
1808
    int i;
1809
 
1810
    if ( p == 0 )
1811
        return(0);
1812
 
1813
    for ( i = 0; (*p != 0) && ( *p >= '0' ) && ( *p <= '9' ); i++ );
1814
 
1815
    return( i );
1816
 
1817
}
1818
 
1819
/****************************************************************************************/
1820
int GetStringDelimiters( char *pString, char **pTokens, int MaxTokens ){
1821
 
1822
    int i;
1823
    char *p;
1824
 
1825
    p = pString;
1826
 
1827
    if ( !p )
1828
        return( 0 );
1829
 
1830
    for ( i = 0; i < MaxTokens; i++ ) {
1831
        while ( True ) {
1832
            if ( (*p == ':') || (*p == ';') || (*p == '=') || (*p == ',') || (*p == '"') || (*p == 0 ) ) {
1833
                *(pTokens + i) = p; /* Remember this location */
1834
                p++;
1835
                if ( *p == 0 )
1836
                    return( i );
1837
                break;
1838
            }
1839
            p++;
1840
        }
1841
    }
1842
    return( i );
1843
}
1844
 
1845
/****************************************************************************************/
1846
int IsTypeArray( unsigned short CoffType ){
1847
 
1848
    int Result;
1849
 
1850
    Result = False;
1851
 
1852
    if ( (CoffType & (DT_ARY << 4 )) == (DT_ARY << 4 ) )
1853
        Result = True;
1854
    if ( (CoffType & (DT_ARY << 6 )) == (DT_ARY << 6 ) )
1855
        Result = True;
1856
    if ( (CoffType & (DT_ARY << 8 )) == (DT_ARY << 8 ) )
1857
        Result = True;
1858
    if ( (CoffType & (DT_ARY << 10 )) == (DT_ARY << 10 ) )
1859
        Result = True;
1860
    if ( (CoffType & (DT_ARY << 12 )) == (DT_ARY << 12 ) )
1861
        Result = True;
1862
    if ( (CoffType & (DT_ARY << 14 )) == (DT_ARY << 14 ) )
1863
        Result = True;
1864
 
1865
    return(Result);
1866
}
1867
 
1868
/****************************************************************************************/
1869
void AddArrayAuxInfo( union auxent *pAux, unsigned short SymbolIndex, STABCOFFMAP *pMap ){
1870
 
1871
    int i;
1872
 
1873
    pAux->x_sym.x_tagndx = SymbolIndex; /* point to the .bf entry index */
1874
    pAux->x_sym.x_misc.x_lnsz.x_lnno =  pMap->Line;
1875
    pAux->x_sym.x_misc.x_lnsz.x_size = pMap->ByteSize;
1876
    for ( i = 0; i < 4; i++ )
1877
        pAux->x_sym.x_fcnary.x_ary.x_dimen[i] = pMap->Dimensions[i];
1878
}
1879
 
1880
/****************************************************************************************/
1881
int AddNameToEntry( char *pName, struct syment *pEntry ) {
1882
 
1883
    int n;
1884
    char *p;
1885
 
1886
    n = strlen( pName );    /* see if it's 8 bytes or less */
1887
    if ( n <= 8 ) {
1888
        strncpy( pEntry->n_name, pName, 8 );
1889
    } else {
1890
        /* point to current offset in string table */
1891
        pEntry->n_offset = ci->ListOfStrings.TotalBytes;
1892
        /* Allocate string table entry */
1893
        if ( (p = (char *)AllocateListObject( &ci->ListOfStrings, n + 1 )) == 0 ) {
1894
            return(0);
1895
        }
1896
        strcpy( p, pName );
1897
    }
1898
    return(n); /* return size of string */
1899
}
1900
 
1901
/****************************************************************************************/
1902
 
1903
char *SkipPastDigits( char *p ){
1904
 
1905
    if ( !p )
1906
        return(p);
1907
/*	if ( *p == 0 );  */  /* JEG 5-01-03 */
1908
	if ( *p == 0 )
1909
    return(p);   /* This line s/b indented JEG */
1910
    for ( p--; (*p >= '0') && (*p <= '9') && (*p != 0); p-- );
1911
    return(p);
1912
}
1913
 
1914
/****************************************************************************************/
1915
 
1916
/****************************************************************************************/
1917
/****************************************************************************************/
1918
/* List management routines */
1919
/****************************************************************************************/
1920
/****************************************************************************************/
1921
 
1922
/****************************************************************************************/
1923
 
1924
/****************************************************************************************/
1925
void InitializeList( LISTNODEHEAD *pHead ){
1926
 
1927
    pHead->Node.Next = &pHead->Node;
1928
    pHead->Node.Last = &pHead->Node;
1929
    pHead->TotalBytes = 0;
1930
    pHead->TotalItems = 0;
1931
    pHead->current = &pHead->Node;
1932
    return;
1933
}
1934
 
1935
/****************************************************************************************/
1936
 
1937
void *AllocateTwoListObjects( LISTNODEHEAD *pHead, int size ){
1938
 
1939
    void *p;
1940
 
1941
    if ( (p = AllocateListObject( pHead, size ) ) )
1942
        pHead->TotalItems++;   /* already incremented once in addtolist */
1943
    return( p );
1944
}
1945
 
1946
/****************************************************************************************/
1947
void *AllocateListObject( LISTNODEHEAD *pHead, int size ){
1948
 
1949
    void *pObject;
1950
 
1951
    LISTNODE *pNode;
1952
 
1953
    if ( (pObject = calloc( 1, size )) != 0 ) {
1954
        if ( !(pNode = AddListObject( pHead, pObject, size )) ) {
1955
            free( pObject );
1956
            pObject = 0;
1957
        }
1958
    }
1959
    return( pObject );
1960
}
1961
 
1962
/****************************************************************************************/
1963
LISTNODE  *AddListObject(LISTNODEHEAD *pHead, void *pObject, int size ){
1964
 
1965
    LISTNODE *pNode;
1966
 
1967
    if ( (pNode = calloc( 1, sizeof(LISTNODE) )) != 0 ) {
1968
        pNode->pObject = pObject;
1969
        pNode->Size = size;
1970
        pNode->FileNumber = ci->CurrentFileNumber;
1971
        AddNodeToList( pHead, pNode );
1972
    }
1973
    return( pNode );
1974
}
1975
 
1976
/****************************************************************************************/
1977
LISTNODE *AllocateListNode( void *pObject, int size ){
1978
 
1979
    LISTNODE *pNew;
1980
 
1981
    if ( (pNew = calloc( 1, sizeof( LISTNODE ) ) ) != 0 ) {
1982
        /* Then we initialize the node */
1983
        pNew->pObject = pObject;
1984
        pNew->Size = size;
1985
        pNew->FileNumber = ci->CurrentFileNumber;
1986
    }
1987
    return(pNew);
1988
}
1989
 
1990
/****************************************************************************************/
1991
void AddNodeToList( LISTNODEHEAD *pHead, LISTNODE *pNode ){
1992
 
1993
    LISTNODE *p;
1994
 
1995
    p = &pHead->Node;
1996
 
1997
    pNode->Next = p->Last->Next;
1998
    p->Last->Next = pNode;
1999
    pNode->Last = p->Last;
2000
    p->Last = pNode;
2001
 
2002
    /* and update current size of data contained in the list */
2003
    pHead->TotalBytes += pNode->Size;
2004
    pHead->TotalItems++;
2005
}
2006
 
2007
/****************************************************************************************/
2008
void RemoveNodeFromList( LISTNODEHEAD *pHead, LISTNODE *pNode ){
2009
 
2010
    pNode->Last->Next = pNode->Next;
2011
    pNode->Next->Last = pNode->Last;
2012
 
2013
    pHead->TotalBytes -= pNode->Size;
2014
    pHead->TotalItems--;
2015
}
2016
 
2017
 
2018
/****************************************************************************************/
2019
void *FindFirstListObject( LISTNODEHEAD *pHead ){
2020
 
2021
    if ( pHead->Node.Next == &pHead->Node )
2022
        return(0);  /* Nothing in list */
2023
 
2024
    pHead->current = pHead->Node.Next;
2025
    return( pHead->current->pObject );
2026
}
2027
/****************************************************************************************/
2028
void *FindNextListObject( LISTNODEHEAD *pHead ){
2029
 
2030
    if ( pHead->current->Next == &pHead->Node )
2031
        return( 0 );
2032
 
2033
    pHead->current = pHead->current->Next;
2034
 
2035
    return( pHead->current->pObject );
2036
}
2037
/****************************************************************************************/
2038
 
2039
LISTNODE *GetCurrentNode( LISTNODEHEAD *pHead ){
2040
 
2041
    return( pHead->current );
2042
}
2043
 
2044
/****************************************************************************************/
2045
void *GetCurrentListObject( LISTNODEHEAD *pHead ){
2046
 
2047
    return( pHead->current->pObject );
2048
}
2049
 
2050
 
2051
/****************************************************************************************/
2052
void *FindLastListObject( LISTNODEHEAD *pHead ){
2053
 
2054
    if ( pHead->Node.Last == &pHead->Node )
2055
        return(0);  /* Nothing in list */
2056
 
2057
    pHead->current = pHead->Node.Last;
2058
    return( pHead->current->pObject );
2059
}
2060
/****************************************************************************************/
2061
void *FindNextLastListObject( LISTNODEHEAD *pHead ){
2062
 
2063
    if ( pHead->current->Last == &pHead->Node )
2064
        return( 0 );
2065
 
2066
    pHead->current = pHead->current->Last;
2067
 
2068
    return( pHead->current->pObject );
2069
}
2070
 
2071
/****************************************************************************************/
2072
 
2073
void FreeList( LISTNODEHEAD *pHead ){
2074
 
2075
    LISTNODE *pNode;
2076
 
2077
    for ( pNode = pHead->Node.Last; pNode->Next != &pHead->Node; pNode = pHead->Node.Last ) {
2078
 
2079
        RemoveNodeFromList( pHead, pNode );
2080
        free( pNode->pObject );
2081
        free( pNode );
2082
    }
2083
    pHead->TotalBytes = 0;
2084
    pHead->TotalItems = 0;
2085
    pHead->current = &pHead->Node;
2086
}
2087
/****************************************************************************************/
2088