Subversion Repositories tendra.SVN

Rev

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

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