Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /trunk/src/installers/amd64/dragonfly/diag_out.c – Rev 6

Subversion Repositories tendra.SVN

Rev

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