4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 1996-2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
35 static struct tdesc
*hash_table
[BUCKETS
];
36 static struct tdesc
*name_table
[BUCKETS
];
38 static void reset(void);
39 static jmp_buf resetbuf
;
41 static char *get_line(void);
42 static void parseline(char *cp
);
43 static char *soudef(char *cp
, enum type type
, struct tdesc
**rtdp
);
44 static void enumdef(char *cp
, struct tdesc
**rtdp
);
45 static int compute_sum(char *w
);
46 static struct tdesc
*lookup(int h
);
48 static char *number(char *cp
, int *n
);
49 static char *name(char *cp
, char **w
);
50 static char *id(char *cp
, int *h
);
51 static char *offsize(char *cp
, struct mlist
*mlp
);
52 static char *whitesp(char *cp
);
53 static void addhash(struct tdesc
*tdp
, int num
);
54 static void tagadd(char *w
, int h
, struct tdesc
*tdp
);
55 static void tagdecl(char *cp
, struct tdesc
**rtdp
, int h
, char *w
);
56 static char *tdefdecl(char *cp
, int h
, struct tdesc
**rtdp
);
57 static char *intrinsic(char *cp
, struct tdesc
**rtdp
);
58 static char *arraydef(char *cp
, struct tdesc
**rtdp
);
60 static int line_number
= 0;
61 static int debug_line
= 0;
62 static char linebuf
[MAXLINE
];
64 extern int debug_level
;
67 debug(int level
, char *cp
, char *fmt
, ...)
74 if (level
> debug_level
)
78 for (i
= 0; i
< 30; i
++) {
85 (void) sprintf(buf
, "%s [cp='%s']\n", fmt
, tmp
);
92 (void) vfprintf(stderr
, buf
, ap
);
97 /* Report unexpected syntax in stabs. */
100 char *who
, /* what function, or part thereof, is reporting */
101 char *what
, /* what was expected */
102 char *where
) /* where we were in the line of input */
104 fprintf(stderr
, "%s, input line %d: expecting \"%s\" at \"%s\"\n",
105 who
, line_number
, what
, where
);
109 /* Read a line from stdin into linebuf and increment line_number. */
113 char *cp
= fgets(linebuf
, MAXLINE
, stdin
);
116 /* For debugging, you can set debug_line to a line to stop on. */
117 if (line_number
== debug_line
) {
118 fprintf(stderr
, "Hit debug line number %d\n", line_number
);
125 /* Get the continuation of the current input line. */
127 get_continuation(void)
129 char *cp
= get_line();
131 fprintf(stderr
, "expecting continuation line, "
132 "got end of input\n");
136 /* Skip to the quoted stuff. */
148 for (i
= 0; i
< BUCKETS
; i
++) {
149 hash_table
[i
] = NULL
;
150 name_table
[i
] = NULL
;
154 * get a line at a time from the .s stabs file and parse.
156 while ((cp
= get_line()) != NULL
)
161 * Parse each line of the .s file (stabs entry) gather meaningful information
162 * like name of type, size, offsets of fields etc.
174 if (setjmp(resetbuf
))
178 * Look for lines of the form
179 * .stabs "str",n,n,n,n
180 * The part in '"' is then parsed.
184 debug(2, cp
, "parseline");
185 if (strncmp(cp
, ".stabs", STLEN
) != 0)
194 * name:type variable (ignored)
196 * name:Ttype struct tag define
205 case 'T': /* struct, union, enum */
213 * The type id and definition follow.
221 if (ntdp
== NULL
) { /* if that type isn't defined yet */
222 if (*cp
++ != '=') /* better be defining it now */
223 expected("parseline/'0-9'", "=", cp
- 1);
224 cp
= tdefdecl(cp
, h
, &tdp
);
225 addhash(tdp
, h
); /* for *(x,y) types */
226 } else { /* that type is already defined */
227 tdp
= malloc(sizeof (*tdp
));
229 tdp
->name
= (w
!= NULL
) ? strdup(w
) : NULL
;
230 tdp
->data
.tdesc
= ntdp
;
231 addhash(tdp
, h
); /* for *(x,y) types */
232 debug(3, NULL
, " %s defined as %s(%d)", w
,
233 (ntdp
->name
!= NULL
) ? ntdp
->name
: "anon", h
);
236 } else if (*cp
++ != '=') {
237 expected("parseline", "=", cp
- 1);
240 tagdecl(cp
, &tdp
, h
, w
);
242 tdefdecl(cp
, h
, &tdp
);
248 * Check if we have this node in the hash table already
250 static struct tdesc
*
254 struct tdesc
*tdp
= hash_table
[hash
];
256 while (tdp
!= NULL
) {
270 for (c
= *cp
++; isspace(c
); c
= *cp
++)
277 name(char *cp
, char **w
)
286 else if (isalpha(c
) || c
== '_') {
287 for (c
= *cp
++; isalnum(c
) || c
== ' ' || c
== '_'; c
= *cp
++)
293 while (orig
< cp
- 1)
296 *w
= new - (len
- 1);
304 number(char *cp
, int *n
)
308 *n
= (int)strtol(cp
, &next
, 10);
310 expected("number", "<number>", cp
);
319 if (*cp
== '(') { /* SunPro style */
321 cp
= number(cp
, &n1
);
323 expected("id", ",", cp
- 1);
324 cp
= number(cp
, &n2
);
326 expected("id", ")", cp
- 1);
328 } else if (isdigit(*cp
)) { /* gcc style */
329 cp
= number(cp
, &n1
);
332 expected("id", "(/0-9", cp
);
338 tagadd(char *w
, int h
, struct tdesc
*tdp
)
343 if (!(otdp
= lookup(h
)))
345 else if (otdp
!= tdp
) {
346 fprintf(stderr
, "duplicate entry\n");
347 fprintf(stderr
, "old: %s %d %d %d\n",
348 otdp
->name
? otdp
->name
: "NULL",
349 otdp
->type
, otdp
->id
/ 1000, otdp
->id
% 1000);
350 fprintf(stderr
, "new: %s %d %d %d\n",
351 tdp
->name
? tdp
->name
: "NULL",
352 tdp
->type
, tdp
->id
/ 1000, tdp
->id
% 1000);
357 tagdecl(char *cp
, struct tdesc
**rtdp
, int h
, char *w
)
359 debug(1, NULL
, "tagdecl: declaring '%s'", w
? w
: "(anon)");
360 if ((*rtdp
= lookup(h
)) != NULL
) {
362 if ((*rtdp
)->name
!= NULL
&&
363 strcmp((*rtdp
)->name
, w
) != 0) {
366 tdp
= malloc(sizeof (*tdp
));
367 tdp
->name
= strdup(w
);
369 tdp
->data
.tdesc
= *rtdp
;
370 addhash(tdp
, h
); /* for *(x,y) types */
371 debug(3, NULL
, " %s defined as %s(%d)", w
,
372 ((*rtdp
)->name
!= NULL
) ?
373 (*rtdp
)->name
: "anon", h
);
374 } else if ((*rtdp
)->name
== NULL
) {
380 *rtdp
= malloc(sizeof (**rtdp
));
387 soudef(cp
, STRUCT
, rtdp
);
390 soudef(cp
, UNION
, rtdp
);
396 expected("tagdecl", "<tag type s/u/e>", cp
- 1);
402 tdefdecl(char *cp
, int h
, struct tdesc
**rtdp
)
409 debug(3, cp
, "tdefdecl h=%d", h
);
412 switch (type
= *cp
) {
413 case 'b': /* integer */
415 if (c
!= 's' && c
!= 'u')
416 expected("tdefdecl/b", "[su]", cp
- 1);
420 cp
= intrinsic(cp
, rtdp
);
423 /* skip up to and past ';' */
426 cp
= intrinsic(cp
, rtdp
);
428 case '(': /* equiv to another type */
431 if (ntdp
== NULL
) { /* if that type isn't defined yet */
432 if (*cp
++ != '=') /* better be defining it now */
433 expected("tdefdecl/'('", "=", cp
- 1);
434 cp
= tdefdecl(cp
, h2
, rtdp
);
435 ntdp
= malloc(sizeof (*ntdp
));
437 ntdp
->data
.tdesc
= *rtdp
;
439 } else { /* that type is already defined */
440 *rtdp
= malloc(sizeof (**rtdp
));
441 (*rtdp
)->type
= TYPEOF
;
442 (*rtdp
)->data
.tdesc
= ntdp
;
447 cp
= tdefdecl(cp
+ 1, h
, &ntdp
);
449 expected("tdefdecl/*", "id", cp
);
451 *rtdp
= malloc(sizeof (**rtdp
));
452 (*rtdp
)->type
= POINTER
;
453 (*rtdp
)->size
= model
->pointersize
;
454 (*rtdp
)->name
= "pointer";
455 (*rtdp
)->data
.tdesc
= ntdp
;
458 cp
= tdefdecl(cp
+ 1, h
, &ntdp
);
459 *rtdp
= malloc(sizeof (**rtdp
));
460 (*rtdp
)->type
= FUNCTION
;
461 (*rtdp
)->size
= model
->pointersize
;
462 (*rtdp
)->name
= "function";
463 (*rtdp
)->data
.tdesc
= ntdp
;
468 expected("tdefdecl/a", "r", cp
- 1);
469 *rtdp
= malloc(sizeof (**rtdp
));
470 (*rtdp
)->type
= ARRAY
;
471 (*rtdp
)->name
= "array";
472 cp
= arraydef(cp
, rtdp
);
476 if (c
!= 's' && c
!= 'u' && c
!= 'e')
477 expected("tdefdecl/x", "[sue]", cp
- 1);
478 cp
= name(cp
+ 1, &w
);
479 *rtdp
= malloc(sizeof (**rtdp
));
480 (*rtdp
)->type
= FORWARD
;
483 case 'B': /* volatile */
484 cp
= tdefdecl(cp
+ 1, h
, &ntdp
);
485 *rtdp
= malloc(sizeof (**rtdp
));
486 (*rtdp
)->type
= VOLATILE
;
488 (*rtdp
)->name
= "volatile";
489 (*rtdp
)->data
.tdesc
= ntdp
;
491 case 'k': /* const */
492 cp
= tdefdecl(cp
+ 1, h
, &ntdp
);
493 *rtdp
= malloc(sizeof (**rtdp
));
494 (*rtdp
)->type
= CONST
;
496 (*rtdp
)->name
= "const";
497 (*rtdp
)->data
.tdesc
= ntdp
;
499 case '0': case '1': case '2': case '3': case '4':
500 case '5': case '6': case '7': case '8': case '9':
501 /* gcc equiv to another type */
504 if (ntdp
== NULL
) { /* if that type isn't defined yet */
505 /* better be defining it now */
508 expected("tdefdecl/'0-9'", "=", cp
- 1);
509 /* defined in terms of itself */
510 *rtdp
= malloc(sizeof (**rtdp
));
511 (*rtdp
)->type
= INTRINSIC
;
512 (*rtdp
)->name
= "void";
515 cp
= tdefdecl(cp
, h2
, rtdp
);
516 ntdp
= malloc(sizeof (*ntdp
));
518 ntdp
->data
.tdesc
= *rtdp
;
521 } else { /* that type is already defined */
522 *rtdp
= malloc(sizeof (**rtdp
));
523 (*rtdp
)->type
= TYPEOF
;
524 (*rtdp
)->data
.tdesc
= ntdp
;
531 *rtdp
= malloc(sizeof (**rtdp
));
532 (*rtdp
)->name
= NULL
;
533 cp
= soudef(cp
, (type
== 'u') ? UNION
: STRUCT
, rtdp
);
536 expected("tdefdecl", "<type code>", cp
);
542 intrinsic(char *cp
, struct tdesc
**rtdp
)
547 cp
= number(cp
, &size
);
548 tdp
= malloc(sizeof (*tdp
));
549 tdp
->type
= INTRINSIC
;
552 debug(3, NULL
, "intrinsic: size=%ld", size
);
558 soudef(char *cp
, enum type type
, struct tdesc
**rtdp
)
560 struct mlist
**next_pp
, *prev_p
= NULL
;
565 cp
= number(cp
, &size
);
566 (*rtdp
)->size
= size
;
567 (*rtdp
)->type
= type
; /* s or u */
570 * An '@' here indicates a bitmask follows. This is so the
571 * compiler can pass information to debuggers about how structures
572 * are passed in the v9 world. We don't need this information
573 * so we skip over it.
578 debug(3, cp
, "soudef: %s size=%d",
579 (*rtdp
)->name
? (*rtdp
)->name
: "(anonsou)",
582 next_pp
= &((*rtdp
)->data
.members
.forw
); /* head for forward linklist */
583 /* fill up the fields */
584 while ((*cp
!= '"') && (*cp
!= ';')) { /* signifies end of fields */
586 struct mlist
*mlp
= malloc(sizeof (*mlp
));
588 mlp
->prev
= prev_p
; /* links for the backward list */
590 *next_pp
= mlp
; /* links for the forward list */
591 next_pp
= &mlp
->next
;
597 * find the tdesc struct in the hash table for this type
598 * and stick a ptr in here
601 if (tdp
== NULL
) { /* not in hash list */
602 debug(3, NULL
, " defines %s (%d)", w
, h
);
604 expected("soudef", "=", cp
- 1);
605 cp
= tdefdecl(cp
, h
, &tdp
);
607 debug(4, cp
, " soudef now looking at ");
611 debug(3, NULL
, " refers to %s (%d, %s)",
612 w
? w
: "anon", h
, tdp
->name
? tdp
->name
: "anon");
616 cp
= offsize(cp
, mlp
); /* cp is now pointing to next field */
617 if (*cp
== '\\') /* could be a continuation */
618 cp
= get_continuation();
620 (*rtdp
)->data
.members
.back
= prev_p
; /* head for backward linklist */
625 offsize(char *cp
, struct mlist
*mlp
)
631 cp
= number(cp
, &offset
);
633 expected("offsize/2", ",", cp
- 1);
634 cp
= number(cp
, &size
);
636 expected("offsize/3", ";", cp
- 1);
637 mlp
->offset
= offset
;
643 arraydef(char *cp
, struct tdesc
**rtdp
)
650 expected("arraydef/1", ";", cp
- 1);
652 (*rtdp
)->data
.ardef
= malloc(sizeof (struct ardef
));
653 (*rtdp
)->data
.ardef
->indices
= malloc(sizeof (struct element
));
654 (*rtdp
)->data
.ardef
->indices
->index_type
= lookup(h
);
656 cp
= number(cp
, &start
); /* lower */
658 expected("arraydef/2", ";", cp
- 1);
659 cp
= number(cp
, &end
); /* upper */
661 expected("arraydef/3", ";", cp
- 1);
662 (*rtdp
)->data
.ardef
->indices
->range_start
= start
;
663 (*rtdp
)->data
.ardef
->indices
->range_end
= end
;
666 cp
= number(cp
, &contents_type
); /* lower */
667 tdp
= lookup(contents_type
);
669 (*rtdp
)->data
.ardef
->contents
= tdp
;
672 expected("arraydef/4", "=", cp
);
673 cp
= tdefdecl(cp
+ 1, h
, &tdp
);
674 addhash(tdp
, h
); /* for *(x,y) types */
675 (*rtdp
)->data
.ardef
->contents
= tdp
;
679 cp
= tdefdecl(cp
, h
, &((*rtdp
)->data
.ardef
->contents
));
684 enumdef(char *cp
, struct tdesc
**rtdp
)
686 struct elist
*elp
, **prev
;
689 (*rtdp
)->type
= ENUM
;
690 (*rtdp
)->data
.emem
= NULL
;
692 prev
= &((*rtdp
)->data
.emem
);
694 elp
= malloc(sizeof (*elp
));
699 cp
= number(cp
, &elp
->number
);
700 debug(3, NULL
, "enum %s: %s=%ld",
701 (*rtdp
)->name
? (*rtdp
)->name
: "(anon enum)",
702 elp
->name
, elp
->number
);
705 expected("enumdef", ",", cp
- 1);
707 cp
= get_continuation();
712 * Add a node to the hash queues.
715 addhash(struct tdesc
*tdp
, int num
)
717 int hash
= HASH(num
);
719 char added_num
= 0, added_name
= 0;
722 * If it already exists in the hash table don't add it again
723 * (but still check to see if the name should be hashed).
728 tdp
->hash
= hash_table
[hash
];
729 hash_table
[hash
] = tdp
;
733 if (tdp
->name
!= NULL
) {
734 ttdp
= lookupname(tdp
->name
);
736 hash
= compute_sum(tdp
->name
);
737 tdp
->next
= name_table
[hash
];
738 name_table
[hash
] = tdp
;
742 if (!added_num
&& !added_name
) {
743 fprintf(stderr
, "stabs: broken hash\n");
749 lookupname(char *name
)
751 int hash
= compute_sum(name
);
752 struct tdesc
*tdp
, *ttdp
= NULL
;
754 for (tdp
= name_table
[hash
]; tdp
!= NULL
; tdp
= tdp
->next
) {
755 if (tdp
->name
!= NULL
&& strcmp(tdp
->name
, name
) == 0) {
756 if (tdp
->type
== STRUCT
|| tdp
->type
== UNION
||
757 tdp
->type
== ENUM
|| tdp
->type
== INTRINSIC
)
759 if (tdp
->type
== TYPEOF
)
772 for (sum
= 0; (c
= *w
) != '\0'; sum
+= c
, w
++)
780 longjmp(resetbuf
, 1);