Subversion Repositories tendra.SVN

Rev

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