Pristine Ack-5.5
[Ack-5.5.git] / util / grind / db_symtab.g
1 /* $Id: db_symtab.g,v 1.13 1994/06/24 10:59:34 ceriel Exp $ */
2
3 /* Symbol table reader
4 */
5
6 {
7 #include        <alloc.h>
8 #include        <stb.h>
9 #include        <assert.h>
10
11 #include        "position.h"
12 #include        "file.h"
13 #include        "type.h"
14 #include        "symbol.h"
15 #include        "scope.h"
16 #include        "class.h"
17 #include        "idf.h"
18 #include        "rd.h"
19 #include        "misc.h"
20
21 extern char     *strindex();
22 extern long     str2long();
23 extern double   atof();
24
25 static char     *DbPtr;                 /* current pointer in db string */
26 static int      AllowName;              /* set if NAME legal at this point */
27 static long     ival;
28 static double   fval;
29 static char     *strval;
30 static int      last_index[2];
31 static struct outname   *currnam;
32 static int      saw_code;
33
34 static struct literal *get_literal_space();
35 static struct fields *get_field_space();
36 static end_field();
37 static char *string_val();
38 }
39
40 %start DbParser, debugger_string;
41
42 %prefix DBS;
43
44 %lexical DBSlex;
45
46 %onerror DBSonerror;
47
48 %token  INTEGER, REAL, STRING, NAME;
49
50 debugger_string
51   { register p_symbol s;
52     char *str;
53     p_type tmp = 0;
54     int upb = 0;
55   }
56 :
57   name(&str)
58   [ /* constant name */
59                         { s = NewSymbol(str, CurrentScope, CONST, currnam); }
60         'c' const_name(s)
61
62   | /* type name */
63                         { s = NewSymbol(str, CurrentScope, TYPE, currnam); }
64         't' type_name(&(s->sy_type), s)
65                         { if (! s->sy_type->ty_sym) s->sy_type->ty_sym = s; 
66                           if ((s->sy_type->ty_class == T_ENUM ||
67                                s->sy_type->ty_class == T_SUBRANGE) &&
68                               currnam->on_desc != 0) {
69                                 s->sy_type->ty_size = currnam->on_desc;
70                           }
71                         }
72   | /* tag name (only C?) */
73                         { s = NewSymbol(str, CurrentScope, TAG, currnam); }
74         'T' type_name(&(s->sy_type), s)
75                         { if (! s->sy_type->ty_sym) s->sy_type->ty_sym = s; 
76                           if (s->sy_type->ty_class != T_CROSS) {
77                                 resolve_cross(s->sy_type);
78                           }
79                         }
80   | /* end scope */
81         'E' INTEGER
82                         { close_scope(); }
83
84   | /* module begin */
85                         { s = NewSymbol(str, CurrentScope, MODULE, currnam); }
86         'M' INTEGER
87                         { open_scope(s, 1);
88                           s->sy_name.nm_scope = CurrentScope;
89                           CurrentScope->sc_start = currnam->on_valu;
90                           CurrentScope->sc_proclevel = currnam->on_desc;
91                           add_scope_addr(CurrentScope);
92                         }
93
94   | /* external procedure */
95                         { s = NewSymbol(str, FileScope, PROC, currnam); }
96         'P' routine(s)
97
98   | /* private procedure */
99                         { s = NewSymbol(str, CurrentScope, PROC, currnam); }
100         'Q' routine(s)
101
102   | /* external function */
103                         { s = NewSymbol(str, FileScope, FUNCTION, currnam); }
104         'F' function(s)
105
106   | /* private function */
107                         { s = NewSymbol(str, CurrentScope, FUNCTION, currnam); }
108         'f' function(s)
109
110   | /* global variable, external */
111                                 /* maybe we already know it; but we need
112                                    the type information anyway for other
113                                    types.
114                                 */
115                         { s = Lookup(findidf(str), FileScope, VAR);
116                           if (s) {
117                                 tmp = s->sy_type;
118                                 s->sy_type = 0;
119                           } else s = NewSymbol(str, FileScope, VAR, currnam);
120                         }
121         'G' type(&(s->sy_type), (int *) 0, s)
122                         { if (tmp) s->sy_type = tmp; } 
123
124   | /* static variable */
125                         { s = NewSymbol(str, CurrentScope, VAR, currnam); }
126         'S' type(&(s->sy_type), (int *) 0, s)
127
128   | /* static variable, local scope */
129                         { s = NewSymbol(str, CurrentScope, VAR, currnam); }
130         'V' type(&(s->sy_type), (int *) 0, s)
131
132   | /* register variable */
133                         { s = NewSymbol(str, CurrentScope, REGVAR, currnam); }
134         'r' type(&(s->sy_type), (int *) 0, s)
135
136   | /* value parameter */
137                         { s = NewSymbol(str, CurrentScope, LOCVAR, currnam); }
138         'p' type(&(s->sy_type), (int *) 0, s)
139                         { add_param_type('p', s); }
140
141   | /* value parameter but address passed */
142                         { s = NewSymbol(str, CurrentScope, VARPAR, currnam); }
143         'i' type(&(s->sy_type), (int *) 0, s)
144                         { add_param_type('i', s); }
145
146   | /* variable parameter */
147                         { s = NewSymbol(str, CurrentScope, VARPAR, currnam); }
148         'v' type(&(s->sy_type), (int *) 0, s)
149                         { add_param_type('v', s); }
150
151   | /* local variable */
152                         { s = NewSymbol(str, CurrentScope, LOCVAR, currnam); }
153         type_name(&(s->sy_type), s)
154
155   | /* lower or upper bound of array descriptor */
156         [ 'A'           { upb = LBOUND; }
157         | 'Z'           { upb = UBOUND; }
158         ]
159         [ ['p' | ]      { s = NewSymbol(str, CurrentScope, LOCVAR, currnam);
160                           if (upb == UBOUND) add_param_type('Z', s);
161                         }
162         | [ 'V' | 'S' ] { s = NewSymbol(str, CurrentScope, VAR, currnam); }
163         ]
164         type_name(&(s->sy_type), s)
165                         { p_symbol s1 = new_symbol();
166                           *s1 = *s;
167                           s->sy_class = upb;
168                           s->sy_descr = s1;
169                         }
170
171   | /* function result in Pascal; ignore ??? */
172                         { s = NewSymbol(str, CurrentScope, LOCVAR, currnam); }
173         'X' type_name(&(s->sy_type), s)
174   ]
175   ';'?
176 ;
177
178 name(char **s;)
179 :
180   /* anything up to a ':' */
181   NAME  { *s = strval; }
182 ;
183
184 const_name(p_symbol cst;)
185   { int type_index[2];
186     long iconst;
187     register char *p;
188   }
189 :
190   '='
191   [
192 /*
193         'b' integer_const(&(cst->sy_const.co_ival))     /* boolean */
194 /*  |
195 */
196         'c' integer_const(&(cst->sy_const.co_ival))     /* character */
197                                 { cst->sy_type = char_type; }
198   |
199         'i' integer_const(&(cst->sy_const.co_ival))     /* integer */
200                                 { cst->sy_type = long_type; }
201   |
202         'r' real_const(&(cst->sy_const.co_rval))        /* real */
203                                 { cst->sy_type = double_type; }
204   |
205         's' string_const                                /* string */
206                                 { cst->sy_const.co_sval = string_val(strval);
207                                   cst->sy_type = string_type;
208                                 }
209   |
210         'e' type_index(type_index) ',' integer_const(&(cst->sy_const.co_ival))
211                                 /* enumeration constant;
212                                  * enumeration type, value
213                                  */
214                                 { cst->sy_type = *tp_lookup(type_index); }
215                                 
216   |
217         'S' type_index(type_index)
218                                 { cst->sy_type = *tp_lookup(type_index);
219                                   cst->sy_const.co_setval = p =
220                                     Malloc((unsigned) cst->sy_type->ty_size);
221                                 }
222         [ ',' integer_const(&iconst)
223                                 { *p++ = iconst; }
224         ]+
225                                 /* set constant:
226                                  *  settype, values of the bytes
227                                  *  in the set.
228                                  */
229   ]
230 ;
231
232 integer_const(long *iconst;)
233   { int sign = 0; }
234 :
235   [ '+' | '-' { sign = 1; } ]?
236   INTEGER                       { *iconst = sign ? -ival : ival; }
237 ;
238
239 real_const(double *f;)
240   { int sign = 0; }
241 :
242   [ '+' | '-' { sign = 1; } ]?
243   REAL                          { *f = sign ? fval : -fval; }
244 ;
245
246 string_const
247 :
248   STRING                        /* has SINGLE quotes! */
249 ;
250
251 type_name(p_type *t; p_symbol sy;)
252   { int type_index[2]; p_type *p; }
253 :
254   type_index(type_index)        { p = tp_lookup(type_index); }
255   [
256                                 { if (*p && (*p)->ty_class != 0 &&
257                                       (*p)->ty_class != T_CROSS) {
258                                         error("Redefining (%d,%d) %d",
259                                           type_index[0],
260                                           type_index[1],
261                                           (*p)->ty_class);
262                                   }
263                                 }
264         '='                     
265         type(p, type_index, sy)
266   |
267                                 { if (*t && ! *p) *p = *t; 
268                                   else if (*t) **t = **p;
269                                 }
270   ]
271                                 { if (*p == 0) *p = new_type();
272                                   *t = *p;
273                                 }
274 ;
275
276 type_index(int *type_index;)
277 :
278 [
279   INTEGER                       { type_index[0] = 0; type_index[1] = ival; }
280 |
281   '(' INTEGER                   { type_index[0] = ival; }
282   ',' INTEGER                   { type_index[1] = ival; }
283   ')'
284 ]
285                                 { last_index[0] = type_index[0];
286                                   last_index[1] = type_index[1];
287                                 }
288 ;
289
290 function(p_symbol p;)
291 :
292                         { p->sy_type = new_type();
293                           p->sy_type->ty_class = T_PROCEDURE;
294                           p->sy_type->ty_size = pointer_size;
295                         }
296   type(&(p->sy_type->ty_retval), (int *) 0, (p_symbol) 0) 
297                         { if (CurrentScope != FileScope &&
298                               saw_code) {
299                                 /* if saw_code is not set, it is a nested
300                                    procedure
301                                 */
302                                 close_scope();
303                           }
304                           saw_code = 0;
305                           open_scope(p, 1);
306                           p->sy_name.nm_scope = CurrentScope;
307                           CurrentScope->sc_start = currnam->on_valu;
308                           add_scope_addr(CurrentScope);
309                           CurrentScope->sc_proclevel = currnam->on_desc;
310                         }
311 ;
312
313 routine(p_symbol p;)
314 :
315                         { p->sy_type = new_type();
316                           p->sy_type->ty_class = T_PROCEDURE;
317                           p->sy_type->ty_size = pointer_size;
318                           if (CurrentScope != FileScope &&
319                               saw_code) {
320                                 /* if saw_code is not set, it is a nested
321                                    procedure
322                                 */
323                                 close_scope();
324                           }
325                           saw_code = 0;
326                           open_scope(p, 1);
327                           p->sy_name.nm_scope = CurrentScope;
328                           CurrentScope->sc_start = currnam->on_valu;
329                           add_scope_addr(CurrentScope);
330                           CurrentScope->sc_proclevel = currnam->on_desc;
331                         }
332   INTEGER ';'
333   type(&(p->sy_type->ty_retval), (int *) 0, (p_symbol) 0) 
334 ;
335
336 type(p_type *ptp; int *type_index; p_symbol sy;)
337   { register p_type tp = *ptp ? *ptp : new_type();
338     p_type t1 = 0, t2 = 0;
339     long ic1, ic2;
340     int A_used = 0;
341     int tclass;
342     int tp_index[2];
343     char *str;
344   }
345 :
346   [
347         /* type cross reference */
348         /* these are used in C for references to a struct, union or
349          * enum that has not been declared (yet)
350          */
351         'x'
352         [ 's'   /* struct */
353                         { tclass = T_STRUCT; }
354         | 'u'   /* union */
355                         { tclass = T_UNION; }
356         | 'e'   /* enum */
357                         { tclass = T_ENUM; }
358         ]
359                         { AllowName = 1; }
360         name(&str)
361                         { sy = Lookfromscope(str2idf(str,0),TAG,CurrentScope);
362                           if (sy && 
363                               (sy->sy_type->ty_class == tclass ||
364                                sy->sy_type->ty_class == T_CROSS)) {
365                                 if (tp != *ptp) free_type(tp);
366                                 tp = sy->sy_type;
367                           }
368                           else {
369                                 tp->ty_class = T_CROSS;
370                                 tp->ty_size = tclass;
371                                 sy = NewSymbol(str, CurrentScope, TAG, (struct outname *) 0);
372                                 sy->sy_type = tp;
373                           }
374                         }
375   |
376         /* subrange */
377         /* the integer_const's represent the lower and the upper bound.
378          * A subrange type defined as subrange of itself is an integer type.
379          * If the second integer_const == 0, but the first is not, we
380          * have a floating point type with size equal to the first
381          * integer_const.
382          * Upperbound -1 means unsigned int or unsigned long.
383          */
384         'r' type_index(tp_index) ';'
385         [ 'A' integer_const(&ic1)       { A_used = 1; }
386         | integer_const(&ic1)
387         ]
388         ';'
389         [ 'A' integer_const(&ic2)       { A_used |= 2; }
390         | integer_const(&ic2)
391         | 'Z' integer_const(&ic2)       { A_used |= 0200; }
392         ]
393                         { if (tp != *ptp) free_type(tp);
394                           tp = subrange_type(A_used,
395                                                tp_index,
396                                                ic1,
397                                                ic2,
398                                                type_index);
399                         }
400   |
401         /* array; first type is bound type, next type
402          * is element type
403          */
404         'a' type(&t1, (int *) 0, (p_symbol) 0) ';' type(&t2, (int *) 0, (p_symbol) 0)
405                         { if (tp != *ptp) free_type(tp);
406                           tp = array_type(t1, t2); 
407                         }
408   |
409         /* structure type */
410         's'             { tp->ty_class = T_STRUCT; }
411         structure_type(tp, sy)
412   |
413         /* union type */
414         'u'             { tp->ty_class = T_UNION; }
415         structure_type(tp, sy)
416   |
417         /* enumeration type */
418         'e'             { tp->ty_class = T_ENUM; }
419         enum_type(tp)
420   |
421         /* pointer type */
422         '*'             { tp->ty_class = T_POINTER;
423                           tp->ty_size = pointer_size;
424                         }
425         type(&(tp->ty_ptrto), (int *) 0, (p_symbol) 0)
426   |
427         /* function type */
428         'f'             { tp->ty_class = T_PROCEDURE;
429                           tp->ty_size = pointer_size;
430                         }
431         type(&(tp->ty_retval), (int *) 0, (p_symbol) 0) 
432 /*
433         [ %prefer
434                 ',' param_list(tp)
435         |
436         ]
437 */
438   |
439         /* procedure type */
440         'Q'             { tp->ty_class = T_PROCEDURE;
441                           tp->ty_size = pointer_size;
442                         }
443         type(&(tp->ty_retval), (int *) 0, (p_symbol) 0) 
444         ',' param_list(tp)
445   |
446         /* another procedure type */
447         'p'             { tp->ty_class = T_PROCEDURE;
448                           tp->ty_size = pointer_size;
449                           tp->ty_retval = void_type;
450                         }
451         param_list(tp)
452   |
453         /* set type */
454         /* the first integer_const represents the size in bytes,
455          * the second one represents the low bound
456          */
457         'S'             { tp->ty_class = T_SET; }
458         type(&(tp->ty_setbase), (int *) 0, (p_symbol) 0) ';'
459         [
460                 integer_const(&(tp->ty_size)) ';'
461                 integer_const(&(tp->ty_setlow)) ';'
462         |
463                         { set_bounds(tp); }
464         ]
465   |
466         /* file type of Pascal */
467         'L'             { tp->ty_class = T_FILE; }
468         type(&(tp->ty_fileof), (int *) 0, (p_symbol) 0)
469   |
470         type_name(ptp, (p_symbol) 0)
471                         { if (type_index &&
472                               (*ptp)->ty_class == 0 &&
473                               type_index[0] == last_index[0] &&
474                               type_index[1] == last_index[1]) {
475                                 **ptp = *void_type;
476                                 if (*ptp != tp) free_type(tp);
477                           }
478                           tp = *ptp;
479                         }
480   ]
481                         { if (*ptp && *ptp != tp) **ptp = *tp;
482                           else *ptp = tp;
483                         }
484 ;
485
486 structure_type(register p_type tp; p_symbol sy;)
487   { register struct fields *fldp;
488     char *str;
489   }
490 :
491   integer_const(&(tp->ty_size))         /* size in bytes */
492                         { open_scope(sy, 0);
493                           if (sy) sy->sy_name.nm_scope = CurrentScope;
494                         }
495   [
496         name(&str)      { fldp = get_field_space(tp, str); }
497         type(&(fldp->fld_type), (int *) 0, (p_symbol) 0) ','
498         integer_const(&(fldp->fld_pos)) ','     /* offset in bits */
499         integer_const(&(fldp->fld_bitsize)) ';' /* size in bits */
500   ]*
501   ';'                   { end_field(tp); 
502                           close_scope();
503                         }
504 ;
505
506 enum_type(register p_type tp;)
507   { register struct literal *litp;
508     long maxval = 0;
509     register p_symbol s;
510   }
511 :
512   [                     { litp = get_literal_space(tp); }
513         name(&(litp->lit_name))
514         integer_const(&(litp->lit_val)) ',' 
515                         { if (maxval < litp->lit_val) maxval = litp->lit_val;
516                           AllowName = 1;
517                           s = NewSymbol(litp->lit_name, CurrentScope, CONST, (struct outname *) 0);
518                           s->sy_const.co_ival = litp->lit_val;
519                           s->sy_type = tp;
520                         }
521   ]*
522   ';'                   { end_literal(tp, maxval); }
523 ;
524
525 param_list(p_type t;)
526   { register struct param *p;
527     long iconst;
528   }
529 :
530   integer_const(&iconst) ';'    /* number of parameters */
531                         { t->ty_nparams = iconst;
532                           t->ty_params = p = (struct param *)
533                             Malloc((unsigned)(t->ty_nparams * sizeof(struct param)));
534                         }
535   [
536         [       'p'     { p->par_kind = 'p'; }
537         |       'v'     { p->par_kind = 'v'; }
538         |       'i'     { p->par_kind = 'i'; }
539         ]
540                         { p->par_type = 0; }
541         type(&(p->par_type), (int *) 0, (p_symbol) 0) ';'
542                         { p->par_off = t->ty_nbparams;
543                           t->ty_nbparams += 
544                                 param_size(p->par_type, p->par_kind);
545                           p++;
546                         }
547   ]*
548 ;
549
550 {
551 static char *db_string;
552 static char *DbOldPtr;
553
554 static struct outname *
555 DbString(n)
556   struct outname        *n;
557 {
558   currnam = n;
559   DbPtr = n->on_mptr;
560   db_string = DbPtr;
561   AllowName = 1;
562   DbParser();
563   return currnam;
564 }
565
566 /*ARGSUSED*/
567 DBSmessage(n)
568 {
569   fatal("error in symbol table string \"%s\", DbPtr = \"%s\", DbOldPtr = \"%s\"",
570         db_string,
571         DbPtr,
572         DbOldPtr);
573
574 }
575
576 DBSonerror(tk, p)
577   int   *p;
578 {
579   DbPtr = DbOldPtr;
580 /* ???  if (DBSsymb < 0) {
581         while (*p && *p != ';') p++;
582         if (*p) DbPtr = ";";
583         return;
584   }
585 */
586   if (! tk) {
587         while (*p && *p != NAME) p++;
588         if (*p) {
589                 AllowName = 1;
590         }
591   }
592   else if (tk == NAME) AllowName = 1;
593 }
594
595 DBSlex()
596 {
597   register char *cp = DbPtr;
598   int allow_name = AllowName;
599   register int c;
600
601   AllowName = 0;
602   DbOldPtr = cp;
603   c = *cp;
604   if (c == '\\' && *(cp+1) == '\0') {
605         currnam++;
606         cp = currnam->on_mptr;
607         DbOldPtr = cp;
608         c = *cp;
609   }
610   if (! c) {
611         DbPtr = cp;
612         return -1;
613   }
614   if ((! allow_name && is_token(c)) || c == ';') {
615         DbPtr = cp+1;
616         return c;
617   }
618   if (is_dig(c)) {
619         int retval = INTEGER;
620
621         while (++cp, is_dig(*cp)) /* nothing */;
622         c = *cp;
623         if (c == '.') {
624                 retval = REAL;
625                 while (++cp, is_dig(*cp)) /* nothing */;
626                 c = *cp;
627         }
628         if (c == 'e' || c == 'E') {
629                 char *oldcp = cp;
630
631                 cp++;
632                 c = *cp;
633                 if (c == '-' || c == '+') {
634                         cp++;
635                         c = *cp;
636                 }
637                 if (is_dig(c)) {
638                         retval = REAL;
639                         while (++cp, is_dig(*cp)) /* nothing */;
640                 }
641                 else cp = oldcp;
642         }
643         c = *cp;
644         *cp = 0;
645         if (retval == INTEGER) {
646                 ival = str2long(DbOldPtr, 10);
647         }
648         else {
649                 fval = atof(DbOldPtr);
650         }
651         *cp = c;
652         DbPtr = cp;
653         return retval;
654   }
655   if (c == '\'') {
656         cp++;
657         strval = cp;
658         while ((c = *cp) && c != '\'') {
659                 if (c == '\\') cp++;    /* backslash escapes next character */
660                 if (!(c =  *cp)) break; /* but not a null byte */
661                 cp++;
662         }
663         if (! c) DBSmessage(0); /* no return */
664         *cp = 0;
665         DbPtr = cp + 1;
666         return STRING;
667   }
668   strval = cp;
669   while ((c = *cp) && c != ':' && c != ',') cp++;
670   DbPtr = *cp ? cp+1 : cp;
671   *cp = 0;
672   return NAME;
673 }
674
675 static struct fields *
676 get_field_space(tp, s)
677   register p_type tp;
678   char  *s;
679 {
680   register struct fields *p;
681   p_symbol      sy;
682
683   if (! (tp->ty_nfields & 07)) {
684         tp->ty_fields = (struct fields *)
685                   Realloc((char *) tp->ty_fields,
686                             (tp->ty_nfields+8)*sizeof(struct fields));
687   }
688   p = &tp->ty_fields[tp->ty_nfields++];
689   p->fld_name = s;
690   p->fld_type = 0;
691   sy = NewSymbol(s, CurrentScope, FIELD, currnam);
692   sy->sy_field = p;
693   return p;
694 }
695
696 static
697 end_field(tp)
698   register p_type tp;
699 {
700   tp->ty_fields = (struct fields *)
701         Realloc((char *) tp->ty_fields,
702                 tp->ty_nfields * sizeof(struct fields));
703 }
704
705 static struct literal *
706 get_literal_space(tp)
707   register p_type tp;
708 {
709   if (! (tp->ty_nenums & 07)) {
710         tp->ty_literals = (struct literal *)
711                 Realloc((char *) tp->ty_literals,
712                         (tp->ty_nenums+8)*sizeof(struct literal));
713   }
714   return &tp->ty_literals[tp->ty_nenums++];
715 }
716
717 static char *
718 string_val(s)
719   char  *s;
720 {
721   register char *ns = s, *os = s;
722   register unsigned int i = 1;
723
724   for (;;) {
725         if (!*os) break;
726         i++;
727         if (*os == '\\') {
728                 os++;
729                 *ns++ = *os++;
730         }
731         else *ns++ = *os++;
732   }
733   *ns = '\0';
734   return Salloc(s, i);
735 }
736
737 static char             *AckStrings;    /* ACK a.out string table */
738 static struct outname   *AckNames;      /* ACK a.out symbol table entries */
739 static unsigned int     NAckNames;      /* Number of ACK symbol table entries */
740 static struct outname   *EndAckNames;   /* &AckNames[NAckNames] */
741
742 /* Read the symbol table from file 'f', which is supposed to be an
743    ACK a.out format file. Offer db strings to the db string parser.
744 */
745 int
746 DbRead(f)
747   char  *f;
748 {
749   struct outhead h;
750   register struct outname *n;
751   register struct outname *line_file = 0;
752   long OffsetStrings;
753   int lbrac_required = 0;
754   int needs_newscope = 0;
755   int lbrac_level = 0;
756
757   /* Open file, read header, and check magic word */
758   if (! rd_open(f)) {
759         fatal("%s: could not open", f);
760   }
761   rd_ohead(&h);
762   if (BADMAGIC(h) && h.oh_magic != O_CONVERTED) {
763         fatal("%s: not an object file", f);
764   }
765
766   /* Allocate space for name table and read it */
767   AckNames = (struct outname *) 
768                 Malloc((unsigned)(sizeof(struct outname) * h.oh_nname));
769   AckStrings = Malloc((unsigned) h.oh_nchar);
770   rd_name(AckNames, h.oh_nname);
771   rd_string(AckStrings, h.oh_nchar);
772
773   /* Adjust file offsets in name table to point at strings */
774   OffsetStrings = OFF_CHAR(h);
775   NAckNames = h.oh_nname;
776   EndAckNames = &AckNames[h.oh_nname];
777   for (n = EndAckNames; --n >= AckNames;) {
778         if (n->on_foff) {
779                 if ((unsigned)(n->on_foff - OffsetStrings) >= h.oh_nchar) {
780                         fatal("%s: error in object file", f);
781                 }
782                 n->on_mptr = AckStrings + (n->on_foff - OffsetStrings);
783         }
784         else    n->on_mptr = 0;
785   }
786
787   /* Offer strings to the db string parser if they contain a ':'.
788      Also offer filename-line number information to add_position_addr().
789      Here, the order may be important.
790   */
791   for (n = &AckNames[0]; n < EndAckNames; n++) {
792         int tp = n->on_type >> 8;
793         register p_symbol sym;
794
795         if (tp & (S_STB >> 8)) {
796                 switch(tp) {
797 #ifdef N_BINCL
798                 case N_BINCL:
799                         n->on_valu = (long) line_file;
800                         line_file = n;
801                         break;
802                 case N_EINCL:
803                         if (line_file) {
804                                 line_file = (struct outname *) line_file->on_valu;
805                         }
806                         break;
807 #endif
808                 case N_SO:
809                         if (n->on_mptr[strlen(n->on_mptr)-1] == '/') {
810                                 /* another N_SO follows ... */
811                                 break;
812                         }
813                         clean_tp_tab();
814                         while (CurrentScope != PervasiveScope) {
815                                 close_scope();
816                         }
817                         saw_code = 0;
818                         sym = add_file(n->on_mptr);
819
820                         if (! listfile) newfile(sym->sy_idf);
821                         open_scope(sym, 0);
822                         sym->sy_file->f_scope = CurrentScope;
823                         FileScope = CurrentScope;
824                         CurrentScope->sc_start = n->on_valu;
825                         /* fall through */
826                 case N_SOL:
827                         if (line_file) n->on_valu = line_file->on_valu;
828                         line_file = n;
829                         break;
830                 case N_MAIN:
831                         if (! FileScope) fatal("No file scope");
832                         newfile(FileScope->sc_definedby->sy_idf);
833                         break;
834                 case N_SLINE:
835                         assert(line_file);
836                         if (CurrentScope->sc_start) {
837                                 register p_scope sc =
838                                         get_scope_from_addr(n->on_valu);
839
840                                 if (sc) CurrentScope = sc;
841                         }
842                         else if (! saw_code) {
843                                 CurrentScope->sc_start = n->on_valu;
844                                 add_scope_addr(CurrentScope);
845                         }
846                         if (!CurrentScope->sc_bp_opp
847                             || CurrentScope->sc_bp_lineno > n->on_desc) {
848                                 CurrentScope->sc_bp_opp = n->on_valu;
849                                 CurrentScope->sc_bp_lineno = n->on_desc;
850                         }
851                         saw_code = 1;
852                         add_position_addr(line_file->on_mptr, n);
853                         break;
854                 case N_LBRAC:   /* block, desc = nesting level */
855                         if (lbrac_level && ! lbrac_required) {
856                                 open_scope((p_symbol) 0, 0);
857                                 saw_code = 0;
858                         }
859                         else {
860                                 /* Sun-4 ld does not relocate LBRAC
861                                    values, so we cannot use it
862                                 
863                                 register p_scope sc = 
864                                         get_scope_from_addr(n->on_valu);
865
866                                 if (!sc || sc->sc_bp_opp) {
867                                 }
868                                 else CurrentScope = sc;
869                                 */
870                         }
871                         lbrac_level++;
872                         needs_newscope = 1;
873                         break;
874 #ifdef N_SCOPE
875                 case N_SCOPE:
876                         if (n->on_mptr && strindex(n->on_mptr, ':')) {
877                                 n = DbString(n);
878                         }
879                         break;
880 #endif
881                 case N_RBRAC:   /* end block, desc = nesting level */
882                         if (CurrentScope != FileScope) close_scope();
883                         needs_newscope = 1;
884                         if (--lbrac_level == 0) needs_newscope = 0;
885                         saw_code = 0;
886                         break;
887                 case N_FUN:     /* function, value = address */
888                 case N_GSYM:    /* global variable */
889                 case N_STSYM:   /* data, static, value = address */
890                 case N_LCSYM:   /* bss, static, value = address */
891                 case N_RSYM:    /* register var, value = reg number */
892                 case N_SSYM:    /* struct/union el, value = offset */
893                 case N_PSYM:    /* parameter, value = offset from AP */
894                 case N_LSYM:    /* local sym, value = offset from FP */
895                         if (needs_newscope) {
896                                 open_scope((p_symbol) 0, 0);
897                                 saw_code = 0;
898                                 needs_newscope = 0;
899                                 lbrac_required = 1;
900                         }
901                         if (n->on_mptr && strindex(n->on_mptr, ':')) {
902                                 n = DbString(n);
903                         }
904                         break;
905                 default:
906 /*
907                         if (n->on_mptr && (n->on_type&S_TYP) >= S_MIN) {
908                                 struct idf *id = str2idf(n->on_mptr, 0);
909
910                                 sym = new_symbol();
911                                 sym->sy_next = id->id_def;
912                                 id->id_def = sym;
913                                 sym->sy_class = SYMENTRY;
914                                 sym->sy_onam = *n;
915                                 sym->sy_idf = id;
916                         }
917 */
918                         break;
919                 }
920         }
921   }
922   close_scope();
923   add_position_addr((char *) 0, (struct outname *) 0);
924   clean_tp_tab();
925   rd_close();
926   return (h.oh_magic == O_CONVERTED);
927 }
928 }