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
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
/* 	alphadiags.c,v 1.3 1995/06/28 10:19:06 john Exp	 */
62
 
63
#ifndef lint
64
static char vcid[] = "alphadiags.c,v 1.3 1995/06/28 10:19:06 john Exp";
65
#endif /* lint */
66
 
67
 
68
/*
69
  alphadiags.c
7 7u83 70
  This file contains functions to handle code diagnostics for
71
  alpha/OSF1. (largely based on the mips installer version
2 7u83 72
  'mipsdiags.c').
73
*/
74
 
75
/*
76
alphadiags.c,v
77
 * Revision 1.3  1995/06/28  10:19:06  john
78
 * Reformatting
79
 *
80
 * Revision 1.2  1995/05/23  10:52:24  john
81
 * Fix to non 64 bit machines
82
 *
83
 * Revision 1.1.1.1  1995/03/23  10:39:01  john
84
 * Entered into CVS
85
 *
86
 * Revision 1.7  1995/01/31  14:24:24  john
87
 * Various portability changes
88
 *
89
 * Revision 1.6  1995/01/26  13:36:38  john
90
 * Minor portability improvements
91
 *
92
*/
93
#include "config.h"
94
#include "common_types.h"
95
#include "exptypes.h"
96
#include "shapemacs.h"
97
#include "expmacs.h"
98
#include "exp.h"
99
#include "procrectypes.h"
100
#include "procrecs.h"
101
#include "tags.h"
102
#include "bitsmacs.h"
103
#include "diagtypes.h"
104
#include "xalloc.h"
105
#include "syms.h"
106
#include "diag_fns.h"
107
#include "locate.h"
108
#include "alphadiags.h"
109
#include "diagglob.h"
110
#include "mark_scope.h"
111
#include "ibinasm.h"
112
#include "out_ba.h"
113
#include "coder.h"
114
#include "cross.h"
115
#include "symbol.h"
116
#include "cross_config.h"
117
 
118
#ifndef CROSS_INCLUDE
119
#include <symconst.h>
120
#else
121
#include CROSS_INCLUDE/symconst.h>
122
#endif
123
 
124
extern FILE * as_file;
7 7u83 125
extern bool last_param(exp e);
2 7u83 126
extern int currentfile;
127
/* our current fileno  */
128
extern int mainfile;
129
/* default fileno for no diags or shape output */
130
 
131
 
132
int *file_dnos;		/* dense nos for files */
133
 
134
filename * fds;
135
int nofds = 0;
136
int szfds = 0;
137
 
138
 
139
#if 0
140
void collect_files
7 7u83 141
(filename f)
2 7u83 142
{
143
  return;
144
}
145
 
146
void OUTPUT_DIAG_TAGS
7 7u83 147
(void)
2 7u83 148
{
149
  return;
150
}
151
#endif
152
 
153
 
154
void collect_files
7 7u83 155
(filename f)
2 7u83 156
{
157
  if (nofds>=szfds) {
7 7u83 158
    fds = (filename*)xrealloc(fds,(size_t)(szfds+=5)*sizeof(filename));
2 7u83 159
  }
160
  fds[nofds++] = f;
161
}
162
 
163
int find_file
7 7u83 164
(filename f)
2 7u83 165
{
166
  int i;
7 7u83 167
  for (i=0; i<nofds; i++) {
168
    if (strcmp(f->file.ints.chars, fds[i] ->file.ints.chars) ==0) return i;
169
  }
2 7u83 170
  return 0;
171
}
172
 
173
 
174
 
175
/* produce symnos for all text files in compilation */
176
void symnosforfiles
7 7u83 177
(void)
2 7u83 178
{
179
  int   i;
7 7u83 180
  file_dnos = (int *)xcalloc(nofds, sizeof(int));
2 7u83 181
  for (i = 0; i < nofds; i++) {
7 7u83 182
    file_dnos[i] = new_lsym_d(fds[i] ->file.ints.chars, 0, stFile, scText,
183
			      (diag_type)0, i);
2 7u83 184
  }
185
  return;
186
}
187
 
188
/* used for testing whether o/p worked */
189
static  void x
7 7u83 190
(int i)
2 7u83 191
{
192
  if (i == EOF) {
7 7u83 193
    failer("can't output");
194
    exit(EXIT_FAILURE);
2 7u83 195
  }
196
  return;
197
}
198
 
199
 
200
/* output .file directive for file i */
201
void stab_file
7 7u83 202
(int i)
2 7u83 203
{
204
  int l;
205
  if (currentfile == i)
206
    return;
207
 
7 7u83 208
  l = (int)strlen(fds[i] ->file.ints.chars);
2 7u83 209
 
210
  if (as_file) {
7 7u83 211
    x(fprintf(as_file, "\t.file\t%d \"%s\"\n", file_dnos[i],
212
		fds[i] ->file.ints.chars+1));
2 7u83 213
  }
214
 
7 7u83 215
  out_value(file_dnos[i], ifile, make_INT64(0,l), 0);
216
  out_data(fds[i] ->file.ints.chars, l);
2 7u83 217
 
218
  currentfile = i;
7 7u83 219
  return;
2 7u83 220
}
221
 
222
int currentlno = -1;		/* the last line number output */
223
 
224
void stabd
7 7u83 225
(int findex, int lno)
2 7u83 226
{
227
  if (findex==currentfile && lno==currentlno) return;
7 7u83 228
  stab_file(findex);
2 7u83 229
  if (as_file)
7 7u83 230
    x(fprintf(as_file, "\t.loc\t%d %d\n", file_dnos[findex], lno));
231
  out_loc(file_dnos[findex],(unsigned)lno);
2 7u83 232
  currentlno = lno;
233
}
234
 
235
static char *lexlev = "0";	/* historic !!! */
236
 
237
 
238
void diagbr_open
7 7u83 239
(int findex)
2 7u83 240
{
241
  int symno;
7 7u83 242
  stab_file(findex);
243
  symno = new_lsym_d((char *)0, 0, stBlock, scText,(diag_type)0,
2 7u83 244
      currentfile);
7 7u83 245
  lexlev[0] ++;
246
  if (as_file) {
247
    x(fprintf(as_file, "\t.bgnb\t%d\n", symno));
2 7u83 248
  }
7 7u83 249
  out_ent(symno, ibgnb, 0);
2 7u83 250
}
251
 
252
void diagbr_close
7 7u83 253
(int findex)
2 7u83 254
{
255
  int symno;
7 7u83 256
  stab_file(findex);
257
  symno = new_lsym_d((char *)0, 0, stEnd, scText,(diag_type)0,
2 7u83 258
      currentfile);
7 7u83 259
  lexlev[0] --;
260
  if (as_file) {
261
    x(fprintf(as_file, "\t.endb\t%d\n", symno));
2 7u83 262
  }
7 7u83 263
  out_ent(symno, iendb, 0);
2 7u83 264
}
265
 
266
 
7 7u83 267
 
268
/*
2 7u83 269
   output appropriate rubbish to symbol table to indicate the declaration of a
270
   local identifier, nm, defined by id, displaced by disp; findex is the index
271
   of the file containing the declaration.  The text below gives o/p for
7 7u83 272
   identifiers allocated in registers; in fact, with current translator,
273
   none are used by stab_local. I don't even know whether the MIPS dbx can
274
   actually use them.
2 7u83 275
*/
276
void stab_local
7 7u83 277
(char *nm, diag_type dt, exp ldid, int disp, int findex)
2 7u83 278
{
7 7u83 279
 
2 7u83 280
  int fs = frame_size >> 3;
281
  exp id = son(ldid);
282
  short   sc;
283
  int  v;
284
  disp+=no(ldid);
7 7u83 285
again:
286
  if (name(id) == ident_tag) {
287
    if ((props(id) & defer_bit) == 0) {
288
      if ((props(id) & inreg_bits)!= 0) {
2 7u83 289
	sc = scRegister;
7 7u83 290
	v = no(id);
2 7u83 291
	/*if (as_file){
292
	  x (fprintf (as_file, " # %s is in $%d\n", nm, v));
293
	  }*/
294
      }
7 7u83 295
      else if ((props(id) & infreg_bits)!= 0) {
2 7u83 296
	sc = scRegister;
7 7u83 297
	v = (no(id) << 1) + float_register;
2 7u83 298
/*	  if (as_file)
299
	  x (fprintf (as_file, " # %s is in $f%d\n", nm, v - float_register));*/
300
      }
301
      else {
7 7u83 302
	v = ((no(id) & ~0x3f) >> 4) + (locals_offset >> 3) + disp / 8 - fs;
2 7u83 303
	sc = scAbs;
304
/*	  if (as_file)
305
	  x (fprintf (as_file,
306
	  " # %s is in %ld($fp)  == %ld($29)\n", nm,
307
	  v, v + fs));*/
7 7u83 308
 
2 7u83 309
      }
310
      (void)new_lsym_d (nm,v,/*(isparam(id))?stParam :*/stLocal,sc,dt,findex);
311
    }
312
    else {
7 7u83 313
      exp sn = son(id);
2 7u83 314
      int d = disp;
315
      while (sn != nilexp) {
316
	switch (name(sn)) {
317
	  case name_tag: {
7 7u83 318
	    disp = d + no(sn);
319
	    id = son(sn);
320
	    if (isvar(id))dt = dt->data.ptr.object;
2 7u83 321
	    goto again;
7 7u83 322
	  }
2 7u83 323
	  case reff_tag: {
7 7u83 324
	    d += no(sn);
325
	    sn = son(sn);
2 7u83 326
	    break;
327
	  }
328
	  case cont_tag: {
7 7u83 329
	    sn = son(sn);
2 7u83 330
	    break;
331
	  }
7 7u83 332
	  default:
2 7u83 333
	  return;
334
	}
335
      }
336
    }
337
  }
338
}
339
 
340
void output_diag
7 7u83 341
(diag_info *d, int proc_no, exp e)
2 7u83 342
{
343
  exp x;
344
  if (d->key == DIAG_INFO_SOURCE) {
345
    sourcemark * s = & d->data.source.beg;
346
    int f = find_file(s->file);
347
    stabd(f, s->line_no.nat_val.small_nat);
348
    return;
349
  }
350
  if (d->key != DIAG_INFO_ID) return;
351
  x = d->data.id_scope.access;
7 7u83 352
  if (isglob(son(x)) || no(son(x)) ==1) return;
2 7u83 353
  /* can't output global values as local names in dbx
354
     && not only diag use */
355
  mark_scope(e);
356
  if (props(e) & 0x80) {
357
    stabd(currentfile, currentlno+1); /* don't have proper lineno */
358
    diagbr_open(currentfile);
359
  }
360
  stab_local(d->data.id_scope.nme.ints.chars, d->data.id_scope.typ,
361
	     x,0,currentfile);
362
  if (last_param(son(x))) {
363
    stabd(currentfile, currentlno+1); /* don't have proper lineno */
7 7u83 364
  }
2 7u83 365
  return;
366
}
367
 
368
 
369
void output_end_scope
7 7u83 370
(diag_info *d, exp e)
2 7u83 371
{
372
  if (d->key == DIAG_INFO_SOURCE) {
373
    sourcemark * s = & d->data.source.end;
374
    int f = find_file(s->file);
7 7u83 375
    int lno = s->line_no.nat_val.small_nat;
2 7u83 376
    stabd(f, (lno==currentlno)?lno+1:lno); /*approx */
377
    return;
7 7u83 378
  }
2 7u83 379
  if (d -> key == DIAG_INFO_ID && props(e) & 0x80) {
380
    diagbr_close(currentfile);
7 7u83 381
  }
382
}
383
 
2 7u83 384
/*
385
  The following procs are concerned with expressing TDF
386
  types as dbx types.  The possible circularity of types and
387
  the vagaries of the type representation contribute to their
388
  complication.
389
*/
390
 
391
typedef struct {
392
  char *n;
393
  int  v;
394
  int   st;
395
  int   sc;
396
  diag_type s;
397
} tsym;
398
static int notsyms = 0;
399
static int nexttsym = 0;
7 7u83 400
static tsym * ats = (tsym *)0;
2 7u83 401
 
402
 
7 7u83 403
/*
404
   used to accumulate all the type reprs arising
405
   from shapes in the program by calling addtsym ....
2 7u83 406
*/
407
void addtsym
7 7u83 408
(char *n, int v, int st, int sc, diag_type s)
2 7u83 409
{
410
  tsym * a;
411
  if (nexttsym >= notsyms) {
7 7u83 412
    ats = (tsym *)xrealloc((void *)ats,(size_t)(nexttsym + 100)* sizeof(tsym));
2 7u83 413
    notsyms = nexttsym + 100;
414
  }
415
  a = &ats[nexttsym++];
416
  a -> n = n;
417
  a -> v = v;
418
  a -> st = st;
419
  a -> sc = sc;
420
  a -> s = s;
421
  return;
422
}
423
 
424
typedef struct {
425
  diag_type sutype;
426
  int   symindex;
427
} shauxt;
428
static int noshaux = 0;
429
int nextshaux = 0;
7 7u83 430
shauxt * shaux = (shauxt *)0;
2 7u83 431
 
432
 
7 7u83 433
/*
434
   used to remember all the indexes into the auxilliary
435
   symbol table for all the shapes in the program
2 7u83 436
*/
437
bool eq_sutype
7 7u83 438
(diag_type a, diag_type b)
2 7u83 439
{
7 7u83 440
 
2 7u83 441
  diag_field_list  fa;
442
  diag_field_list  fb;
7 7u83 443
  int j;
2 7u83 444
  if (a==b) return 1;
445
  if (a->key != b->key) return 0;
446
  if (a->key != DIAG_TYPE_STRUCT && a->key != DIAG_TYPE_UNION) return 0;
447
   if (strcmp(a->data.t_struct.nme.ints.chars, b->data.t_struct.nme.ints.chars))
448
     return 0;
449
  fa = a->data.t_struct.fields;
450
  fb = b->data.t_struct.fields;
451
  if (fa->lastused != fb->lastused) return 0;
7 7u83 452
  for (j=fa->lastused-1; j>=0; j--) {
2 7u83 453
    diag_field sfa = (fa->array)[j];
454
    diag_field sfb = (fb->array)[j];
455
    if (strcmp(sfa->field_name.ints.chars, sfb->field_name.ints.chars))
456
      return 0;
457
  }
7 7u83 458
  return(bool)eq_shape(a->data.t_struct.tdf_shape,b->data.t_struct.tdf_shape);
459
}
2 7u83 460
 
461
 
7 7u83 462
/*
463
   finds the index into the auxilliary table for type s
2 7u83 464
*/
465
int find_aux
7 7u83 466
(diag_type s)
2 7u83 467
{
468
  int   i;
469
  for (i = 0; i < nextshaux; i++) {
7 7u83 470
    if (eq_sutype(s, shaux[i].sutype))
2 7u83 471
      return shaux[i].symindex;
472
  }
473
  return - 1;
474
}
475
 
476
 
7 7u83 477
/*
478
   remembers ind as index into aux table for shape s
2 7u83 479
*/
480
static void addaux
7 7u83 481
(diag_type s, int ind)
2 7u83 482
{
483
 
484
  shauxt * x;
485
  if (nextshaux >= noshaux) {
7 7u83 486
    shaux = (shauxt *)xrealloc((void *)shaux,
487
				(size_t)(nextshaux + 10)* sizeof(shauxt));
2 7u83 488
  }
489
  x = &shaux[nextshaux++];
490
  x -> sutype = s;
491
  x -> symindex = ind;
492
}
493
 
494
static diag_tagdef ** su_diags = (diag_tagdef**)0;
495
static long no_of_sus = 0;
496
static long leng_sus = 0;
497
 
498
void OUTPUT_DIAG_TAGS
7 7u83 499
(void)
2 7u83 500
{
7 7u83 501
  /*collects structs & unions */
2 7u83 502
  diag_tagdef ** di = unit_ind_diagtags;
503
  long n = unit_no_of_diagtags;
504
  long i;
505
  long il = no_of_sus;
506
 
7 7u83 507
  for (i=0; i<n; ++i) {
508
    diag_type d = di[i] ->d_type;
509
    switch (d -> key) {
2 7u83 510
      case DIAG_TYPE_STRUCT:
511
      case DIAG_TYPE_UNION: {
512
	int j;
7 7u83 513
	for (j=0; j < il; j++) {
514
	  if (eq_sutype(d, su_diags[j] ->d_type))break;
2 7u83 515
	}
7 7u83 516
	if (j!=il)break;
2 7u83 517
	if (no_of_sus >= leng_sus) {
7 7u83 518
	  su_diags = (diag_tagdef**)xrealloc(su_diags,
519
				(size_t)(leng_sus+=20)*sizeof(diag_tagdef*));
520
	}
2 7u83 521
	su_diags[no_of_sus++] = di[i];
522
	break;
7 7u83 523
      }
2 7u83 524
      default: break;
525
    }
7 7u83 526
  }
2 7u83 527
  return;
528
}
529
 
530
 
531
 
7 7u83 532
/*
533
   outputs symbol table info for all struct & union  in program
2 7u83 534
*/
535
void stab_types
7 7u83 536
(void)
2 7u83 537
{
538
  int i;
7 7u83 539
  int firsts = get_sym_index(mainfile);
2 7u83 540
  for (i = 0; i < no_of_sus; ++i) {/* treat struct shapes */
541
    int   j;
542
    diag_tagdef * sc = su_diags[i];
543
    switch (sc->d_type->key) {
7 7u83 544
      case DIAG_TYPE_STRUCT:
2 7u83 545
      case DIAG_TYPE_UNION: {
546
	diag_field_list  fields = sc->d_type->data.t_struct.fields;
547
	shape s = sc->d_type->data.t_struct.tdf_shape;
548
	char * nme = sc->d_type->data.t_struct.nme.ints.chars;
549
	addaux(sc->d_type, nexttsym+firsts);
7 7u83 550
	addtsym(nme, shape_size(s) >>3, stBlock, scInfo, sc->d_type);
551
	for (j=fields->lastused-1; j>=0; j--) {
2 7u83 552
	  diag_field sf = (fields->array)[j];
7 7u83 553
	  addtsym(sf->field_name.ints.chars, no(sf->where), stMember, scInfo,
554
		  sf->field_type);
2 7u83 555
	}
556
	break;
557
      }
7 7u83 558
      default:;
559
    }
560
    addtsym("", 0, stEnd, scInfo,(diag_type)0);
2 7u83 561
  }
562
 
563
  for (i = 0; i < nexttsym; i++) {/* output accumulated type info */
564
    tsym * t = &ats[i];
7 7u83 565
   (void)new_lsym(t -> n, t -> v, t -> st, t -> sc, t->s, mainfile);
2 7u83 566
  }
567
 
568
  for (i = 0; i < unit_diagvar_tab.lastused; ++i) {
569
  /* associated names of types */
570
    diag_descriptor * dd = unit_diagvar_tab.array+i;
571
    if (dd->key == DIAG_TYPEDEF_KEY) {
7 7u83 572
     (void)new_lsym_d(dd->data.typ.nme.ints.chars, 0, stTypedef, scInfo,
573
		       dd->data.typ.new_type, mainfile);
2 7u83 574
    }
575
  }
7 7u83 576
  free(ats);
2 7u83 577
  return;
578
}
579
 
580
 
581
 
582
 
583
 
584
 
585