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
/* 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
 
7 7u83 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);
2 7u83 142
 
143
 
144
/*
145
    DIAGNOSTICS FILE
146
*/
147
 
7 7u83 148
static FILE *dg_file;
149
static char *dg_file_name;
2 7u83 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
7 7u83 176
static long reg_stabno[8] = {0, 2, 1, 3, 7, 6, 5, 4};
2 7u83 177
#endif
178
 
179
/*
180
    BASIC POINTERS
181
*/
182
 
7 7u83 183
static long stab_ptrs[NO_STABS] = {
2 7u83 184
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
7 7u83 185
};
2 7u83 186
 
187
 
188
/*
189
    CURRENT TYPE NUMBER
190
*/
191
 
7 7u83 192
static long typeno;
2 7u83 193
 
194
 
195
/*
196
    SIZE OF LAST STAB TYPE OUTPUT
197
*/
198
 
7 7u83 199
static long last_type_sz = 0;
2 7u83 200
 
201
 
202
/*
203
    CURRENT LINE NUMBER AND FILE NUMBER
204
*/
205
 
7 7u83 206
long currentlno = -1;
207
long currentfile = -1;
2 7u83 208
 
209
 
210
/*
211
    ARRAY OF TYPE SIZES
212
*/
213
 
7 7u83 214
static long *type_sizes;
215
static int total_type_sizes = 0;
2 7u83 216
 
217
 
218
/*
219
    SETTING AND GETTING TYPE SIZES
220
*/
221
 
7 7u83 222
#define set_stab_size(i)	type_sizes[(i)] = last_type_sz
223
#define get_stab_size(i)	(type_sizes[(i)])
2 7u83 224
 
225
 
226
/*
227
    GET THE NEXT TYPE NUMBER
228
*/
229
 
7 7u83 230
static long
231
next_typen(void)
2 7u83 232
{
7 7u83 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;
2 7u83 241
    }
7 7u83 242
    return(typeno++);
2 7u83 243
}
244
 
245
 
246
/*
247
    ARRAY OF FILE DESCRIPTORS
248
*/
249
 
7 7u83 250
static filename *fds = NULL;
251
static int szfds = 0;
252
static int nofds = 0;
2 7u83 253
 
254
 
255
/*
256
    ADD A NEW FILE TO THE ARRAY OF FILE DESCRIPTORS
257
*/
258
 
7 7u83 259
void
260
stab_collect_files(filename f)
2 7u83 261
{
7 7u83 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));
2 7u83 268
    }
7 7u83 269
    fds[nofds++] = f;
270
    return;
2 7u83 271
}
272
 
273
 
274
/*
275
    FIND THE FILE DESCRIPTOR CORRESPONDING TO A FILE NAME
276
*/
277
 
7 7u83 278
static long
279
find_file(char *f)
2 7u83 280
{
7 7u83 281
    long i;
282
    for (i = 0; i < nofds; i++) {
283
	if (strcmp(f, fds[i] ->file.ints.chars) == 0) {
284
	    return(i);
285
	}
2 7u83 286
    }
7 7u83 287
    return(0);
2 7u83 288
}
289
 
290
 
291
static int last_proc_cname;
7 7u83 292
static char *last_proc_pname;
2 7u83 293
static int in_proc = 0;
294
 
7 7u83 295
static void
296
out_procname(void)
2 7u83 297
{
298
  if (last_proc_cname == -1) {
7 7u83 299
    outs(last_proc_pname);
300
  } else {
301
    outs(local_prefix);
302
    outn((long)last_proc_cname);
2 7u83 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
 
7 7u83 317
static void
318
stabd(long findex, long lno, int seg)
2 7u83 319
{
7 7u83 320
    long i;
2 7u83 321
 
7 7u83 322
    if (findex == currentfile && lno == currentlno) {
323
	return;
324
    }
325
    stab_file(findex, 1);
2 7u83 326
 
7 7u83 327
    if (seg != 0) {		/* 0 suppresses always */
328
      if (seg < 0 && !linux_elf) {
2 7u83 329
	seg = - seg;
7 7u83 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);
2 7u83 336
	if (linux_elf && in_proc) {
7 7u83 337
	  outs("-");
338
	  out_procname();
2 7u83 339
	}
7 7u83 340
	outnl();
2 7u83 341
      }
342
    }
7 7u83 343
    currentlno = lno;
344
    return;
2 7u83 345
}
346
 
347
 
348
#ifdef NEWDIAGS
349
/*
350
    OUTPUT DIAGNOSTICS SURROUNDING CODE
351
*/
352
 
7 7u83 353
void
354
code_diag_info(diag_info *d, int proc_no, void(*mcode)(void *), void *args)
2 7u83 355
{
356
  if (d == nildiag) {
7 7u83 357
   (*mcode)(args);
2 7u83 358
    return;
359
  }
360
  switch (d->key) {
361
    case DIAG_INFO_SCOPE: {
7 7u83 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);
2 7u83 366
	return;
367
    }
368
    case DIAG_INFO_SOURCE: {
7 7u83 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);
2 7u83 376
	return;
377
    }
378
    case DIAG_INFO_ID: {
379
	exp acc = d -> data.id_scope.access;
7 7u83 380
	if (name(acc)!= hold_tag) {
2 7u83 381
	  failer("not hold_tag");
7 7u83 382
	}
2 7u83 383
	acc = son(acc);
7 7u83 384
	if (name(acc) == cont_tag && name(son(acc)) == name_tag &&
385
	    isvar(son(son(acc)))) {
2 7u83 386
	  acc = son(acc);
7 7u83 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);
2 7u83 393
    }
7 7u83 394
  }
2 7u83 395
  return;
396
}
397
 
398
 
399
#else
400
 
401
/*
402
    OUTPUT INITIAL DIAGNOSTICS FOR A DIAGNOSE_TAG
403
*/
404
 
7 7u83 405
void
406
output_diag(diag_info *d, int proc_no, exp e)
2 7u83 407
{
7 7u83 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;
2 7u83 413
  }
414
 
7 7u83 415
  if (d->key == DIAG_INFO_ID) {
416
    exp acc = d->data.id_scope.access;
2 7u83 417
 
7 7u83 418
    if (isglob(son(acc)) || no(son(acc)) == 1) {
419
      return;
420
    }
2 7u83 421
    mark_scope(e);
422
 
7 7u83 423
    if (props(e) & 0x80) {
424
      stab_scope_open(currentfile);
425
      stabd(currentfile, (long)(currentlno + 1), N_SLINE);
2 7u83 426
    }
427
 
7 7u83 428
    stab_local(d, proc_no, acc);
429
    return;
2 7u83 430
  }
431
}
432
 
433
 
434
/*
435
    OUTPUT FINAL DIAGNOSTICS FOR A DIAGNOSE_TAG
436
*/
437
 
7 7u83 438
void
439
output_end_scope(diag_info *d, exp e)
2 7u83 440
{
7 7u83 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;
2 7u83 447
    }
7 7u83 448
    if (d->key == DIAG_INFO_ID && props(e) & 0x80) {
449
	stab_scope_close(currentfile);
450
	return;
2 7u83 451
    }
7 7u83 452
    return;
2 7u83 453
}
454
 
455
 
456
#endif
457
/*
458
    INITIALISE DIAGNOSTICS
459
*/
460
 
7 7u83 461
void
462
out_diagnose_prelude(void)
2 7u83 463
{
7 7u83 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);
2 7u83 469
    }
7 7u83 470
    stab_types();
471
    return;
2 7u83 472
}
473
 
474
 
475
/*
476
    INITIALIZE DIAGNOSTICS
477
*/
478
 
7 7u83 479
void
480
init_stab_aux(void)
2 7u83 481
{
7 7u83 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
	}
2 7u83 491
    }
7 7u83 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");
2 7u83 498
    }
7 7u83 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;
2 7u83 511
}
512
 
7 7u83 513
void
514
out_diagnose_postlude(void)
2 7u83 515
{
7 7u83 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;
2 7u83 521
}
522
 
523
 
524
/*
525
    FIND THE STAB OF A SIMPLE SHAPE
526
*/
527
 
7 7u83 528
static long
529
out_sh_type(shape s)
2 7u83 530
{
7 7u83 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);
2 7u83 544
    }
7 7u83 545
    return(STAB_VOID);
2 7u83 546
}
547
 
548
 
549
/*
550
    OUTPUT DIAGNOSTICS DIRECTIVE FOR A FILE
551
*/
552
 
7 7u83 553
static void
554
stab_file(long findex, bool internal)
2 7u83 555
{
7 7u83 556
    static long i = 0;
2 7u83 557
 
7 7u83 558
    if (findex == currentfile || findex < 0 || findex >= szfds) {
559
	return;
2 7u83 560
    }
561
 
7 7u83 562
    if (!internal) {
2 7u83 563
	/* source file */
7 7u83 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);
2 7u83 568
    } else {
569
	/* included file */
7 7u83 570
	fprintf(dg_file, "\t.stabs\t\"%s\",0x84,0,0,%sL.%ld\n",
571
		fds[findex]->file.ints.chars, local_prefix, i);
2 7u83 572
    }
7 7u83 573
    currentfile = findex;
574
    return;
2 7u83 575
}
576
 
577
 
578
/*
579
    ARRAY OF DIAGNOSTIC SCOPES
580
*/
581
 
7 7u83 582
static long open_label = 0;
583
static long bracket_level = 0;
2 7u83 584
 
585
 
586
/*
587
    START OF A DIAGNOSTICS SCOPE
588
*/
589
 
7 7u83 590
static void
591
stab_scope_open(long findex)
2 7u83 592
{
7 7u83 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);
2 7u83 598
    }
7 7u83 599
    i = next_lab();
600
    fprintf(dg_file, "%sL.%ld:\n", local_prefix, i);
601
    bracket_level++;
602
    open_label = i;
603
    return;
2 7u83 604
}
605
 
606
 
607
/*
608
    END OF A DIAGNOSTICS SCOPE
609
*/
610
 
7 7u83 611
static void
612
stab_scope_close(long findex)
2 7u83 613
{
7 7u83 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;
2 7u83 619
    }
7 7u83 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;
2 7u83 626
}
627
 
628
 
629
/*
630
    DEPTH COUNT FOR STAB TYPES
631
*/
632
 
7 7u83 633
static int max_depth = 64;
634
static int depth_now = 0;
2 7u83 635
 
636
 
637
/*
638
    OUTPUT A DIAGNOSTICS TYPE
639
*/
640
 
7 7u83 641
#define OUT_DT_SHAPE(dt)	out_dt_shape((depth_now = 0, dt))
2 7u83 642
 
7 7u83 643
static void
644
out_dt_shape(diag_type dt)
2 7u83 645
{
7 7u83 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;
2 7u83 650
    }
651
 
652
    /* SunOS as(1) rejects stab lines >2k so reduce size arbitrarily */
7 7u83 653
    if (depth_now >= max_depth) {
654
	fprintf(dg_file, "%d", STAB_SLONG);
655
	return;
2 7u83 656
    }
7 7u83 657
    depth_now++;
2 7u83 658
 
7 7u83 659
    switch (dt->key) {
2 7u83 660
 
7 7u83 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);
2 7u83 671
		} else {
7 7u83 672
		    fprintf(dg_file, "%ld", non);
2 7u83 673
		}
674
	    } else {
7 7u83 675
		non = next_typen();
676
		fprintf(dg_file, "%ld=*", non);
677
		out_dt_shape(dt->data.ptr.object);
2 7u83 678
	    }
7 7u83 679
	    dt->been_outed = non;
680
	    last_type_sz = 32;
681
	    set_stab_size(non);
682
	    break;
2 7u83 683
	}
684
 
7 7u83 685
	case DIAG_TYPE_ARRAY: {
2 7u83 686
#if 0
7 7u83 687
	    long str = no(dt->data.array.stride);
2 7u83 688
#endif
7 7u83 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;
2 7u83 702
	}
703
 
7 7u83 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;
2 7u83 712
 
7 7u83 713
	    if (dt->key == DIAG_TYPE_STRUCT) {
714
		fields = dt->data.t_struct.fields;
715
		s = dt->data.t_struct.tdf_shape;
2 7u83 716
		su = 's';
717
	    } else {
7 7u83 718
		fields = dt->data.t_union.fields;
2 7u83 719
		s = dt->data.t_union.tdf_shape;
7 7u83 720
		su = 'u';
2 7u83 721
	    }
7 7u83 722
	    fprintf(dg_file, "%ld=%c%d", non, su, shape_size(s) / 8);
2 7u83 723
 
7 7u83 724
	    for (i = fields->lastused - 1; i >= 0; i--) {
725
		diag_field sf = (fields->array)[i];
726
		long offset = no(sf->where);
2 7u83 727
 
7 7u83 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);
2 7u83 735
	    }
7 7u83 736
	    fprintf(dg_file, ";");
737
	    last_type_sz = shape_size(s);
738
	    set_stab_size(non);
739
	    break;
2 7u83 740
	}
741
 
7 7u83 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;
2 7u83 746
	}
747
 
748
	case DIAG_TYPE_PROC: {
7 7u83 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;
2 7u83 759
	}
760
 
761
	case DIAG_TYPE_LOC: {
762
	    /* +++ use qualifier which gives "const"/"volatile" */
7 7u83 763
	    out_dt_shape(dt->data.loc.object);
764
	    break;
2 7u83 765
	}
766
 
7 7u83 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;
2 7u83 771
	}
772
 
7 7u83 773
	case DIAG_TYPE_NULL: {
774
	    fprintf(dg_file, "%d", STAB_VOID);
775
	    last_type_sz = 0;
776
	    break;
2 7u83 777
	}
778
 
7 7u83 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;
2 7u83 784
	}
785
 
7 7u83 786
	case DIAG_TYPE_ENUM: {
787
	    int i;
2 7u83 788
	    enum_values_list enumvals = dt->data.t_enum.values;
7 7u83 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));
2 7u83 795
	    }
7 7u83 796
	    fprintf(dg_file, ";");
797
	    last_type_sz = 32;
798
	    set_stab_size(non);
799
	    break;
2 7u83 800
	}
801
 
802
	default : {
7 7u83 803
	    fprintf(dg_file, "%d", STAB_VOID);
804
	    last_type_sz = 0;
805
	    break;
2 7u83 806
	}
807
    }
7 7u83 808
    return;
2 7u83 809
}
810
 
811
 
812
/*
813
    OUTPUT DIAGNOSTICS FOR A GLOBAL VARIABLE
814
*/
815
 
7 7u83 816
void
817
diag_val_begin(diag_global *d, int global, int cname, char *pname)
2 7u83 818
{
7 7u83 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);
2 7u83 821
 
7 7u83 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);
2 7u83 831
    if (cname == -1) {
7 7u83 832
      outs(pname);
833
    } else {
834
      outs(local_prefix);
835
      outn((long)cname);
2 7u83 836
    }
7 7u83 837
    outnl();
838
  }
839
  return;
2 7u83 840
}
841
 
7 7u83 842
void
843
diag_val_end(diag_global *d)
2 7u83 844
{
845
  UNUSED(d);
846
  return;
847
}
848
 
849
 
850
/*
851
    OUTPUT DIAGNOSTICS FOR A PROCEDURE
852
*/
853
 
7 7u83 854
void
855
diag_proc_begin(diag_global *d, int global, int cname, char *pname)
2 7u83 856
{
857
  last_proc_pname = pname;
858
  last_proc_cname = cname;
859
  in_proc = 1;
7 7u83 860
  if (!d) {
2 7u83 861
    return;
7 7u83 862
  }
2 7u83 863
 
7 7u83 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);
2 7u83 866
 
7 7u83 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;
2 7u83 879
}
880
 
7 7u83 881
void
882
diag_proc_end(diag_global *d)
2 7u83 883
{
884
  UNUSED(d);
885
  in_proc = 0;
886
  return;
887
}
888
 
889
 
890
 
891
/*
892
    OUTPUT DIAGNOSTICS FOR A LOCAL VARIABLE
893
*/
894
 
7 7u83 895
static void
896
stab_local(diag_info *d, int proc_no, exp acc)
2 7u83 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));
7 7u83 903
    if (no_frame && acc_type != reg_pl) {
2 7u83 904
      return;
7 7u83 905
    }
2 7u83 906
  }
907
  if (name(acc) != name_tag) {
7 7u83 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
2 7u83 915
#endif
916
  {
917
    p = (no(acc) + no(son(acc))) / 8;
918
    param_dec = isparam(son(acc));
919
 
7 7u83 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
    }
2 7u83 928
  }
7 7u83 929
  return;
2 7u83 930
}
931
 
932
 
933
 
934
/*
935
    DEAL WITH BASIC TYPES
936
*/
937
 
7 7u83 938
static void
939
stab_types(void)
2 7u83 940
{
7 7u83 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;
2 7u83 983
}
984
 
985
 
986
/*
987
    DEAL WITH STRUCTURE, UNION AND ENUM TAGS
988
*/
989
 
7 7u83 990
void
991
stab_tagdefs(void)
2 7u83 992
{
7 7u83 993
    diag_tagdef **di = unit_ind_diagtags;
994
    int i, n = unit_no_of_diagtags, istag;
2 7u83 995
 
7 7u83 996
    for (i = 0; i < n; i++) {
997
	diag_type d = di[i]->d_type;
2 7u83 998
	istag = 1;
999
 
7 7u83 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);
2 7u83 1005
		} else {
7 7u83 1006
		    static int s_count = 0;
1007
		    fprintf(dg_file, "\t.stabs\t\"_struct%d:", s_count++);
2 7u83 1008
		}
7 7u83 1009
		break;
2 7u83 1010
	    }
7 7u83 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);
2 7u83 1015
		} else {
7 7u83 1016
		    static int u_count = 0;
1017
		    fprintf(dg_file, "\t.stabs\t\"_union%d:", u_count++);
2 7u83 1018
		}
7 7u83 1019
		break;
2 7u83 1020
	    }
7 7u83 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);
2 7u83 1025
		} else {
7 7u83 1026
		    static int e_count = 0;
1027
		    fprintf(dg_file, "\t.stabs\t\"_enum%d:", e_count++);
2 7u83 1028
		}
7 7u83 1029
		break;
2 7u83 1030
	    }
1031
	    default: {
7 7u83 1032
		istag = 0;
1033
		break;
2 7u83 1034
	    }
1035
	}
1036
	if (istag) {
7 7u83 1037
	    if (d->been_outed && 0) {
1038
		fprintf(dg_file, "%d", (int)d->been_outed);
2 7u83 1039
	    } else {
7 7u83 1040
		fprintf(dg_file, "T");
1041
		OUT_DT_SHAPE(d);
2 7u83 1042
	    }
7 7u83 1043
	    fprintf(dg_file, "\",0x80,0,0,0\n");
2 7u83 1044
	}
1045
    }
7 7u83 1046
    return;
2 7u83 1047
}
1048
 
1049
 
1050
/*
1051
    DEAL WITH TYPEDEFS
1052
*/
1053
 
7 7u83 1054
void
1055
stab_typedefs(void)
2 7u83 1056
{
7 7u83 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");
2 7u83 1066
	}
1067
    }
7 7u83 1068
    return;
2 7u83 1069
}