Subversion Repositories tendra.SVN

Rev

Rev 6 | Details | Compare with Previous | Last modification | View Log | RSS feed

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