Init
This commit is contained in:
63
uts/sun4u/forthdebug/forthgen/Makefile
Executable file
63
uts/sun4u/forthdebug/forthgen/Makefile
Executable file
@@ -0,0 +1,63 @@
|
||||
#
|
||||
# Copyright (c) 1991 by Sun Microsystems, Inc.
|
||||
#
|
||||
#ident "@(#)Makefile 1.2 95/06/14 SMI"
|
||||
#
|
||||
# uts/sun4u/forthdebug/forthgen/Makefile
|
||||
|
||||
UTSBASE = ../../..
|
||||
|
||||
#
|
||||
# Define the module and object file sets.
|
||||
#
|
||||
FORTHGEN = $(OBJS_DIR)/forthgen
|
||||
FORTHGEN_OBJS = parser.o stabs.o
|
||||
OBJECTS = $(FORTHGEN_OBJS:%=$(OBJS_DIR)/%)
|
||||
LINTS = $(FORTHGEN_OBJS:%.o=$(LINTS_DIR)/%.ln)
|
||||
SRCS_DIR = $(UTSBASE)/sun4u/forthdebug/forthgen
|
||||
|
||||
#
|
||||
# Include common rules.
|
||||
#
|
||||
CLEANFILES = $(OBJECTS)
|
||||
|
||||
FILEMODE = 755
|
||||
OWNER = bin
|
||||
GROUP = bin
|
||||
|
||||
include $(UTSBASE)/sun4u/Makefile.sun4u
|
||||
|
||||
NATIVECFLAGS = -c
|
||||
|
||||
|
||||
#
|
||||
# Default build targets.
|
||||
#
|
||||
.KEEP_STATE:
|
||||
|
||||
|
||||
all: $(FORTHGEN)
|
||||
|
||||
install: all
|
||||
|
||||
lint: $(SRCS_DIR)/parser.c $(SRCS_DIR)/stabs.c
|
||||
@$(LINT) $(LINTFLAGS) $(SRCS_DIR)/parser.c $(SRCS_DIR)/stabs.c
|
||||
|
||||
clean:
|
||||
$(RM) $(CLEANFILES)
|
||||
|
||||
clobber: clean
|
||||
$(RM) $(FORTHGEN)
|
||||
|
||||
clean.lint:
|
||||
$(RM) $(LINTS)
|
||||
|
||||
|
||||
$(FORTHGEN): $(FORTHGEN_OBJS)
|
||||
$(NATIVECC) -o $@ $(FORTHGEN_OBJS) -lm
|
||||
|
||||
$(OBJS_DIR)/parser.o: $(SRCS_DIR)/parser.c
|
||||
$(NATIVECC) $(NATIVECFLAGS) $(SRCS_DIR)/parser.c -o $@
|
||||
|
||||
$(OBJS_DIR)/stabs.o: $(SRCS_DIR)/stabs.c
|
||||
$(NATIVECC) $(NATIVECFLAGS) $(SRCS_DIR)/stabs.c -o $@
|
||||
504
uts/sun4u/forthdebug/forthgen/parser.c
Executable file
504
uts/sun4u/forthdebug/forthgen/parser.c
Executable file
@@ -0,0 +1,504 @@
|
||||
|
||||
#include "stabs.h"
|
||||
|
||||
jmp_buf resetbuf;
|
||||
|
||||
char *whitesp(), *name(), *id(), *decl(), *number(), *offsize();
|
||||
char *tdefdecl(), *intrinsic(), *arraydef();
|
||||
void addhash();
|
||||
|
||||
|
||||
parse_input()
|
||||
{
|
||||
char *cp;
|
||||
int i = 0;
|
||||
static char linebuf[MAXLINE];
|
||||
|
||||
while (i++ < BUCKETS) {
|
||||
hash_table[i] = NULL;
|
||||
name_table[i] = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* get a line at a time from the .s stabs file and parse.
|
||||
*/
|
||||
while (cp = fgets(linebuf, MAXLINE, stdin))
|
||||
parseline(cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse each line of the .s file (stabs entry) gather meaningful information
|
||||
* like name of type, size, offsets of fields etc.
|
||||
*/
|
||||
parseline(cp)
|
||||
char *cp;
|
||||
{
|
||||
struct tdesc *tdp;
|
||||
char c, *w;
|
||||
int h, tagdef;
|
||||
int debug;
|
||||
|
||||
/*
|
||||
* setup for reset()
|
||||
*/
|
||||
if (setjmp(resetbuf))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Look for lines of the form
|
||||
* .stabs "str",n,n,n,n
|
||||
* The part in '"' is then parsed.
|
||||
*/
|
||||
cp = whitesp(cp);
|
||||
#define STLEN 6
|
||||
if (strncmp(cp, ".stabs", STLEN) != 0)
|
||||
reset();
|
||||
cp += STLEN;
|
||||
#undef STLEN
|
||||
cp = whitesp(cp);
|
||||
if (*cp++ != '"')
|
||||
reset();
|
||||
|
||||
/*
|
||||
* name:type variable (ignored)
|
||||
* name:ttype typedef
|
||||
* name:Ttype struct tag define
|
||||
*/
|
||||
cp = name(cp, &w);
|
||||
switch (c = *cp++) {
|
||||
case 't': /* type */
|
||||
tagdef = 0;
|
||||
break;
|
||||
case 'T': /* struct, union, enum */
|
||||
tagdef = 1;
|
||||
break;
|
||||
default:
|
||||
reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* The type id and definition follow.
|
||||
*/
|
||||
cp = id(cp, &h);
|
||||
if (*cp++ != '=')
|
||||
reset();
|
||||
if (tagdef) {
|
||||
tagdecl(cp, &tdp, h, w);
|
||||
} else {
|
||||
tdefdecl(cp, &tdp);
|
||||
tagadd(w, h, tdp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we have this node in the hash table already
|
||||
*/
|
||||
struct tdesc *
|
||||
lookup(int h)
|
||||
{
|
||||
int hash = HASH(h);
|
||||
struct tdesc *tdp = hash_table[hash];
|
||||
|
||||
while (tdp != NULL) {
|
||||
if (tdp->id == h)
|
||||
return (tdp);
|
||||
tdp = tdp->hash;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
char *
|
||||
whitesp(cp)
|
||||
char *cp;
|
||||
{
|
||||
char *orig, c;
|
||||
|
||||
orig = cp;
|
||||
for (c = *cp++; isspace(c); c = *cp++)
|
||||
;
|
||||
if (--cp == orig)
|
||||
reset();
|
||||
return (cp);
|
||||
}
|
||||
|
||||
char *
|
||||
name(cp, w)
|
||||
char *cp, **w;
|
||||
{
|
||||
char *new, *orig, c;
|
||||
int len;
|
||||
|
||||
orig = cp;
|
||||
c = *cp++;
|
||||
if (c == ':')
|
||||
*w = NULL;
|
||||
else if (isalpha(c) || c == '_') {
|
||||
for (c = *cp++; isalnum(c) || c == ' ' || c == '_'; c = *cp++)
|
||||
;
|
||||
if (c != ':')
|
||||
reset();
|
||||
len = cp - orig;
|
||||
new = (char *)malloc(len);
|
||||
while (orig < cp - 1)
|
||||
*new++ = *orig++;
|
||||
*new = '\0';
|
||||
*w = new - (len - 1);
|
||||
} else
|
||||
reset();
|
||||
return (cp);
|
||||
}
|
||||
|
||||
char *
|
||||
number(cp, n)
|
||||
char *cp;
|
||||
long *n;
|
||||
{
|
||||
char *next;
|
||||
|
||||
*n = strtol(cp, &next, 10);
|
||||
if (next == cp)
|
||||
reset();
|
||||
return (next);
|
||||
}
|
||||
|
||||
char *
|
||||
id(cp, h)
|
||||
char *cp;
|
||||
int *h;
|
||||
{
|
||||
long n1, n2;
|
||||
|
||||
if (*cp++ != '(')
|
||||
reset();
|
||||
cp = number(cp, &n1);
|
||||
if (*cp++ != ',')
|
||||
reset();
|
||||
cp = number(cp, &n2);
|
||||
if (*cp++ != ')')
|
||||
reset();
|
||||
*h = n1 * 1000 + n2;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
tagadd(char *w, int h, struct tdesc *tdp)
|
||||
{
|
||||
struct tdesc *otdp, *hash;
|
||||
|
||||
tdp->name = w;
|
||||
if (!(otdp = lookup(h)))
|
||||
addhash(tdp, h);
|
||||
else if (otdp != tdp) {
|
||||
fprintf(stderr, "duplicate entry\n");
|
||||
fprintf(stderr, "old: %s %d %d %d\n",
|
||||
otdp->name ? otdp->name : "NULL",
|
||||
otdp->type, otdp->id / 1000, otdp->id % 1000);
|
||||
fprintf(stderr, "new: %s %d %d %d\n",
|
||||
tdp->name ? tdp->name : "NULL",
|
||||
tdp->type, tdp->id / 1000, tdp->id % 1000);
|
||||
}
|
||||
}
|
||||
|
||||
tagdecl(cp, rtdp, h, w)
|
||||
char *cp;
|
||||
struct tdesc **rtdp;
|
||||
int h;
|
||||
char *w;
|
||||
{
|
||||
if (*rtdp = lookup(h)) {
|
||||
if ((*rtdp)->type != FORWARD)
|
||||
fprintf(stderr, "found but not forward: %s \n", cp);
|
||||
} else {
|
||||
*rtdp = ALLOC(struct tdesc);
|
||||
(*rtdp)->name = w;
|
||||
addhash(*rtdp, h);
|
||||
}
|
||||
|
||||
switch (*cp++) {
|
||||
case 's':
|
||||
soudef(cp, STRUCT, rtdp);
|
||||
break;
|
||||
case 'u':
|
||||
soudef(cp, UNION, rtdp);
|
||||
break;
|
||||
case 'e':
|
||||
enumdef(cp, rtdp);
|
||||
break;
|
||||
default:
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
tdefdecl(cp, rtdp)
|
||||
char *cp;
|
||||
struct tdesc **rtdp;
|
||||
{
|
||||
struct tdesc *tdp, *ntdp;
|
||||
char *w;
|
||||
int c, h;
|
||||
|
||||
/* Type codes */
|
||||
switch (*cp) {
|
||||
case 'b': /* integer */
|
||||
c = *++cp;
|
||||
if (c != 's' && c != 'u')
|
||||
reset();
|
||||
c = *++cp;
|
||||
if (c == 'c')
|
||||
cp++;
|
||||
cp = intrinsic(cp, rtdp);
|
||||
break;
|
||||
case 'R': /* fp */
|
||||
cp += 3;
|
||||
cp = intrinsic(cp, rtdp);
|
||||
break;
|
||||
case '(': /* equiv to another type */
|
||||
cp = id(cp, &h);
|
||||
ntdp = lookup(h);
|
||||
if (ntdp == NULL) {
|
||||
if (*cp++ != '=')
|
||||
reset();
|
||||
cp = tdefdecl(cp, rtdp);
|
||||
addhash(*rtdp, h); /* for *(x,y) types */
|
||||
} else {
|
||||
*rtdp = ALLOC(struct tdesc);
|
||||
(*rtdp)->type = TYPEOF;
|
||||
(*rtdp)->data.tdesc = ntdp;
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
cp = tdefdecl(cp + 1, &ntdp);
|
||||
*rtdp = ALLOC(struct tdesc);
|
||||
(*rtdp)->type = POINTER;
|
||||
(*rtdp)->size = sizeof (void *);
|
||||
(*rtdp)->name = "pointer";
|
||||
(*rtdp)->data.tdesc = ntdp;
|
||||
break;
|
||||
case 'f':
|
||||
cp = tdefdecl(cp + 1, &ntdp);
|
||||
*rtdp = ALLOC(struct tdesc);
|
||||
(*rtdp)->type = FUNCTION;
|
||||
(*rtdp)->size = sizeof (void *);
|
||||
(*rtdp)->name = "function";
|
||||
(*rtdp)->data.tdesc = ntdp;
|
||||
break;
|
||||
case 'a':
|
||||
cp++;
|
||||
if (*cp++ != 'r')
|
||||
reset();
|
||||
*rtdp = ALLOC(struct tdesc);
|
||||
(*rtdp)->type = ARRAY;
|
||||
(*rtdp)->name = "array";
|
||||
cp = arraydef(cp, rtdp);
|
||||
break;
|
||||
case 'x':
|
||||
c = *++cp;
|
||||
if (c != 's' && c != 'u' && c != 'e')
|
||||
reset();
|
||||
cp = name(cp + 1, &w);
|
||||
*rtdp = ALLOC(struct tdesc);
|
||||
(*rtdp)->type = FORWARD;
|
||||
(*rtdp)->name = w;
|
||||
break;
|
||||
default:
|
||||
reset();
|
||||
}
|
||||
return (cp);
|
||||
}
|
||||
|
||||
char *
|
||||
intrinsic(cp, rtdp)
|
||||
char *cp;
|
||||
struct tdesc **rtdp;
|
||||
{
|
||||
struct tdesc *tdp;
|
||||
long size;
|
||||
|
||||
cp = number(cp, &size);
|
||||
tdp = ALLOC(struct tdesc);
|
||||
tdp->type = INTRINSIC;
|
||||
tdp->size = size;
|
||||
tdp->name = NULL;
|
||||
*rtdp = tdp;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
soudef(cp, type, rtdp)
|
||||
char *cp;
|
||||
enum type type;
|
||||
struct tdesc **rtdp;
|
||||
{
|
||||
struct mlist *mlp, **prev;
|
||||
char *w;
|
||||
int h, i = 0;
|
||||
long size;
|
||||
struct tdesc *tdp;
|
||||
char linebuf[MAXLINE];
|
||||
|
||||
cp = number(cp, &size);
|
||||
(*rtdp)->size = size;
|
||||
(*rtdp)->type = type; /* s or u */
|
||||
|
||||
prev = &((*rtdp)->data.members);
|
||||
/* now fill up the fields */
|
||||
while ((*cp != '"') && (*cp != ';')) { /* signifies end of fields */
|
||||
mlp = ALLOC(struct mlist);
|
||||
*prev = mlp;
|
||||
cp = name(cp, &w);
|
||||
mlp->name = w;
|
||||
cp = id(cp, &h);
|
||||
/*
|
||||
* find the tdesc struct in the hash table for this type
|
||||
* and stick a ptr in here
|
||||
*/
|
||||
tdp = lookup(h);
|
||||
if (tdp == NULL) { /* not in hash list */
|
||||
if (*cp++ != '=')
|
||||
reset();
|
||||
cp = tdefdecl(cp, &tdp);
|
||||
addhash(tdp, h);
|
||||
}
|
||||
|
||||
mlp->fdesc = tdp;
|
||||
cp = offsize(cp, mlp);
|
||||
/* cp is now pointing to next field */
|
||||
prev = &mlp->next;
|
||||
/* could be a continuation */
|
||||
if (*cp == '\\') {
|
||||
/* get next line */
|
||||
cp = fgets(linebuf, MAXLINE, stdin);
|
||||
while (*cp++ != '"')
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
offsize(cp, mlp)
|
||||
char *cp;
|
||||
struct mlist *mlp;
|
||||
{
|
||||
long offset, size;
|
||||
|
||||
if (*cp++ != ',')
|
||||
reset();
|
||||
cp = number(cp, &offset);
|
||||
if (*cp++ != ',')
|
||||
reset();
|
||||
cp = number(cp, &size);
|
||||
if (*cp++ != ';')
|
||||
reset();
|
||||
mlp->offset = offset;
|
||||
mlp->size = size;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
char *
|
||||
arraydef(char *cp, struct tdesc **rtdp)
|
||||
{
|
||||
int h;
|
||||
long start, end;
|
||||
|
||||
cp = id(cp, &h);
|
||||
if (*cp++ != ';')
|
||||
reset();
|
||||
|
||||
(*rtdp)->data.ardef = ALLOC(struct ardef);
|
||||
(*rtdp)->data.ardef->indices = ALLOC(struct element);
|
||||
(*rtdp)->data.ardef->indices->index_type = lookup(h);
|
||||
|
||||
cp = number(cp, &start);
|
||||
if (*cp++ != ';')
|
||||
reset();
|
||||
cp = number(cp, &end);
|
||||
if (*cp++ != ';')
|
||||
reset();
|
||||
(*rtdp)->data.ardef->indices->range_start = start;
|
||||
(*rtdp)->data.ardef->indices->range_end = end;
|
||||
cp = tdefdecl(cp, &((*rtdp)->data.ardef->contents));
|
||||
return (cp);
|
||||
}
|
||||
|
||||
enumdef(char *cp, struct tdesc **rtdp)
|
||||
{
|
||||
char *next;
|
||||
struct elist *elp, **prev;
|
||||
char *w;
|
||||
char linebuf[MAXLINE];
|
||||
|
||||
(*rtdp)->type = ENUM;
|
||||
|
||||
prev = &((*rtdp)->data.emem);
|
||||
while (*cp != ';') {
|
||||
elp = ALLOC(struct elist);
|
||||
*prev = elp;
|
||||
cp = name(cp, &w);
|
||||
elp->name = w;
|
||||
cp = number(cp, &elp->number);
|
||||
prev = &elp->next;
|
||||
if (*cp++ != ',')
|
||||
reset();
|
||||
if (*cp == '\\') {
|
||||
cp = fgets(linebuf, MAXLINE, stdin);
|
||||
while (*cp++ != '"')
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a node to the hash queues.
|
||||
*/
|
||||
void
|
||||
addhash(tdp, num)
|
||||
struct tdesc *tdp;
|
||||
int num;
|
||||
{
|
||||
int hash = HASH(num);
|
||||
|
||||
tdp->id = num;
|
||||
tdp->hash = hash_table[hash];
|
||||
hash_table[hash] = tdp;
|
||||
|
||||
if (tdp->name) {
|
||||
hash = compute_sum(tdp->name);
|
||||
tdp->next = name_table[hash];
|
||||
name_table[hash] = tdp;
|
||||
}
|
||||
}
|
||||
|
||||
struct tdesc *
|
||||
lookupname(name)
|
||||
char *name;
|
||||
{
|
||||
int hash = compute_sum(name);
|
||||
struct tdesc *tdp, *ttdp = NULL;
|
||||
|
||||
for (tdp = name_table[hash]; tdp != NULL; tdp = tdp->next) {
|
||||
if (tdp->name != NULL && strcmp(tdp->name, name) == 0) {
|
||||
if (tdp->type == STRUCT || tdp->type == UNION ||
|
||||
tdp->type == ENUM)
|
||||
return (tdp);
|
||||
if (tdp->type == TYPEOF)
|
||||
ttdp = tdp;
|
||||
}
|
||||
}
|
||||
return (ttdp);
|
||||
}
|
||||
|
||||
int
|
||||
compute_sum(char *w)
|
||||
{
|
||||
char c;
|
||||
int sum;
|
||||
|
||||
for (sum = 0; c = *w; sum += c, w++)
|
||||
;
|
||||
return (HASH(sum));
|
||||
}
|
||||
|
||||
reset()
|
||||
{
|
||||
longjmp(resetbuf, 1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
435
uts/sun4u/forthdebug/forthgen/stabs.c
Executable file
435
uts/sun4u/forthdebug/forthgen/stabs.c
Executable file
@@ -0,0 +1,435 @@
|
||||
|
||||
#include <math.h>
|
||||
#include "stabs.h"
|
||||
|
||||
char *convert_format();
|
||||
|
||||
int line;
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
parse_input();
|
||||
get_dbgs(argc, argv);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine will read the .dbg files and build a list of the structures
|
||||
* and fields that user is interested in. Any struct specified will get all
|
||||
* its fields included. If nested struct needs to be printed - then the
|
||||
* field name and name of struct type needs to be included in the next line.
|
||||
*/
|
||||
get_dbgs(int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
for (argc--, argv++; argc != 0; argc--, argv++) {
|
||||
if ((fp = fopen(*argv, "r")) == NULL)
|
||||
fprintf(stderr, "Cannot open %s\n", *argv);
|
||||
/* add all types in this file to our table */
|
||||
parse_dbg(fp);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
namex(char *cp, char **w)
|
||||
{
|
||||
char *new, *orig, c;
|
||||
int len;
|
||||
|
||||
for (c = *cp++; isspace(c); c = *cp++)
|
||||
;
|
||||
orig = --cp;
|
||||
c = *cp++;
|
||||
if (isalpha(c) || ispunct(c)) {
|
||||
for (c = *cp++; isalnum(c) || ispunct(c); c = *cp++)
|
||||
;
|
||||
len = cp - orig;
|
||||
new = (char *)malloc(len);
|
||||
while (orig < cp - 1)
|
||||
*new++ = *orig++;
|
||||
*new = '\0';
|
||||
*w = new - (len - 1);
|
||||
} else
|
||||
fprintf(stderr, "line %d has bad character %c\n", line, c);
|
||||
|
||||
return (cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* checks to see if this field in the struct was requested for by user
|
||||
* in the .dbg file.
|
||||
*/
|
||||
struct child *
|
||||
find_child(struct node *np, char *w)
|
||||
{
|
||||
struct child *chp;
|
||||
|
||||
for (chp = np->child; chp != NULL; chp = chp->next) {
|
||||
if (strcmp(chp->name, w) == 0)
|
||||
return (chp);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct tdesc *
|
||||
find_member(struct tdesc *tdp, char *name)
|
||||
{
|
||||
struct mlist *mlp;
|
||||
|
||||
while (tdp->type == TYPEOF)
|
||||
tdp = tdp->data.tdesc;
|
||||
if (tdp->type != STRUCT && tdp->type != UNION)
|
||||
return (NULL);
|
||||
for (mlp = tdp->data.members; mlp != NULL; mlp = mlp->next)
|
||||
if (strcmp(mlp->name, name) == 0)
|
||||
return (mlp->fdesc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* add this field to our table of structs/fields that the user has
|
||||
* requested in the .dbg files
|
||||
*/
|
||||
addchild(char *cp, struct node *np)
|
||||
{
|
||||
struct child *chp;
|
||||
char *w;
|
||||
|
||||
chp = ALLOC(struct child);
|
||||
cp = namex(cp, &w);
|
||||
chp->name = w;
|
||||
cp = namex(cp, &w);
|
||||
chp->format = w;
|
||||
chp->next = np->child;
|
||||
np->child = chp;
|
||||
}
|
||||
|
||||
/*
|
||||
* add this struct to our table of structs/fields that the user has
|
||||
* requested in the .dbg files
|
||||
*/
|
||||
struct node *
|
||||
getnode(char *cp)
|
||||
{
|
||||
char *w;
|
||||
struct node *np;
|
||||
int sum = 0;
|
||||
|
||||
cp = namex(cp, &w);
|
||||
np = ALLOC(struct node);
|
||||
np->name = w;
|
||||
np->child = NULL;
|
||||
return (np);
|
||||
}
|
||||
|
||||
/*
|
||||
* Format for .dbg files should be
|
||||
* Ex:
|
||||
* seg
|
||||
* as s_as
|
||||
* if you wanted the contents of "s_as" (a pointer) to be printed in
|
||||
* the format of a "as"
|
||||
*/
|
||||
parse_dbg(FILE *sp)
|
||||
{
|
||||
char *cp;
|
||||
struct node *np;
|
||||
static char linebuf[MAXLINE];
|
||||
int copy_flag = 0;
|
||||
|
||||
/* grab each line and add them to our table */
|
||||
for (line = 1; cp = fgets(linebuf, MAXLINE, sp); line++) {
|
||||
if (*cp == '\n') {
|
||||
if (copy_flag)
|
||||
printf("\n");
|
||||
continue;
|
||||
}
|
||||
if (*cp == '\\')
|
||||
continue;
|
||||
if (strcmp(cp, "forth_start\n") == 0) {
|
||||
copy_flag = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(cp, "forth_end\n") == 0) {
|
||||
copy_flag = 0;
|
||||
continue;
|
||||
}
|
||||
if (copy_flag) {
|
||||
printf("%s", cp);
|
||||
continue;
|
||||
}
|
||||
np = getnode(cp);
|
||||
for (line++;
|
||||
(cp = fgets(linebuf, MAXLINE, sp)) && *cp != '\n';
|
||||
line++) {
|
||||
/* members of struct, union or enum */
|
||||
addchild(cp, np);
|
||||
}
|
||||
printnode(np);
|
||||
}
|
||||
}
|
||||
|
||||
printnode(struct node *np)
|
||||
{
|
||||
struct tdesc *tdp;
|
||||
|
||||
tdp = lookupname(np->name);
|
||||
if (tdp == NULL) {
|
||||
char *member;
|
||||
struct tdesc *ptdp;
|
||||
|
||||
if (member = strchr(np->name, '.')) {
|
||||
*member = '\0';
|
||||
ptdp = lookupname(np->name);
|
||||
if (ptdp != NULL)
|
||||
tdp = find_member(ptdp, member + 1);
|
||||
*member = '.';
|
||||
}
|
||||
if (tdp == NULL) {
|
||||
fprintf(stderr, "Can't find %s\n", np->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
again:
|
||||
switch (tdp->type) {
|
||||
case STRUCT:
|
||||
case UNION:
|
||||
do_sou(tdp, np);
|
||||
break;
|
||||
case ENUM:
|
||||
do_enum(tdp, np);
|
||||
break;
|
||||
case TYPEOF:
|
||||
tdp = tdp->data.tdesc;
|
||||
goto again;
|
||||
default:
|
||||
fprintf(stderr, "%s isn't aggregate\n", np->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
do_sou(struct tdesc *tdp, struct node *np)
|
||||
{
|
||||
struct mlist *mlp;
|
||||
struct child *chp;
|
||||
char *name, *format;
|
||||
|
||||
printf("\n");
|
||||
printf("vocabulary %s-words\n", np->name);
|
||||
printf("%x ' %s-words c-struct .%s\n",
|
||||
tdp->size, np->name, np->name);
|
||||
printf("also %s-words definitions\n\n", np->name);
|
||||
|
||||
/*
|
||||
* Run thru all the fields of a struct and print them out
|
||||
*/
|
||||
for (mlp = tdp->data.members; mlp != NULL; mlp = mlp->next) {
|
||||
/*
|
||||
* If there's a child list, only print those members.
|
||||
*/
|
||||
if (np->child) {
|
||||
chp = find_child(np, mlp->name);
|
||||
if (chp == NULL)
|
||||
continue;
|
||||
format = chp->format;
|
||||
} else
|
||||
format = NULL;
|
||||
switch_on_type(mlp, mlp->fdesc, format, 0);
|
||||
}
|
||||
printf("\nkdbg-words definitions\n");
|
||||
printf("previous\n\n");
|
||||
printf("\\ end %s section\n\n", np->name);
|
||||
}
|
||||
|
||||
do_enum(struct tdesc *tdp, struct node *np)
|
||||
{
|
||||
int nelem = 0;
|
||||
struct elist *elp;
|
||||
|
||||
printf("\n");
|
||||
for (elp = tdp->data.emem; elp != NULL; elp = elp->next) {
|
||||
printf("here ,\" %s\" %x\n", elp->name, elp->number);
|
||||
nelem++;
|
||||
}
|
||||
printf("%x c-enum .%s\n", nelem, np->name);
|
||||
}
|
||||
|
||||
switch_on_type(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
switch (tdp->type) {
|
||||
|
||||
case INTRINSIC:
|
||||
print_intrinsic(mlp, tdp, format, level);
|
||||
break;
|
||||
case POINTER:
|
||||
print_pointer(mlp, tdp, format, level);
|
||||
break;
|
||||
case ARRAY:
|
||||
print_array(mlp, tdp, format, level);
|
||||
break;
|
||||
case FUNCTION:
|
||||
print_function(mlp, tdp, format, level);
|
||||
break;
|
||||
case UNION:
|
||||
print_union(mlp, tdp, format, level);
|
||||
break;
|
||||
case ENUM:
|
||||
print_enum(mlp, tdp, format, level);
|
||||
break;
|
||||
case FORWARD:
|
||||
print_forward(mlp, tdp, format, level);
|
||||
break;
|
||||
case TYPEOF:
|
||||
print_typeof(mlp, tdp, format, level);
|
||||
break;
|
||||
case STRUCT:
|
||||
print_struct(mlp, tdp, format, level);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Switch to Unknown type\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print_forward(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
fprintf(stderr, "%s never defined\n", mlp->name);
|
||||
}
|
||||
|
||||
print_typeof(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
switch_on_type(mlp, tdp->data.tdesc, format, level);
|
||||
}
|
||||
|
||||
print_intrinsic(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
format = convert_format(format, ".x");
|
||||
|
||||
if (level != 0)
|
||||
switch (tdp->size) {
|
||||
case 1:
|
||||
printf("' c@ ' %s", format);
|
||||
break;
|
||||
case 2:
|
||||
printf("' w@ ' %s", format);
|
||||
break;
|
||||
case 4:
|
||||
printf("' l@ ' %s", format);
|
||||
break;
|
||||
case 8:
|
||||
printf("' x@ ' %s", format);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Check for bit field.
|
||||
*/
|
||||
else if ((mlp->size % 8) != 0 || (mlp->offset % mlp->size) != 0) {
|
||||
int offset, shift, mask;
|
||||
|
||||
offset = (mlp->offset / 32) * 4;
|
||||
shift = 32 - ((mlp->offset % 32) + mlp->size);
|
||||
mask = ((int)pow(2, mlp->size) - 1) << shift;
|
||||
printf("' %s %x %x %x bits-field %s\n",
|
||||
format, shift, mask, offset, mlp->name);
|
||||
} else {
|
||||
switch (tdp->size) {
|
||||
case 1:
|
||||
printf("' %s %x byte-field %s\n",
|
||||
format, mlp->offset / 8, mlp->name);
|
||||
break;
|
||||
case 2:
|
||||
printf("' %s %x short-field %s\n",
|
||||
format, mlp->offset / 8, mlp->name);
|
||||
break;
|
||||
case 4:
|
||||
printf("' %s %x long-field %s\n",
|
||||
format, mlp->offset / 8, mlp->name);
|
||||
break;
|
||||
case 8:
|
||||
printf("' %s %x ext-field %s\n",
|
||||
format, mlp->offset / 8, mlp->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print_pointer(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
format = convert_format(format, ".x");
|
||||
if (level != 0)
|
||||
printf("' l@ ' %s", format);
|
||||
else {
|
||||
printf("' %s %x ptr-field %s\n",
|
||||
format, mlp->offset / 8, mlp->name);
|
||||
}
|
||||
}
|
||||
|
||||
print_array(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
struct ardef *ap = tdp->data.ardef;
|
||||
int items, inc, limit;
|
||||
|
||||
if (level != 0)
|
||||
fprintf(stderr, "");
|
||||
else {
|
||||
items = ap->indices->range_end - ap->indices->range_start + 1;
|
||||
inc = (mlp->size / items) / 8;
|
||||
limit = mlp->size / 8;
|
||||
switch_on_type(mlp, ap->contents, format, level + 1);
|
||||
printf(" %x %x %x", limit, inc, mlp->offset / 8);
|
||||
printf(" array-field %s\n", mlp->name);
|
||||
}
|
||||
}
|
||||
|
||||
print_function(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
fprintf(stderr, "function in struct %s\n", tdp->name);
|
||||
}
|
||||
|
||||
print_struct(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
format = convert_format(format, ".x");
|
||||
if (level != 0)
|
||||
printf("' noop ' %s", format);
|
||||
else {
|
||||
printf("' %s %x struct-field %s\n",
|
||||
format, mlp->offset / 8, mlp->name);
|
||||
}
|
||||
}
|
||||
|
||||
print_union(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
format = convert_format(format, ".x");
|
||||
if (level != 0)
|
||||
printf("' noop ' %s", format);
|
||||
else {
|
||||
printf("' %s %x struct-field %s\n",
|
||||
format, mlp->offset / 8, mlp->name);
|
||||
}
|
||||
}
|
||||
|
||||
print_enum(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
|
||||
{
|
||||
format = convert_format(format, ".d");
|
||||
|
||||
if (level != 0)
|
||||
printf("' l@ ' %s", format);
|
||||
else
|
||||
printf("' %s %x long-field %s\n",
|
||||
format, mlp->offset / 8, mlp->name);
|
||||
}
|
||||
|
||||
char *
|
||||
convert_format(char *format, char *dfault)
|
||||
{
|
||||
static char dot[3] = ".";
|
||||
|
||||
if (format == NULL)
|
||||
return (dfault);
|
||||
else if (strlen(format) == 1) {
|
||||
dot[1] = *format;
|
||||
return (dot);
|
||||
} else
|
||||
return (format);
|
||||
}
|
||||
101
uts/sun4u/forthdebug/forthgen/stabs.h
Executable file
101
uts/sun4u/forthdebug/forthgen/stabs.h
Executable file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 1994, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_STABS_H
|
||||
#define _SYS_STABS_H
|
||||
|
||||
#pragma ident "@(#)stabs.h 1.7 95/03/16 SMI"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAXLINE 1024
|
||||
|
||||
#define BUCKETS 128
|
||||
|
||||
struct tdesc *hash_table[BUCKETS];
|
||||
struct tdesc *name_table[BUCKETS];
|
||||
|
||||
struct node {
|
||||
char *name;
|
||||
struct child *child;
|
||||
};
|
||||
|
||||
struct child {
|
||||
char *name;
|
||||
char *format;
|
||||
struct child *next;
|
||||
};
|
||||
|
||||
#define HASH(NUM) ((int)(NUM & (BUCKETS - 1)))
|
||||
|
||||
enum type {
|
||||
INTRINSIC,
|
||||
POINTER,
|
||||
ARRAY,
|
||||
FUNCTION,
|
||||
STRUCT,
|
||||
UNION,
|
||||
ENUM,
|
||||
FORWARD,
|
||||
TYPEOF,
|
||||
};
|
||||
|
||||
struct tdesc {
|
||||
char *name;
|
||||
struct tdesc *next;
|
||||
enum type type;
|
||||
int size;
|
||||
union {
|
||||
struct tdesc *tdesc; /* *, f , to */
|
||||
struct ardef *ardef; /* ar */
|
||||
struct mlist *members; /* s, u */
|
||||
struct elist *emem; /* e */
|
||||
} data;
|
||||
int id;
|
||||
struct tdesc *hash;
|
||||
};
|
||||
|
||||
struct elist {
|
||||
char *name;
|
||||
int number;
|
||||
struct elist *next;
|
||||
};
|
||||
|
||||
struct element {
|
||||
struct tdesc *index_type;
|
||||
int range_start;
|
||||
int range_end;
|
||||
};
|
||||
|
||||
struct ardef {
|
||||
struct tdesc *contents;
|
||||
struct element *indices;
|
||||
};
|
||||
|
||||
struct mlist {
|
||||
int offset;
|
||||
int size;
|
||||
char *name;
|
||||
struct mlist *next;
|
||||
struct tdesc *fdesc; /* s, u */
|
||||
};
|
||||
|
||||
#define ALLOC(t) ((t *)malloc(sizeof (t)))
|
||||
|
||||
struct tdesc *lookupname();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_STABS_H */
|
||||
Reference in New Issue
Block a user