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