Subversion Repositories tendra.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/**********************************************************************
32
$Author: release $
33
$Date: 1998/02/04 10:43:43 $
34
$Revision: 1.2 $
35
$Log: mipsdiags.c,v $
36
 * Revision 1.2  1998/02/04  10:43:43  release
37
 * Changes during testing.
38
 *
39
 * Revision 1.1.1.1  1998/01/17  15:56:06  release
40
 * First version to be checked into rolling release.
41
 *
42
 * Revision 1.3  1995/09/12  10:59:34  currie
43
 * gcc pedanttry
44
 *
45
 * Revision 1.2  1995/08/16  16:06:54  currie
46
 * Shortened some .h names
47
 *
48
 * Revision 1.1  1995/04/13  09:08:06  currie
49
 * Initial revision
50
 *
51
***********************************************************************/
52
 
53
/*****************************************************************
54
 
55
                           mipsdiags.c
56
 
57
Provides the routines for outputting diagnostic information, suitable for
58
MIPS dbx.
59
These diagnostics, in the absence of any documentation, have been
60
produced in a suck-it-and-see mode, but they are vaguely based
61
around the syms modules provided in the system library.
62
 
63
 
64
********************************************************************/
65
#include "config.h"
66
#include "cross_config.h"
67
 
68
#ifndef CROSS_INCLUDE
69
#include <symconst.h>
70
#else
71
#include CROSS_INCLUDE/symconst.h>
72
#endif
73
 
74
#include "common_types.h"
75
#include "symtab.h"
76
#include "exptypes.h"
77
#include "shapemacs.h"
78
#include "expmacs.h"
79
#include "exp.h"
80
#include "procrectypes.h"
81
#include "tags.h"
82
#include "bitsmacs.h"
83
#include "diagtypes.h"
84
#include "xalloc.h"
85
#include "ibinasm.h"
86
#include "out_ba.h"
87
#include "syms.h"
88
#include "diag_fns.h"
89
#include "locate.h"
90
#include "mipsdiags.h"
91
#include "diagglob.h"
92
#include "mark_scope.h"
93
#include "basicread.h"
94
#include "new_code.h"
95
#include "new_symbol.h"
96
 
97
extern  FILE * as_file;
98
 
99
extern long currentfile;
100
 /* our current fileno  */
101
extern long mainfile;
102
 /* default fileno for no diags or shape output */
103
extern long fscopefile;		/* file of currect proc */
104
 
105
 
106
int  *file_dnos;		/* dense nos for files */
107
 
108
filename * fds;
109
int nofds = 0;
110
int szfds = 0;
111
 
112
void collect_files
113
    PROTO_N ( (f) )
114
    PROTO_T ( filename f )
115
{
116
	if (nofds>=szfds) {
117
		fds = (filename*)xrealloc(fds, (szfds+=5)*sizeof(filename));
118
	}
119
	fds[nofds++] = f;
120
}
121
 
122
int find_file
123
    PROTO_N ( (f) )
124
    PROTO_T ( char * f )
125
{
126
   int i;
127
   for(i=0; i<nofds; i++) {
128
   	if (strcmp(f, fds[i]->file.ints.chars)==0) return i;
129
   }
130
   return 0;
131
}
132
 
133
void symnosforfiles
134
    PROTO_Z ()
135
{	/* produce symnos for all text files in compilation */
136
  int   i;
137
  file_dnos = (int *) xcalloc (nofds, sizeof (int));
138
  for (i = 0; i < nofds; i++) {
139
    file_dnos[i] = new_lsym_d (fds[i]->file.ints.chars, 0, stFile, scText, (diag_type)0, i);
140
  }
141
 
142
}
143
 
144
static void x
145
    PROTO_N ( (i) )
146
    PROTO_T ( int i )
147
{
148
  if (i == EOF) {
149
    failer ("can't output");
150
    exit (EXIT_FAILURE);
151
  };
152
  return;
153
}
154
 
155
void stab_file
156
    PROTO_N ( (i) )
157
    PROTO_T ( int i )
158
{	/* output .file directive for file i */
159
  int   l;
160
  if (currentfile == i)
161
    return;
162
  l = strlen (fds[i]->file.ints.chars);
163
  if (as_file) {
164
    x (fprintf (as_file, "\t.file\t%d \"%s\"\n", file_dnos[i], fds[i]->file.ints.chars));
165
  }
166
  out_value (file_dnos[i], ifile, l, 0);
167
  out_data (fds[i]->file.ints.chars, l);
168
  currentfile = i;
169
}
170
 
171
long  currentlno = -1;		/* the last line number output */
172
 
173
void stabd (findex, lno)	/* output .loc directive */
174
long  findex,
175
      lno;
176
{
177
  if (findex==currentfile && lno==currentlno) return;
178
  stab_file (findex);
179
  if (as_file)
180
    x (fprintf (as_file, "\t.loc\t%d %ld\n", file_dnos[findex], lno));
181
  out_loc (file_dnos[findex], lno);
182
  currentlno = lno;
183
}
184
 
185
static char *lexlev = "0";	/* historic !!! */
186
 
187
void diagbr_open
188
    PROTO_N ( (findex) )
189
    PROTO_T ( long findex )
190
{/* block begin directive */
191
  int   symno;
192
  stab_file (findex);
193
  symno = new_lsym_d ((char *) 0, 0, stBlock, scText, (diag_type)0,
194
      currentfile);
195
  lexlev[0]++;
196
  if (as_file)
197
    x (fprintf (as_file, "\t.bgnb\t%d\n", symno));
198
  out_ent (symno, ibgnb, 0);
199
}
200
 
201
void diagbr_close
202
    PROTO_N ( (findex) )
203
    PROTO_T ( long findex )
204
{/* block end directive */
205
  int   symno;
206
  stab_file (findex);
207
  symno = new_lsym_d ((char *) 0, 0, stEnd, scText, (diag_type)0,
208
      currentfile);
209
  lexlev[0]--;
210
  if (as_file)
211
    x (fprintf (as_file, "\t.endb\t%d\n", symno));
212
  out_ent (symno, iendb, 0);
213
}
214
 
215
 
216
void stab_local
217
    PROTO_N ( (nm, dt, ldid, disp, findex) )
218
    PROTO_T ( char *nm X diag_type dt X exp ldid X long disp X long findex )
219
{
220
                            /* output appropriate rubbish to symbol
221
                               table to indicate the declaration of a
222
                               local identifier, nm, defined by id,
223
                               displaced by disp; findex is the index
224
                               of the file containing the declaration.
225
                                The text below gives o/p for
226
                               identifiers allocated in registers; in
227
                               fact, with current translator, none are
228
                               used by stab_local. I don't even know
229
                               whether the MIPS dbx can actually use
230
                               them. */
231
  long  fs = frame_size >> 3;
232
  exp id = son(ldid);
233
  short   sc;
234
  long  v;
235
  disp+=no(ldid);
236
again:
237
  if (name (id) == ident_tag) {
238
    if ((props (id) & defer_bit) == 0) {
239
      if ((props (id) & inreg_bits) != 0) {
240
	sc = scRegister;
241
	v = no (id);
242
	if (as_file)
243
	  x (fprintf (as_file, " # %s is in $%ld\n", nm, v));
244
      }
245
      else
246
	if ((props (id) & infreg_bits) != 0) {
247
	  sc = scRegister;
248
	  v = (no (id) << 1) + float_register;
249
	  if (as_file)
250
	    x (fprintf (as_file, " # %s is in $f%ld\n", nm, v - float_register));
251
	}
252
	else {
253
	  v = ((no (id) & ~0x3f) >> 4) + (locals_offset >> 3) + disp / 8 - fs;
254
	  sc = scAbs;
255
	  if (as_file)
256
	    x (fprintf (as_file,
257
		  " # %s is in %ld($fp)  == %ld($29)\n", nm,
258
		  v, v + fs));
259
 
260
	}
261
      IGNORE new_lsym_d (nm, v, (isparam(id))?stParam :stLocal, sc, dt, findex);
262
    }
263
    else {
264
      exp sn = son (id);
265
      long  d = disp;
266
      while (sn != nilexp) {
267
	switch (name(sn)) {
268
	  case name_tag:
269
	    {
270
	      disp = d + no (sn);
271
	      id = son (sn);
272
	      if (isvar (id)) dt = dt->data.ptr.object;
273
	      goto again;
274
	    }
275
	  case reff_tag: {
276
	      d += no (sn);
277
	      sn = son (sn);
278
	      break;
279
	    }
280
	  case cont_tag: {
281
	      sn = son (sn);
282
	      break;
283
	    }
284
	  default:
285
	    return;
286
	    }
287
      }
288
    }
289
  }
290
 
291
}
292
 
293
void output_diag
294
    PROTO_N ( (d, proc_no, e) )
295
    PROTO_T ( diag_info *d X int proc_no X exp e )
296
{
297
    exp x;
298
    if (d->key == DIAG_INFO_SOURCE) {
299
    	sourcemark * s = & d->data.source.beg;
300
    	int f = find_file(s->file->file.ints.chars);
301
    	stabd(f, s->line_no.nat_val.small_nat);
302
	return;
303
    }
304
    if (d->key != DIAG_INFO_ID) return;
305
    x = d->data.id_scope.access;
306
    if (isglob(son(x)) || no(son(x))==1) return;
307
    	    /* can't output global values as local names in dbx
308
    	         && not only diag use */
309
    mark_scope(e);
310
    if (props(e) & 0x80) {
311
    	stabd(currentfile, currentlno+1); /* don't have proper lineno */
312
    	diagbr_open(currentfile);
313
    }
314
 
315
    stab_local(d->data.id_scope.nme.ints.chars, d->data.id_scope.typ,
316
                    x,0,currentfile);
317
    if (last_param(son(x))) {
318
   	stabd(currentfile, currentlno+1); /* don't have proper lineno */
319
    }
320
 
321
}
322
 
323
void output_end_scope
324
    PROTO_N ( (d, e) )
325
    PROTO_T ( diag_info *d X exp e )
326
{
327
    if (d->key == DIAG_INFO_SOURCE) {
328
    	sourcemark * s = & d->data.source.end;
329
    	int f = find_file(s->file->file.ints.chars);
330
    	long lno = s->line_no.nat_val.small_nat;
331
    	stabd(f, lno);
332
	return;
333
    }
334
    if (d -> key == DIAG_INFO_ID && props(e) & 0x80) {
335
    	diagbr_close(currentfile);
336
    }
337
}
338
 
339
/****************************************************************
340
	The following procs are concerned with expressing TDF
341
	types as dbx types.  The possible circularity of types and
342
	the vagaries of the type representation contribute to their
343
	complication.
344
****************************************************************/
345
 
346
typedef struct {
347
  char *n;
348
  long  v;
349
  int   st;
350
  int   sc;
351
  diag_type s;
352
}               tsym;
353
static int  notsyms = 0;
354
static int  nexttsym = 0;
355
static  tsym * ats = (tsym *) 0;
356
 /* used to accumulate all the type reprs arising from shapes in the
357
    program by calling addtsym .... */
358
 
359
void addtsym
360
    PROTO_N ( (n ,v, st, sc, s) )
361
    PROTO_T ( char *n X long v X int st X int sc X diag_type s )
362
{
363
  tsym * a;
364
  if (nexttsym >= notsyms) {
365
    ats = (tsym *) xrealloc ((char *) ats, (nexttsym + 100) * sizeof (tsym));
366
    notsyms = nexttsym + 100;
367
  }
368
  a = &ats[nexttsym++];
369
  a -> n = n;
370
  a -> v = v;
371
  a -> st = st;
372
  a -> sc = sc;
373
  a -> s = s;
374
  return;
375
}
376
 
377
typedef struct {
378
  diag_type sutype;
379
  int   symindex;
380
}               shauxt;
381
static int  noshaux = 0;
382
int   nextshaux = 0;
383
shauxt * shaux = (shauxt *) 0;
384
 /* used to remember all the indexes into the auxilliary symbol table for
385
    all the shapes in the program */
386
 
387
bool eq_sutype
388
    PROTO_N ( (a, b) )
389
    PROTO_T ( diag_type a X diag_type b )
390
{
391
   diag_field_list  fa;
392
   diag_field_list  fb;
393
   int j;
394
   if (a==b) return 1;
395
   if (a->key != b->key) return 0;
396
   if (a->key != DIAG_TYPE_STRUCT && a->key != DIAG_TYPE_UNION) return 0;
397
   if (strcmp(a->data.t_struct.nme.ints.chars, b->data.t_struct.nme.ints.chars))
398
   	return 0;
399
   fa = a->data.t_struct.fields;
400
   fb = b->data.t_struct.fields;
401
   if (fa->lastused != fb->lastused) return 0;
402
   for(j=fa->lastused-1; j>=0; j--) {
403
       diag_field sfa = (fa->array)[j];
404
       diag_field sfb = (fb->array)[j];
405
       if (strcmp(sfa->field_name.ints.chars, sfb->field_name.ints.chars))
406
       		return 0;
407
   }
408
   return eq_shape(a->data.t_struct.tdf_shape, b->data.t_struct.tdf_shape);
409
}
410
 
411
long  find_aux
412
    PROTO_N ( (s) )
413
    PROTO_T ( diag_type s /* struct or union shape */ )
414
{
415
				/* finds the index into the auxilliary
416
				   table for type s */
417
  int   i;
418
  for (i = 0; i < nextshaux; i++) {
419
    if (eq_sutype(s, shaux[i].sutype) )
420
      return shaux[i].symindex;
421
  }
422
  return - 1;
423
}
424
 
425
static  void addaux
426
    PROTO_N ( (s, ind) )
427
    PROTO_T ( diag_type s X int ind )
428
{
429
				/* remembers ind as index into aux table
430
				   for shape s */
431
          shauxt * x;
432
  if (nextshaux >= noshaux) {
433
    shaux =
434
      (shauxt *) xrealloc ((char *) shaux, (nextshaux + 10) * sizeof (shauxt));
435
  }
436
  x = &shaux[nextshaux++];
437
  x -> sutype = s;
438
  x -> symindex = ind;
439
}
440
 
441
static diag_tagdef ** su_diags = (diag_tagdef**)0;
442
static long no_of_sus = 0;
443
static long leng_sus = 0;
444
 
445
void OUTPUT_DIAG_TAGS
446
    PROTO_Z ()
447
{
448
  diag_tagdef ** di = unit_ind_diagtags;
449
  unsigned long n = unit_no_of_diagtags;
450
  long i;
451
  long il = no_of_sus;
452
 
453
  for (i=0; i<n; ++i)
454
   {
455
     diag_type d = di[i]->d_type;
456
     switch (d -> key)
457
      {
458
        case DIAG_TYPE_STRUCT:
459
        case DIAG_TYPE_UNION: {
460
            int j;
461
            for(j=0; j < il; j++) {
462
               if (eq_sutype(d, su_diags[j]->d_type)) break;
463
            }
464
            if (j!=il) break;
465
	    if (no_of_sus >= leng_sus) {
466
	    	su_diags = (diag_tagdef**)xrealloc(su_diags,
467
	    			(leng_sus+=20)*sizeof(diag_tagdef*) );
468
	    }
469
	    su_diags[no_of_sus++] = di[i];
470
            break;
471
        }
472
        default: break;
473
      };
474
   };
475
  return;
476
}
477
 
478
 
479
void stab_types
480
    PROTO_Z ()
481
{		/* outputs symbol table info for all
482
		   struct & union  in program */
483
  int   i;
484
  int   firsts = get_sym_index (mainfile);
485
 
486
  for (i = 0; i < no_of_sus; ++i) {/* treat struct shapes */
487
    int   j;
488
    diag_tagdef * sc = su_diags[i];
489
    switch (sc->d_type->key) {
490
    	case DIAG_TYPE_STRUCT: case DIAG_TYPE_UNION: {
491
    	   diag_field_list  fields = sc->d_type->data.t_struct.fields;
492
    	   shape s = sc->d_type->data.t_struct.tdf_shape;
493
    	   char * nme = sc->d_type->data.t_struct.nme.ints.chars;
494
    	   addaux(sc->d_type, nexttsym+firsts);
495
    	   addtsym(nme, shape_size(s)>>3, stBlock, scInfo, sc->d_type);
496
    	   for(j=fields->lastused-1; j>=0; j--) {
497
    	   	diag_field sf = (fields->array)[j];
498
    	   	addtsym(sf->field_name.ints.chars, no(sf->where), stMember, scInfo, sf->field_type);
499
    	   }
500
    	   break;
501
    	}
502
    	default: ;
503
    }
504
    addtsym ("", 0, stEnd, scInfo, (diag_type)0);
505
  }
506
 
507
  for (i = 0; i < nexttsym; i++) {/* output accumulated type info */
508
    tsym * t = &ats[i];
509
    {
510
      IGNORE new_lsym (t -> n, t -> v, t -> st, t -> sc, t->s, mainfile);
511
    }
512
  }
513
 
514
  for (i = 0; i < unit_diagvar_tab.lastused; ++i) {/* associated names of types */
515
	diag_descriptor * dd = unit_diagvar_tab.array+i;
516
	if (dd->key == DIAG_TYPEDEF_KEY) {
517
	   IGNORE new_lsym_d(dd->data.typ.nme.ints.chars, 0, stTypedef, scInfo,
518
	   			dd->data.typ.new_type, mainfile);
519
	}
520
  }
521
  xfree (ats);
522
  return;
523
}