Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/* linux/diag_out.c */
32
 
33
/**********************************************************************
34
$Author: release $
35
$Date: 1998/03/27 09:47:50 $
36
$Revision: 1.2 $
37
$Log: diag_out.c,v $
38
 * Revision 1.2  1998/03/27  09:47:50  release
39
 * Changes for 4.1.2 release.
40
 *
41
 * Revision 1.1.1.1  1998/01/17  15:55:52  release
42
 * First version to be checked into rolling release.
43
 *
44
 * Revision 1.12  1997/04/02  10:33:21  pwe
45
 * diagnose pl_tests
46
 *
47
 * Revision 1.11  1997/03/24  12:43:26  pwe
48
 * outn int->long
49
 *
50
 * Revision 1.10  1996/10/29  14:55:32  pwe
51
 * correct linux/elf stabs for global variables
52
 *
53
 * Revision 1.9  1996/07/05  09:07:43  pwe
54
 * correct stabs enums
55
 *
56
 * Revision 1.8  1996/05/09  17:30:47  pwe
57
 * shift invalidate_dest, and stabs postlude
58
 *
59
 * Revision 1.7  1996/04/19  16:14:16  pwe
60
 * simplified use of global id = id, correcting linux call problem
61
 *
62
 * Revision 1.6  1996/03/13  13:43:26  pwe
63
 * diags for long long
64
 *
65
 * Revision 1.5  1996/02/08  13:45:29  pwe
66
 * Linux elf v aout option
67
 *
68
 * Revision 1.4  1995/12/20  11:13:54  pwe
69
 * stabs local variable scopes
70
 *
71
 * Revision 1.3  1995/11/30  10:19:43  pwe
72
 * diag struct struct
73
 *
74
 * Revision 1.2  1995/03/28  14:28:53  pwe
75
 * correct diagnose empty file
76
 *
77
 * Revision 1.1  1995/03/17  18:29:52  pwe
78
 * stabs diagnostics for solaris and linux
79
 *
80
**********************************************************************/
81
 
82
#include "config.h"
83
#include "common_types.h"
84
#include "basicread.h"
85
#include "out.h"
86
#include "machine.h"
87
#include "shapemacs.h"
88
#include "expmacs.h"
89
#include "tags.h"
90
#include "szs_als.h"
91
#include "diagglob.h"
92
#include "xalloc.h"
93
#include "exp.h"
94
#include "mark_scope.h"
95
#include "externs.h"
96
#ifdef NEWDIAGS
97
#include "codermacs.h"
98
#include "instr.h"
99
#endif
100
 
101
 
102
 
103
/*
104
    FORWARD DECLARATIONS
105
*/
106
 
107
static void stab_scope_open PROTO_S ( ( long ) ) ;
108
static void stab_scope_close PROTO_S ( ( long ) ) ;
109
static void stab_file PROTO_S ( ( long, bool ) ) ;
110
static void stab_local PROTO_S ( ( diag_info *, int, exp ) ) ;
111
static void stab_types PROTO_S ( ( void ) ) ;
112
 
113
 
114
 
115
 
116
/*
117
    DIAGNOSTICS FILE
118
*/
119
 
120
static FILE *dg_file ;
121
static char *dg_file_name ;
122
 
123
 
124
/*
125
    BASIC TYPE NUMBERS
126
*/
127
 
128
#define STAB_SCHAR	4
129
#define STAB_UCHAR	6
130
#define STAB_SSHRT	2
131
#define STAB_USHRT	3
132
#define STAB_SLONG	1
133
#define STAB_ULONG	8
134
#define STAB_FLOAT	10
135
#define STAB_DBL	11
136
#define STAB_LDBL	12
137
#define STAB_VOID	13
138
#define STAB_S64	14
139
#define STAB_U64	15
140
#define NO_STABS	16
141
 
142
 
143
/*
144
    80x86 register numbers
145
*/
146
 
147
#ifdef NEWDIAGS
148
static long reg_stabno [8] = {0, 2, 1, 3, 7, 6, 5, 4};
149
#endif
150
 
151
/*
152
    BASIC POINTERS
153
*/
154
 
155
static long stab_ptrs [ NO_STABS ] = {
156
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
157
} ;
158
 
159
 
160
/*
161
    CURRENT TYPE NUMBER
162
*/
163
 
164
static long typeno ;
165
 
166
 
167
/*
168
    SIZE OF LAST STAB TYPE OUTPUT
169
*/
170
 
171
static long last_type_sz = 0 ;
172
 
173
 
174
/*
175
    CURRENT LINE NUMBER AND FILE NUMBER
176
*/
177
 
178
long currentlno = -1 ;
179
long currentfile = -1 ;
180
 
181
 
182
/*
183
    ARRAY OF TYPE SIZES
184
*/
185
 
186
static long *type_sizes ;
187
static int total_type_sizes = 0 ;
188
 
189
 
190
/*
191
    SETTING AND GETTING TYPE SIZES
192
*/
193
 
194
#define set_stab_size( i )	type_sizes [ ( i ) ] = last_type_sz
195
#define get_stab_size( i )	( type_sizes [ ( i ) ] )
196
 
197
 
198
/*
199
    GET THE NEXT TYPE NUMBER
200
*/
201
 
202
static long next_typen
203
    PROTO_Z ()
204
{
205
    if ( typeno >= total_type_sizes ) {
206
	int i, n = total_type_sizes, m = n + 100 ;
207
	type_sizes = ( long * ) xrealloc ( (void*)(CH type_sizes),
208
					m * sizeof ( long ) ) ;
209
	for ( i = n ; i < m ; i++ ) type_sizes [i] = 0 ;
210
	total_type_sizes = m ;
211
    }
212
    return ( typeno++ ) ;
213
}
214
 
215
 
216
/*
217
    ARRAY OF FILE DESCRIPTORS
218
*/
219
 
220
static filename *fds = NULL ;
221
static int szfds = 0 ;
222
static int nofds = 0 ;
223
 
224
 
225
/*
226
    ADD A NEW FILE TO THE ARRAY OF FILE DESCRIPTORS
227
*/
228
 
229
void stab_collect_files
230
    PROTO_N ( (f) )
231
    PROTO_T ( filename f )
232
{
233
    if ( fds == NULL ) {
234
	szfds += 10 ;
235
	fds = ( filename * ) xmalloc ( szfds * sizeof ( filename ) ) ;
236
    } else if ( nofds >= szfds ) {
237
	szfds += 10 ;
238
	fds = ( filename * ) xrealloc ( (void*)(CH fds),
239
				szfds * sizeof ( filename ) ) ;
240
    }
241
    fds [ nofds++ ] = f ;
242
    return ;
243
}
244
 
245
 
246
/*
247
    FIND THE FILE DESCRIPTOR CORRESPONDING TO A FILE NAME
248
*/
249
 
250
static long find_file
251
    PROTO_N ( (f) )
252
    PROTO_T ( char * f )
253
{
254
    long i ;
255
    for ( i = 0 ; i < nofds ; i++ ) {
256
	if ( strcmp ( f, fds [i]->file.ints.chars ) == 0 ) return ( i ) ;
257
    }
258
    return ( 0 ) ;
259
}
260
 
261
 
262
static int last_proc_cname;
263
static char * last_proc_pname;
264
static int in_proc = 0;
265
 
266
static void out_procname
267
    PROTO_Z ()
268
{
269
  if (last_proc_cname == -1) {
270
    outs (last_proc_pname);
271
  }
272
  else {
273
    outs(local_prefix);
274
    outn ((long)last_proc_cname);
275
  };
276
}
277
 
278
 
279
/*
280
    OUTPUT A FILE POSITION CONSTRUCT
281
*/
282
 
283
#define N_SLINE 0x44
284
#define N_DSLINE 0x46
285
#define N_BSLINE 0x48
286
#define N_LBRAC  0xc0
287
#define N_RBRAC  0xe0
288
 
289
static void stabd
290
    PROTO_N ( (findex, lno, seg) )
291
    PROTO_T ( long findex X long lno X int seg )
292
{
293
    long i ;
294
 
295
    if ( findex == currentfile && lno == currentlno ) return ;
296
    stab_file ( findex, 1 ) ;
297
 
298
    if (seg != 0)		/* 0 suppresses always */
299
    {
300
      if (seg < 0 && !linux_elf)
301
	seg = - seg;
302
      if (seg > 0)		/* -ve line nos are put out in the stabs */
303
      {
304
	i = next_lab () ;
305
	fprintf ( dg_file, "%sL.%ld:\n", local_prefix, i ) ;
306
	fprintf ( dg_file, "\t.stabn\t0x%x,0,%ld,%sL.%ld",seg, lno, local_prefix, i ) ;
307
	if (linux_elf && in_proc) {
308
	  outs ("-");
309
	  out_procname ();
310
	}
311
	outnl ();
312
      }
313
    }
314
    currentlno = lno ;
315
    return ;
316
}
317
 
318
 
319
#ifdef NEWDIAGS
320
/*
321
    OUTPUT DIAGNOSTICS SURROUNDING CODE
322
*/
323
 
324
void code_diag_info
325
    PROTO_N ( (d, proc_no, mcode, args) )
326
    PROTO_T ( diag_info * d X int proc_no X void (*mcode) PROTO_S ((void *)) X void * args )
327
{
328
  if (d == nildiag) {
329
    (*mcode)(args);
330
    return;
331
  }
332
  switch (d->key) {
333
    case DIAG_INFO_SCOPE: {
334
	stab_scope_open ( currentfile ) ;
335
	stabd ( currentfile, ( long ) ( currentlno + 1 ), N_SLINE ) ;
336
	code_diag_info (d->more, proc_no, mcode, args);
337
	stab_scope_close ( currentfile ) ;
338
	return;
339
    }
340
    case DIAG_INFO_SOURCE: {
341
	sourcemark *s = &d->data.source.beg ;
342
	long f = find_file ( s->file->file.ints.chars ) ;
343
	stabd ( f, ( long ) s->line_no.nat_val.small_nat ,N_SLINE) ;
344
	code_diag_info (d->more, proc_no, mcode, args);
345
	s = &d->data.source.end ;
346
	f = find_file ( s->file->file.ints.chars ) ;
347
	stabd ( f, ( long ) s->line_no.nat_val.small_nat ,N_SLINE) ;
348
	return;
349
    }
350
    case DIAG_INFO_ID: {
351
	exp acc = d -> data.id_scope.access;
352
	if (name(acc) != hold_tag)
353
	  failer("not hold_tag");
354
	acc = son(acc);
355
	if (name(acc) == cont_tag && name(son(acc)) == name_tag && isvar(son(son(acc))))
356
	  acc = son(acc);
357
	if ( ( name(acc) == name_tag && !isdiscarded(acc) && !isglob(son(acc)) ) ||
358
		name(acc) == val_tag )
359
	  stab_local ( d, proc_no, acc );
360
	code_diag_info (d->more, proc_no, mcode, args);
361
    }
362
  };
363
  return;
364
}
365
 
366
 
367
#else
368
 
369
/*
370
    OUTPUT INITIAL DIAGNOSTICS FOR A DIAGNOSE_TAG
371
*/
372
 
373
void output_diag
374
    PROTO_N ( (d, proc_no, e) )
375
    PROTO_T ( diag_info * d X int proc_no X exp e )
376
{
377
  if ( d->key == DIAG_INFO_SOURCE ) {
378
    sourcemark *s = &d->data.source.beg ;
379
    long f = find_file ( s->file->file.ints.chars ) ;
380
    stabd ( f, ( long ) s->line_no.nat_val.small_nat ,N_SLINE) ;
381
    return ;
382
  }
383
 
384
  if (d -> key == DIAG_INFO_ID) {
385
    exp acc = d -> data.id_scope.access;
386
 
387
    if ( isglob ( son ( acc ) ) || no ( son ( acc ) ) == 1 ) return;
388
    mark_scope(e);
389
 
390
    if ( props ( e ) & 0x80 ) {
391
      stab_scope_open ( currentfile ) ;
392
      stabd ( currentfile, ( long ) ( currentlno + 1 ), N_SLINE ) ;
393
    }
394
 
395
    stab_local ( d, proc_no, acc );
396
    return ;
397
  }
398
}
399
 
400
 
401
/*
402
    OUTPUT FINAL DIAGNOSTICS FOR A DIAGNOSE_TAG
403
*/
404
 
405
void output_end_scope
406
    PROTO_N ( (d, e) )
407
    PROTO_T ( diag_info * d X exp e )
408
{
409
    if ( d->key == DIAG_INFO_SOURCE ) {
410
	sourcemark *s = &d->data.source.end ;
411
	long f = find_file ( s->file->file.ints.chars ) ;
412
	long lno = s->line_no.nat_val.small_nat ;
413
	stabd ( f, lno, N_SLINE) ;
414
	return ;
415
    }
416
    if ( d->key == DIAG_INFO_ID && props ( e ) & 0x80 ) {
417
	stab_scope_close ( currentfile ) ;
418
	return ;
419
    }
420
    return ;
421
}
422
 
423
 
424
#endif
425
/*
426
    INITIALISE DIAGNOSTICS
427
*/
428
 
429
void out_diagnose_prelude
430
    PROTO_Z ()
431
{
432
    dg_file_name = tmpnam ( NULL ) ;
433
    dg_file = fopen ( dg_file_name, "w" ) ;
434
    if ( dg_file == NULL ) {
435
	failer ( "Can't open temporary diagnostics file" ) ;
436
	exit (EXIT_FAILURE) ;
437
    }
438
    stab_types () ;
439
    return ;
440
}
441
 
442
 
443
/*
444
    INITIALIZE DIAGNOSTICS
445
*/
446
 
447
void init_stab_aux
448
    PROTO_Z ()
449
{
450
    int c ;
451
    FILE *f ;
452
    int i, j = -1 ;
453
    for ( i = 0 ; i < nofds ; i++ ) {
454
	char *s = fds [i]->file.ints.chars ;
455
	int n = ( int ) strlen ( s ) ;
456
	if ( n && s [ n - 1 ] != 'h' ) j = i ;
457
    }
458
    fclose ( dg_file ) ;
459
    dg_file = fpout ;
460
    if (j >= 0)
461
	fprintf (dg_file, "\t.file\t\"%s\"\n", fds[j]->file.ints.chars) ;
462
    else
463
	fprintf (dg_file, "\t.file\t\"no_source_file\"\n") ;
464
    stab_file ( ( long ) j, 0 ) ;
465
    f = fopen ( dg_file_name, "r" ) ;
466
    if ( f == NULL ) {
467
	failer ( "Can't open temporary diagnostics file" ) ;
468
	exit (EXIT_FAILURE) ;
469
    }
470
    while ( c = fgetc ( f ), c != EOF ) outc ( c ) ;
471
    fclose ( f ) ;
472
    remove ( dg_file_name ) ;
473
    return ;
474
}
475
 
476
void out_diagnose_postlude
477
    PROTO_Z ()
478
{
479
    long i = next_lab () ;
480
    fprintf ( dg_file, ".text\n" ) ;
481
    fprintf ( dg_file, "%sL.%ld:\n", local_prefix, i ) ;
482
    fprintf ( dg_file, "\t.stabs\t\"\",0x64,0,0,%sL.%ld\n", local_prefix, i ) ;
483
    return ;
484
}
485
 
486
 
487
/*
488
    FIND THE STAB OF A SIMPLE SHAPE
489
*/
490
 
491
static long out_sh_type
492
    PROTO_N ( (s) )
493
    PROTO_T ( shape s )
494
{
495
    last_type_sz = shape_size ( s ) ;
496
    switch ( name ( s ) ) {
497
	case scharhd : return ( STAB_SCHAR ) ;
498
	case ucharhd : return ( STAB_UCHAR ) ;
499
	case swordhd : return ( STAB_SSHRT ) ;
500
	case uwordhd : return ( STAB_USHRT ) ;
501
	case slonghd : return ( STAB_SLONG ) ;
502
	case ulonghd : return ( STAB_ULONG ) ;
503
	case s64hd : return ( STAB_S64 ) ;
504
	case u64hd : return ( STAB_U64 ) ;
505
	case shrealhd : return ( STAB_FLOAT ) ;
506
	case realhd : return ( STAB_DBL ) ;
507
	case doublehd : return ( STAB_LDBL ) ;
508
    }
509
    return ( STAB_VOID ) ;
510
}
511
 
512
 
513
/*
514
    OUTPUT DIAGNOSTICS DIRECTIVE FOR A FILE
515
*/
516
 
517
static void stab_file
518
    PROTO_N ( (findex, internal) )
519
    PROTO_T ( long findex X bool internal )
520
{
521
    static long i = 0 ;
522
 
523
    if ( findex == currentfile || findex < 0 || findex >= szfds ) {
524
	return ;
525
    }
526
 
527
    if ( !internal ) {
528
	/* source file */
529
	i = next_lab () ;
530
	fprintf ( dg_file, "%sL.%ld:\n", local_prefix, i ) ;
531
	fprintf ( dg_file, "\t.stabs\t\"%s\",0x64,0,0,%sL.%ld\n",
532
		  fds [ findex ]->file.ints.chars, local_prefix, i ) ;
533
    } else {
534
	/* included file */
535
	fprintf ( dg_file, "\t.stabs\t\"%s\",0x84,0,0,%sL.%ld\n",
536
		  fds [ findex ]->file.ints.chars, local_prefix, i ) ;
537
    }
538
    currentfile = findex ;
539
    return ;
540
}
541
 
542
 
543
/*
544
    ARRAY OF DIAGNOSTIC SCOPES
545
*/
546
 
547
static long open_label = 0 ;
548
static long bracket_level = 0 ;
549
 
550
 
551
/*
552
    START OF A DIAGNOSTICS SCOPE
553
*/
554
 
555
static void stab_scope_open
556
    PROTO_N ( (findex) )
557
    PROTO_T ( long findex )
558
{
559
    long i ;
560
    stab_file ( findex, 1 ) ;
561
    if ( open_label != 0 )
562
    {
563
	fprintf ( dg_file, "\t.stabn\t0x%x,0,%ld,%sL.%ld\n", N_LBRAC,
564
		  bracket_level, local_prefix, open_label ) ;
565
    }
566
    i = next_lab () ;
567
    fprintf ( dg_file, "%sL.%ld:\n", local_prefix, i ) ;
568
    bracket_level++ ;
569
    open_label = i ;
570
    return ;
571
}
572
 
573
 
574
/*
575
    END OF A DIAGNOSTICS SCOPE
576
*/
577
 
578
static void stab_scope_close
579
    PROTO_N ( (findex) )
580
    PROTO_T ( long findex )
581
{
582
    long i ;
583
    if ( open_label != 0 )
584
    {
585
	fprintf ( dg_file, "\t.stabn\t0x%x,0,%ld,%sL.%ld\n", N_LBRAC,
586
		  bracket_level, local_prefix, open_label ) ;
587
	open_label = 0 ;
588
    }
589
    i = next_lab () ;
590
    fprintf ( dg_file, "%sL.%ld:\n", local_prefix, i ) ;
591
    fprintf ( dg_file, "\t.stabn\t0x%x,0,%ld,%sL.%ld\n", N_RBRAC,
592
		  bracket_level, local_prefix, i ) ;
593
    bracket_level-- ;
594
    return ;
595
}
596
 
597
 
598
/*
599
    DEPTH COUNT FOR STAB TYPES
600
*/
601
 
602
static int max_depth = 64 ;
603
static int depth_now = 0 ;
604
 
605
 
606
/*
607
    OUTPUT A DIAGNOSTICS TYPE
608
*/
609
 
610
#define OUT_DT_SHAPE( dt )	out_dt_shape ( ( depth_now = 0, dt ) )
611
 
612
static void out_dt_shape
613
    PROTO_N ( (dt) )
614
    PROTO_T ( diag_type dt )
615
{
616
    if ( dt->been_outed ) {
617
	fprintf ( dg_file, "%d",(int) dt->been_outed ) ;
618
	last_type_sz = get_stab_size ( dt->been_outed ) ;
619
	return ;
620
    }
621
 
622
    /* SunOS as(1) rejects stab lines >2k so reduce size arbitrarily */
623
    if ( depth_now >= max_depth ) {
624
	fprintf ( dg_file, "%d", STAB_SLONG ) ;
625
	return ;
626
    }
627
    depth_now++ ;
628
 
629
    switch ( dt->key ) {
630
 
631
	case DIAG_TYPE_PTR : {
632
	    long non ;
633
	    diag_type pdt = dt->data.ptr.object ;
634
	    if ( pdt->key == DIAG_TYPE_VARIETY ) {
635
		long pn = out_sh_type ( f_integer ( pdt->data.var ) ) ;
636
		non = stab_ptrs [ pn ] ;
637
		if ( non == 0 ) {
638
		    non = next_typen () ;
639
		    stab_ptrs [ pn ] = non ;
640
		    fprintf ( dg_file, "%ld=*%ld", non, pn ) ;
641
		} else {
642
		    fprintf ( dg_file, "%ld", non ) ;
643
		}
644
	    } else {
645
		non = next_typen () ;
646
		fprintf ( dg_file, "%ld=*", non ) ;
647
		out_dt_shape ( dt->data.ptr.object ) ;
648
	    }
649
	    dt->been_outed = non ;
650
	    last_type_sz = 32 ;
651
	    set_stab_size ( non ) ;
652
	    break ;
653
	}
654
 
655
	case DIAG_TYPE_ARRAY : {
656
#if 0
657
	    long str = no ( dt->data.array.stride ) ;
658
#endif
659
	    long lwb = no ( dt->data.array.lower_b ) ;
660
	    long upb = no ( dt->data.array.upper_b ) ;
661
	    diag_type index_type = dt->data.array.index_type ;
662
	    diag_type element_type = dt->data.array.element_type ;
663
	    long non = next_typen () ;
664
	    dt->been_outed = non ;
665
	    fprintf ( dg_file, "%ld=ar", non ) ;
666
	    out_dt_shape ( index_type ) ;
667
	    fprintf ( dg_file, ";%ld;%ld;", lwb, upb ) ;
668
	    out_dt_shape ( element_type ) ;
669
	    last_type_sz *= ( upb - lwb + 1 ) ;
670
	    set_stab_size ( non ) ;
671
	    break ;
672
	}
673
 
674
	case DIAG_TYPE_STRUCT :
675
	case DIAG_TYPE_UNION : {
676
	    int i ;
677
	    char su ;
678
	    shape s ;
679
	    diag_field_list fields ;
680
	    long non = next_typen () ;
681
	    dt->been_outed = non ;
682
 
683
	    if ( dt->key == DIAG_TYPE_STRUCT ) {
684
		fields = dt->data.t_struct.fields ;
685
		s = dt->data.t_struct.tdf_shape ;
686
		su = 's';
687
	    } else {
688
		fields = dt->data.t_union.fields ;
689
		s = dt->data.t_union.tdf_shape;
690
		su = 'u' ;
691
	    }
692
	    fprintf ( dg_file, "%ld=%c%d", non, su, shape_size ( s ) / 8 ) ;
693
 
694
	    for ( i = fields->lastused - 1 ; i >= 0 ; i-- ) {
695
		diag_field sf =  ( fields->array ) [i] ;
696
		long offset = no ( sf->where );
697
 
698
		if ( depth_now >= max_depth ) return ;
699
		depth_now++ ;
700
		fprintf ( dg_file, "%s:", sf->field_name.ints.chars ) ;
701
		out_dt_shape ( sf->field_type ) ;
702
		fprintf ( dg_file, ",%ld,%ld;", offset, last_type_sz ) ;
703
	    }
704
	    fprintf ( dg_file, ";" ) ;
705
	    last_type_sz = shape_size ( s ) ;
706
	    set_stab_size ( non ) ;
707
	    break ;
708
	}
709
 
710
	case DIAG_TYPE_VARIETY : {
711
	    dt->been_outed = out_sh_type ( f_integer ( dt->data.var ) ) ;
712
	    fprintf ( dg_file, "%ld", dt->been_outed ) ;
713
	    break ;
714
	}
715
 
716
	case DIAG_TYPE_PROC: {
717
	    diag_type result_type = dt->data.proc.result_type ;
718
	    long non1 = next_typen () ;
719
	    long non2 = next_typen () ;
720
	    dt->been_outed = non1 ;
721
	    fprintf ( dg_file, "%ld=*%ld=f", non1, non2 ) ;
722
	    out_dt_shape ( result_type ) ;
723
	    last_type_sz = 32 ;
724
	    set_stab_size ( non1 ) ;
725
	    set_stab_size ( non2 ) ;
726
	    break ;
727
	}
728
 
729
	case DIAG_TYPE_LOC: {
730
	    /* +++ use qualifier which gives "const"/"volatile" */
731
	    out_dt_shape ( dt->data.loc.object ) ;
732
	    break ;
733
	}
734
 
735
	case DIAG_TYPE_FLOAT : {
736
	    dt->been_outed = out_sh_type ( f_floating ( dt->data.f_var ) ) ;
737
	    fprintf ( dg_file, "%ld", dt->been_outed ) ;
738
	    break ;
739
	}
740
 
741
	case DIAG_TYPE_NULL : {
742
	    fprintf ( dg_file, "%d", STAB_VOID ) ;
743
	    last_type_sz = 0 ;
744
	    break ;
745
	}
746
 
747
	case DIAG_TYPE_BITFIELD : {
748
	    long sz = dt->data.bitfield.no_of_bits.nat_val.small_nat ;
749
	    fprintf ( dg_file, "%d", STAB_SLONG ) ;
750
	    last_type_sz = sz ;
751
	    break ;
752
	}
753
 
754
	case DIAG_TYPE_ENUM : {
755
	    int i ;
756
	    enum_values_list enumvals = dt->data.t_enum.values;
757
	    long non = next_typen () ;
758
	    dt->been_outed = non ;
759
	    fprintf ( dg_file, "%ld=e", non ) ;
760
	    for ( i = enumvals->lastused - 1 ; i >= 0 ; i-- ) {
761
		enum_values ef =  ( enumvals->array ) [i] ;
762
		fprintf ( dg_file, "%s:%d,", ef->nme.ints.chars, no ( ef->val ) );
763
	    }
764
	    fprintf ( dg_file, ";" ) ;
765
	    last_type_sz = 32 ;
766
	    set_stab_size ( non ) ;
767
	    break ;
768
	}
769
 
770
	default : {
771
	    fprintf ( dg_file, "%d", STAB_VOID ) ;
772
	    last_type_sz = 0 ;
773
	    break ;
774
	}
775
    }
776
    return ;
777
}
778
 
779
 
780
/*
781
    OUTPUT DIAGNOSTICS FOR A GLOBAL VARIABLE
782
*/
783
 
784
void diag_val_begin
785
    PROTO_N ( (d, global, cname, pname) )
786
    PROTO_T ( diag_global * d X int global X int cname X char * pname )
787
{
788
  stabd ( find_file ( d->data.id.whence.file->file.ints.chars ),
789
	 ( long ) d->data.id.whence.line_no.nat_val.small_nat
790
	 , -N_DSLINE ) ;
791
 
792
  fprintf ( dg_file, "\t.stabs\t\"%s:%c",
793
	d->data.id.nme.ints.chars, (global ? 'G' : 'S'));
794
  OUT_DT_SHAPE ( d->data.id.new_type ) ;
795
  if (global)
796
    fprintf ( dg_file, "\",0x20,0,%d,0\n",
797
	d->data.id.whence.line_no.nat_val.small_nat);
798
  else {
799
    fprintf ( dg_file, "\",0x28,0,%d,",
800
	d->data.id.whence.line_no.nat_val.small_nat);
801
    if (cname == -1) {
802
      outs (pname);
803
    }
804
    else {
805
      outs(local_prefix);
806
      outn ((long)cname);
807
    };
808
    outnl ();
809
  };
810
  return ;
811
}
812
 
813
void diag_val_end
814
    PROTO_N ( (d) )
815
    PROTO_T ( diag_global * d )
816
{
817
  UNUSED(d);
818
  return;
819
}
820
 
821
 
822
/*
823
    OUTPUT DIAGNOSTICS FOR A PROCEDURE
824
*/
825
 
826
void diag_proc_begin
827
    PROTO_N ( (d, global, cname, pname) )
828
    PROTO_T ( diag_global * d X int global X int cname X char * pname )
829
{
830
  last_proc_pname = pname;
831
  last_proc_cname = cname;
832
  in_proc = 1;
833
  if (!d)
834
    return;
835
 
836
  stabd ( find_file ( d->data.id.whence.file->file.ints.chars ),
837
	 ( long ) d->data.id.whence.line_no.nat_val.small_nat
838
	 ,0) ;
839
 
840
  outs ("\t.stabs\t\"");
841
  outs (d->data.id.nme.ints.chars);
842
  if (global)
843
    outs (":F");
844
  else
845
    outs (":f");
846
  OUT_DT_SHAPE ( d->data.id.new_type->data.proc.result_type ) ;
847
  outs ("\",0x24,0,0,");
848
  out_procname ();
849
  outnl ();
850
  return ;
851
}
852
 
853
void diag_proc_end
854
    PROTO_N ( (d) )
855
    PROTO_T ( diag_global * d )
856
{
857
  UNUSED(d);
858
  in_proc = 0;
859
  return;
860
}
861
 
862
 
863
 
864
/*
865
    OUTPUT DIAGNOSTICS FOR A LOCAL VARIABLE
866
*/
867
 
868
static void stab_local
869
    PROTO_N ( (d, proc_no, acc) )
870
    PROTO_T ( diag_info * d X int proc_no X exp acc )
871
{
872
  int p, param_dec;
873
#ifdef NEWDIAGS
874
  long acc_type;
875
  if (name(acc) == name_tag) {
876
    acc_type = ptno(son(acc));
877
    if (no_frame && acc_type != reg_pl)
878
      return;
879
  }
880
  if (name(acc) != name_tag) {
881
    fprintf ( dg_file, "\t.stabs\t\"%s=i\",0x80,0,0,%d\n",
882
	d -> data.id_scope.nme.ints.chars, no(acc) );
883
  }
884
  else
885
  if (acc_type == reg_pl) {
886
    fprintf ( dg_file, "\t.stabs\t\"%s:r",
887
	d -> data.id_scope.nme.ints.chars );
888
    OUT_DT_SHAPE ( d -> data.id_scope.typ ) ;
889
    fprintf ( dg_file, "\",0x40,0,0,%d\n",
890
		reg_stabno [get_reg_no (no(son(acc)))]);
891
  }
892
  else
893
#endif
894
  {
895
    p = (no(acc) + no(son(acc))) / 8;
896
    param_dec = isparam(son(acc));
897
 
898
    fprintf ( dg_file, "\t.stabs\t\"%s:",
899
	d -> data.id_scope.nme.ints.chars );
900
    OUT_DT_SHAPE ( d -> data.id_scope.typ ) ;
901
    fprintf ( dg_file, "\",0x80,0,%d,",
902
 
903
    if (param_dec)
904
      fprintf ( dg_file, "%d\n", p+8);
905
    else
906
      fprintf ( dg_file, "%d-%sdisp%d\n", p, local_prefix, proc_no);
907
  }
908
  return ;
909
}
910
 
911
 
912
 
913
/*
914
    DEAL WITH BASIC TYPES
915
*/
916
 
917
static void stab_types
918
    PROTO_Z ()
919
{
920
    total_type_sizes = NO_STABS ;
921
    typeno = NO_STABS ;
922
    type_sizes = ( long * ) xmalloc ( NO_STABS * sizeof ( long ) ) ;
923
    fputs ( "\t.stabs\t\"int:t1=r1;-2147483648;2147483647;\",0x80,0,0,0\n",
924
	    dg_file ) ;
925
    fputs ( "\t.stabs\t\"short int:t2=r1;-32768;32767;\",0x80,0,0,0\n",
926
	    dg_file ) ;
927
    fputs ( "\t.stabs\t\"short unsigned int:t3=r1;0;65535;\",0x80,0,0,0\n",
928
	    dg_file ) ;
929
    fputs ( "\t.stabs\t\"char:t4=r4;0;127;\",0x80,0,0,0\n",
930
	    dg_file ) ;
931
    fputs ( "\t.stabs\t\"signed char:t5=r1;-128;127;\",0x80,0,0,0\n",
932
	    dg_file ) ;
933
    fputs ( "\t.stabs\t\"unsigned char:t6=r1;0;255;\",0x80,0,0,0\n",
934
	    dg_file ) ;
935
    fputs ( "\t.stabs\t\"long int:t7=r1;-2147483648;2147483647;\",0x80,0,0,0\n",
936
	    dg_file ) ;
937
    fputs ( "\t.stabs\t\"unsigned int:t8=r1;0;-1;\",0x80,0,0,0\n",
938
	    dg_file ) ;
939
    fputs ( "\t.stabs\t\"long unsigned int:t9=r1;0;-1;\",0x80,0,0,0\n",
940
	    dg_file ) ;
941
    fputs ( "\t.stabs\t\"float:t10=r1;4;0;\",0x80,0,0,0\n",
942
	    dg_file ) ;
943
    fputs ( "\t.stabs\t\"double:t11=r1;8;0;\",0x80,0,0,0\n",
944
	    dg_file ) ;
945
    fprintf ( dg_file, "\t.stabs\t\"long double:t12=r1;%d;0;\",0x80,0,0,0\n",
946
	      DOUBLE_SZ / 8 ) ;
947
    fputs ( "\t.stabs\t\"void:t13=13\",0x80,0,0,0\n",
948
	    dg_file ) ;
949
    fputs ( "\t.stabs\t\"long long int:t14=r1;", dg_file ) ;
950
    fputs ( "01000000000000000000000;0777777777777777777777;\",0x80,0,0,0\n",
951
	    dg_file ) ;
952
    fputs ( "\t.stabs\t\"unsigned long long int:t15=r1;", dg_file ) ;
953
    fputs ( "0000000000000;01777777777777777777777;\",0x80,0,0,0\n",
954
	    dg_file ) ;
955
    type_sizes [0] = 0 ;
956
    type_sizes [1] = 32 ;
957
    type_sizes [2] = 16 ;
958
    type_sizes [3] = 16 ;
959
    type_sizes [4] = 8 ;
960
    type_sizes [5] = 8 ;
961
    type_sizes [6] = 8 ;
962
    type_sizes [7] = 32 ;
963
    type_sizes [8] = 32 ;
964
    type_sizes [9] = 32 ;
965
    type_sizes [10] = 32 ;
966
    type_sizes [11] = 64 ;
967
    type_sizes [12] = DOUBLE_SZ ;
968
    type_sizes [13] = 0 ;
969
    type_sizes [14] = 64 ;
970
    type_sizes [15] = 64 ;
971
    return ;
972
}
973
 
974
 
975
/*
976
    DEAL WITH STRUCTURE, UNION AND ENUM TAGS
977
*/
978
 
979
void stab_tagdefs
980
    PROTO_Z ()
981
{
982
    diag_tagdef **di = unit_ind_diagtags ;
983
    int i, n = unit_no_of_diagtags, istag ;
984
 
985
    for ( i = 0 ; i < n ; i++ ) {
986
	diag_type d = di [i]->d_type ;
987
	istag = 1;
988
 
989
	switch ( d->key ) {
990
 
991
	    case DIAG_TYPE_STRUCT : {
992
		char *nme = d->data.t_struct.nme.ints.chars ;
993
		if ( nme && *nme ) {
994
		    fprintf ( dg_file, "\t.stabs\t\"%s:", nme ) ;
995
		} else {
996
		    static int s_count = 0 ;
997
		    fprintf ( dg_file, "\t.stabs\t\"_struct%d:", s_count++ ) ;
998
		}
999
		break ;
1000
	    }
1001
	    case DIAG_TYPE_UNION : {
1002
		char *nme = d->data.t_union.nme.ints.chars ;
1003
		if ( nme && *nme ) {
1004
		    fprintf ( dg_file, "\t.stabs\t\"%s:", nme ) ;
1005
		} else {
1006
		    static int u_count = 0 ;
1007
		    fprintf ( dg_file, "\t.stabs\t\"_union%d:", u_count++ ) ;
1008
		}
1009
		break ;
1010
	    }
1011
	    case DIAG_TYPE_ENUM : {
1012
		char *nme = d->data.t_enum.nme.ints.chars ;
1013
		if ( nme && *nme ) {
1014
		    fprintf ( dg_file, "\t.stabs\t\"%s:", nme ) ;
1015
		} else {
1016
		    static int e_count = 0 ;
1017
		    fprintf ( dg_file, "\t.stabs\t\"_enum%d:", e_count++ ) ;
1018
		}
1019
		break ;
1020
	    }
1021
	    default: {
1022
		istag = 0 ;
1023
		break ;
1024
	    }
1025
	}
1026
	if (istag) {
1027
	    if ( d->been_outed && 0) {
1028
		fprintf ( dg_file, "%d", (int)d->been_outed ) ;
1029
	    } else {
1030
		fprintf ( dg_file, "T" ) ;
1031
		OUT_DT_SHAPE ( d ) ;
1032
	    }
1033
	    fprintf ( dg_file, "\",0x80,0,0,0\n" ) ;
1034
	}
1035
    }
1036
    return ;
1037
}
1038
 
1039
 
1040
/*
1041
    DEAL WITH TYPEDEFS
1042
*/
1043
 
1044
void stab_typedefs
1045
    PROTO_Z ()
1046
{
1047
    diag_descriptor *di = unit_diagvar_tab.array ;
1048
    int i, n = unit_diagvar_tab.lastused ;
1049
    for ( i = 0 ; i < n ; i++ ) {
1050
	if ( di [i].key == DIAG_TYPEDEF_KEY ) {
1051
	    long non = next_typen () ;
1052
	    fprintf ( dg_file, "\t.stabs\t\"%s:t%ld=",
1053
		      di [i].data.typ.nme.ints.chars, non ) ;
1054
	    OUT_DT_SHAPE ( di [i].data.typ.new_type ) ;
1055
	    fprintf ( dg_file, "\",0x80,0,0,0\n" ) ;
1056
	}
1057
    }
1058
    return ;
1059
}