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

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 – /branches/algol60/src/installers/sparc/sunos/sparcdiags.c – Rev 7

Subversion Repositories tendra.SVN

Rev

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