diff options
| author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
|---|---|---|
| committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
| commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
| tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/adbgen | |
| download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz | |
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/adbgen')
| -rw-r--r-- | usr/src/cmd/adbgen/Makefile | 52 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/Makefile.com | 81 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/amd64/Makefile | 35 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/common/adbgen.sh | 104 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/common/adbgen1.c | 604 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/common/adbgen3.c | 82 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/common/adbgen4.c | 148 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/common/adbsub.c | 230 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/i386/Makefile | 29 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/sparc/Makefile | 29 | ||||
| -rw-r--r-- | usr/src/cmd/adbgen/sparcv9/Makefile | 35 |
11 files changed, 1429 insertions, 0 deletions
diff --git a/usr/src/cmd/adbgen/Makefile b/usr/src/cmd/adbgen/Makefile new file mode 100644 index 0000000000..28880692be --- /dev/null +++ b/usr/src/cmd/adbgen/Makefile @@ -0,0 +1,52 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.cmd + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +.PARALLEL: $(SUBDIRS) + +all := TARGET = all +install := TARGET = install +clean := TARGET = clean +clobber := TARGET = clobber + +.KEEP_STATE: + +all install clean clobber: $(SUBDIRS) + +lint: + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/cmd/adbgen/Makefile.com b/usr/src/cmd/adbgen/Makefile.com new file mode 100644 index 0000000000..16e859da99 --- /dev/null +++ b/usr/src/cmd/adbgen/Makefile.com @@ -0,0 +1,81 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +PROGS = adbgen1 adbgen3 adbgen4 +OBJS = adbsub.o +SCRIPTS = adbgen + +CLOBBERFILES = $(PROGS) $(OBJS) $(SCRIPTS) + +.PARALLEL: $(PROGS) $(OBJS) $(SCRIPTS) +.KEEP_STATE: + +include ../../Makefile.cmd + +ROOTADBDIR32 = $(ROOT)/usr/lib/adb +ROOTADBDIR64 = $(ROOT)/usr/lib/adb/$(MACH64) +ROOTADBDIR = $(ROOTADBDIR32) + +ROOTPROGS = $(PROGS:%=$(ROOTADBDIR)/%) +ROOTOBJS = $(OBJS:%=$(ROOTADBDIR)/%) +ROOTSCRIPTS = $(SCRIPTS:%=$(ROOTADBDIR)/%) + +FILEMODE = 0644 +$(ROOTPROGS) $(ROOTSCRIPTS) := FILEMODE = 0755 + +all: $$(PROGS) $$(OBJS) $$(SCRIPTS) +install: $$(ROOTPROGS) $$(ROOTOBJS) $$(ROOTSCRIPTS) + +clean: + +adbgen%: ../common/adbgen%.c + $(LINK.c) -o $@ $< + $(POST_PROCESS) + +%.o: ../common/%.c + $(COMPILE.c) -c -o $@ $< + $(POST_PROCESS_O) + +%: ../common/%.sh + $(RM) $@ + cat $< >$@ + chmod +x $@ + +$(ROOTADBDIR32)/%: % $(ROOTADBDIR32) + $(INS.file) + +$(ROOTADBDIR64)/%: % $(ROOTADBDIR64) + $(INS.file) + +$(ROOTADBDIR32): + $(INS.dir) + +$(ROOTADBDIR64): $(ROOTADBDIR32) + $(INS.dir) + +include ../../Makefile.targ diff --git a/usr/src/cmd/adbgen/amd64/Makefile b/usr/src/cmd/adbgen/amd64/Makefile new file mode 100644 index 0000000000..98369f820f --- /dev/null +++ b/usr/src/cmd/adbgen/amd64/Makefile @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com +include ../../Makefile.cmd.64 + +PROGS = +SCRIPTS = + +ROOTADBDIR = $(ROOTADBDIR64) diff --git a/usr/src/cmd/adbgen/common/adbgen.sh b/usr/src/cmd/adbgen/common/adbgen.sh new file mode 100644 index 0000000000..c1014898cd --- /dev/null +++ b/usr/src/cmd/adbgen/common/adbgen.sh @@ -0,0 +1,104 @@ +#! /bin/sh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 1998 by Sun Microsystems, Inc. +# All rights reserved. +# +# ident "%Z%%M% %I% %E% SMI" +# +USAGE="adbgen [-d] [-m ilp32|lp64] [-w] <adb macro file>" +cflags= +mflag=-milp32 +subdir= + +while getopts dwm: c +do + case $c in + d) + DEBUG=: + ;; + m) + case $OPTARG in + ilp32) + mflag=-milp32 + ;; + lp64) + mflag=-mlp64 + cflags=-xarch=v9 + subdir=sparcv9 + /usr/bin/optisa sparcv9 > /dev/null + if [ $? -ne 0 ] + then + echo adbgen -mlp64 must be run on 64-bit system + fi + ;; + *) + echo $USAGE + exit 2 + ;; + esac + ;; + w) + flag=-w + ;; + \?) + echo $USAGE + exit 2 + ;; + esac +done +shift `expr $OPTIND - 1` + +ADBDIR=/usr/lib/adb +PATH=$PATH:$ADBDIR +for file in $* +do + if [ `expr "XX$file" : ".*\.adb"` -eq 0 ] + then + echo File $file invalid. + exit 1 + fi + if [ $# -gt 1 ] + then + echo $file: + fi + file=`expr "XX$file" : "XX\(.*\)\.adb"` + if adbgen1 $flag $mflag < $file.adb > $file.adb.c + then + if ${CC:-cc} -w -D${ARCH:-`uname -m`} $cflags \ + -I/usr/share/src/uts/${ARCH:-`uname -m`} \ + -o $file.run $file.adb.c $ADBDIR/$subdir/adbsub.o + then + $file.run | adbgen3 | adbgen4 > $file + $DEBUG rm -f $file.run $file.adb.C $file.adb.c $file.adb.o + else + $DEBUG rm -f $file.run $file.adb.C $file.adb.c $file.adb.o + echo compile failed + exit 1 + fi + else + $DEBUG rm -f $file.adb.C + echo adbgen1 failed + exit 1 + fi +done diff --git a/usr/src/cmd/adbgen/common/adbgen1.c b/usr/src/cmd/adbgen/common/adbgen1.c new file mode 100644 index 0000000000..99cd6412fa --- /dev/null +++ b/usr/src/cmd/adbgen/common/adbgen1.c @@ -0,0 +1,604 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Read in "high-level" adb script and emit C program. + * The input may have specifications within {} which + * we analyze and then emit C code to generate the + * ultimate adb acript. + * We are just a filter; no arguments are accepted. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define streq(s1, s2) (strcmp(s1, s2) == 0) + +#define LINELEN 1024 /* max line length expected in input */ +#define STRLEN 128 /* for shorter strings */ +#define NARGS 5 /* number of emitted subroutine arguments */ + +/* + * Format specifier strings + * which are recognized by adbgen when surrounded by {} + */ +#define FSTR_PTR "POINTER" +#define FSTR_LONG_DEC "LONGDEC" +#define FSTR_LONG_OCT "LONGOCT" +#define FSTR_ULONG_DEC "ULONGDEC" +#define FSTR_ULONG_HEX "ULONGHEX" +#define FSTR_ULONG_OCT "ULONGOCT" + +/* + * Types of specifications in {}. + */ +#define PTR_HEX 0 /* emit hex pointer format char */ +#define LONG_DEC 1 /* emit decimal long format char */ +#define LONG_OCT 2 /* emit octal unsigned long format char */ +#define ULONG_DEC 3 /* emit decimal unsigned long format char */ +#define ULONG_HEX 4 /* emit hexadecimal long format char */ +#define ULONG_OCT 5 /* emit octal unsigned long format char */ + +#define FMT_ENTRIES 6 /* number of adbgen format specifier strings */ + +#define PRINT 6 /* print member name with format */ +#define INDIRECT 7 /* fetch member value */ +#define OFFSETOK 8 /* insist that the offset is ok */ +#define SIZEOF 9 /* print sizeof struct */ +#define END 10 /* get offset to end of struct */ +#define OFFSET 11 /* just emit offset */ +#define EXPR 12 /* arbitrary C expression */ + +/* + * Special return code from nextchar. + */ +#define CPP -2 /* cpp line, restart parsing */ + +typedef struct adbgen_fmt { + char *f_str; + char f_char; +} adbgen_fmt_t; + +char struct_name[STRLEN]; /* struct name */ +char member[STRLEN]; /* member name */ +char format[STRLEN]; /* adb format spec */ +char arg[NARGS][STRLEN]; /* arg list for called subroutine */ +char *ptr_hex_fmt; /* adb format character for pointer in hex */ +char *long_dec_fmt; /* adb format character for long in decimal */ +char *ulong_dec_fmt; /* adb format character for ulong in decimal */ +char *ulong_hex_fmt; /* adb format character for ulong in hex */ +char *long_oct_fmt; /* adb format character for long in octal */ +char *ulong_oct_fmt; /* adb format character for ulong in octal */ + +int line_no = 1; /* input line number - for error messages */ +int specsize; /* size of {} specification - 1 or 2 parts */ +int state; /* XXX 1 = gathering a printf */ + /* This is a kludge so we emit pending */ + /* printf's when we see a CPP line */ + +adbgen_fmt_t adbgen_fmt_tbl [FMT_ENTRIES] = { + {FSTR_PTR}, + {FSTR_LONG_DEC}, + {FSTR_LONG_OCT}, + {FSTR_ULONG_DEC}, + {FSTR_ULONG_HEX}, + {FSTR_ULONG_OCT} +}; + +void emit_call(char *name, int nargs); +void emit_end(void); +void emit_expr(void); +void emit_indirect(void); +void emit_offset(void); +void emit_offsetok(void); +void emit_print(void); +void emit_printf(char *cp); +void emit_sizeof(void); +void generate(void); +int get_type(void); +int nextchar(char *cp); +void read_spec(void); +char *start_printf(void); + +int +main(int argc, char **argv) +{ + char *cp; + int c; + int warn_flag = 0; + int is_lp64 = 0; + char *usage = "adbgen1 [-w] [-m ilp32|lp64] < <macro file>\n"; + + while ((c = getopt(argc, argv, "m:w")) != EOF) { + switch (c) { + case 'm': + if (streq(optarg, "ilp32")) + is_lp64 = 0; + else if (streq(optarg, "lp64")) + is_lp64 = 1; + else + fprintf(stderr, usage); + break; + case 'w': + warn_flag++; + break; + case '?': + fprintf(stderr, usage); + break; + } + } + if (is_lp64) { + adbgen_fmt_tbl[PTR_HEX].f_char = 'J'; + adbgen_fmt_tbl[LONG_DEC].f_char = 'e'; + adbgen_fmt_tbl[LONG_OCT].f_char = 'g'; + adbgen_fmt_tbl[ULONG_DEC].f_char = 'E'; + adbgen_fmt_tbl[ULONG_HEX].f_char = 'J'; + adbgen_fmt_tbl[ULONG_OCT].f_char = 'G'; + } else { + adbgen_fmt_tbl[PTR_HEX].f_char = 'X'; + adbgen_fmt_tbl[LONG_DEC].f_char = 'D'; + adbgen_fmt_tbl[LONG_OCT].f_char = 'Q'; + adbgen_fmt_tbl[ULONG_DEC].f_char = 'U'; + adbgen_fmt_tbl[ULONG_HEX].f_char = 'X'; + adbgen_fmt_tbl[ULONG_OCT].f_char = 'O'; + } + + /* + * Get structure name. + */ + cp = struct_name; + while ((c = nextchar(NULL)) != '\n') { + if (c == EOF) { + fprintf(stderr, "Premature EOF\n"); + exit(1); + } + if (c == CPP) + continue; + *cp++ = (char)c; + } + *cp = '\0'; + /* + * Basically, the generated program is just an ongoing printf + * with breaks for {} format specifications. + */ + printf("\n"); + printf("#include <sys/types.h>\n"); + printf("#include <sys/inttypes.h>\n"); + printf("\n\n"); + printf("int do_fmt(char *acp);\n"); + printf("void format(char *name, size_t size, char *fmt);\n"); + printf("void indirect(off_t offset, size_t size, " + "char *base, char *member);\n"); + printf("void offset(off_t off);\n"); + printf("void offsetok(void);\n"); + printf("\n\n"); + printf("main(int argc, char *argv[])\n"); + printf("{\n"); + if (warn_flag) { + printf("\textern int warnings;\n\n\twarnings = 0;\n"); + } + cp = start_printf(); + while ((c = nextchar(cp)) != EOF) { + switch (c) { + case '"': + *cp++ = '\\'; /* escape ' in string */ + *cp++ = '"'; + break; + case '\n': + *cp++ = '\\'; /* escape newline in string */ + *cp++ = 'n'; + break; + case '{': + emit_printf(cp); + read_spec(); + generate(); + cp = start_printf(); + break; + case CPP: + /* + * Restart printf after cpp line. + */ + cp = start_printf(); + break; + default: + *cp++ = c; + break; + } + if (cp - arg[1] >= STRLEN - 10) { + emit_printf(cp); + cp = start_printf(); + } + } + emit_printf(cp); + + /* terminate program, checking for "error" mode */ + printf("\n\tif (argc > 1 && strcmp(argv[1], \"-e\") == 0) {\n"); + printf("\t\textern int warns;\n\n"); + printf("\t\tif (warns)\n"); + printf("\t\t\treturn (1);\n"); + printf("\t}\n"); + printf("\treturn (0);\n"); + printf("}\n"); + + return (0); +} + +int +nextchar(char *cp) +{ + int c; + static int newline = 1; + + c = getchar(); + /* + * Lines beginning with '#' and blank lines are passed right through. + */ + while (newline) { + switch (c) { + case '#': + if (state) + emit_printf(cp); + do { + putchar(c); + c = getchar(); + if (c == EOF) + return (c); + } while (c != '\n'); + putchar(c); + line_no++; + return (CPP); + case '\n': + if (state) + emit_printf(cp); + putchar(c); + c = getchar(); + line_no++; + break; + default: + newline = 0; + break; + } + } + if (c == '\n') { + newline++; + line_no++; + } + return (c); +} + +/* + * Get started on printf of ongoing adb script. + */ +char * +start_printf(void) +{ + char *cp; + + strcpy(arg[0], "\"%s\""); + cp = arg[1]; + *cp++ = '"'; + state = 1; /* XXX */ + return (cp); +} + +/* + * Emit call to printf to print part of ongoing adb script. + */ +void +emit_printf(cp) + char *cp; +{ + *cp++ = '"'; + *cp = '\0'; + emit_call("printf", 2); + state = 0; /* XXX */ +} + +/* + * Read {} specification. + * The first part (up to a comma) is put into "member". + * The second part, if present, is put into "format". + */ +void +read_spec(void) +{ + char *cp; + int c; + int nesting; + + cp = member; + specsize = 1; + nesting = 0; + while ((c = nextchar(NULL)) != '}' || (c == '}' && nesting)) { + switch (c) { + case EOF: + fprintf(stderr, "Unexpected EOF inside {}\n"); + exit(1); + case '\n': + fprintf(stderr, "Newline not allowed in {}, line %d\n", + line_no); + exit(1); + case '#': + fprintf(stderr, "# not allowed in {}, line %d\n", + line_no); + exit(1); + case ',': + if (specsize == 2) { + fprintf(stderr, "Excessive commas in {}, "); + fprintf(stderr, "line %d\n", line_no); + exit(1); + } + specsize = 2; + *cp = '\0'; + cp = format; + break; + case '{': + /* + * Allow up to one set of nested {}'s for adbgen + * requests of the form {member, {format string}} + */ + if (!nesting) { + nesting = 1; + *cp++ = c; + } else { + fprintf(stderr, "Too many {'s, line %d\n", + line_no); + exit(1); + } + break; + case '}': + *cp++ = c; + nesting = 0; + break; + default: + *cp++ = c; + break; + } + } + *cp = '\0'; + if (cp == member) { + specsize = 0; + } +} + +/* + * Decide what type of input specification we have. + */ +int +get_type(void) +{ + int i; + + if (specsize == 1) { + if (streq(member, "SIZEOF")) { + return (SIZEOF); + } + if (streq(member, "OFFSETOK")) { + return (OFFSETOK); + } + if (streq(member, "END")) { + return (END); + } + for (i = 0; i < FMT_ENTRIES; i++) + if (streq(member, adbgen_fmt_tbl[i].f_str)) + return (i); + return (OFFSET); + } + if (specsize == 2) { + if (member[0] == '*') { + return (INDIRECT); + } + if (streq(member, "EXPR")) { + return (EXPR); + } + return (PRINT); + } + fprintf(stderr, "Invalid specification, line %d\n", line_no); + exit(1); +} + +/* + * Generate the appropriate output for an input specification. + */ +void +generate(void) +{ + char *cp; + int type; + + type = get_type(); + + switch (type) { + case PTR_HEX: + case LONG_DEC: + case LONG_OCT: + case ULONG_DEC: + case ULONG_HEX: + case ULONG_OCT: + cp = start_printf(); + *cp++ = adbgen_fmt_tbl[type].f_char; + emit_printf(cp); + break; + case PRINT: + emit_print(); + break; + case OFFSET: + emit_offset(); + break; + case INDIRECT: + emit_indirect(); + break; + case OFFSETOK: + emit_offsetok(); + break; + case SIZEOF: + emit_sizeof(); + break; + case EXPR: + emit_expr(); + break; + case END: + emit_end(); + break; + default: + fprintf(stderr, "Internal error in generate\n"); + exit(1); + } +} + +/* + * Emit calls to set the offset and print a member. + */ +void +emit_print(void) +{ + char *cp; + char fmt_request[STRLEN]; + int i; + char number[STRLEN]; + + emit_offset(); + /* + * Emit call to "format" subroutine + */ + sprintf(arg[0], "\"%s\"", member); + sprintf(arg[1], "sizeof ((struct %s *)0)->%s", + struct_name, member); + + /* + * Split the format string into <number><format character string> + * This is for format strings that contain format specifier requests + * like {POINTER_HEX}, {LONG_DEC}, etc. which need to be substituted + * with a format character instead. + */ + for (cp = format, i = 0; *cp >= '0' && *cp <= '9' && *cp != '\0'; + cp++, i++) + number[i] = *cp; + number[i] = '\0'; + + for (i = 0; i < FMT_ENTRIES; i++) { + (void) sprintf(fmt_request, "{%s}", adbgen_fmt_tbl[i].f_str); + if (streq(cp, fmt_request)) { + sprintf(arg[2], "\"%s%c\"", + number, adbgen_fmt_tbl[i].f_char); + break; + } + } + if (i == FMT_ENTRIES) + sprintf(arg[2], "\"%s\"", format); + + emit_call("format", 3); +} + +/* + * Emit calls to set the offset and print a member. + */ +void +emit_offset(void) +{ + /* + * Emit call to "offset" subroutine + */ + sprintf(arg[0], "(off_t) &(((struct %s *)0)->%s)", + struct_name, member); + emit_call("offset", 1); +} + +/* + * Emit call to indirect routine. + */ +void +emit_indirect(void) +{ + sprintf(arg[0], "(off_t) &(((struct %s *)0)->%s)", + struct_name, member+1); + sprintf(arg[1], "sizeof ((struct %s *)0)->%s", struct_name, member+1); + sprintf(arg[2], "\"%s\"", format); /* adb register name */ + sprintf(arg[3], "\"%s\"", member); + emit_call("indirect", 4); +} + +/* + * Emit call to "offsetok" routine. + */ +void +emit_offsetok(void) +{ + emit_call("offsetok", 0); +} + +/* + * Emit call to printf the sizeof the structure. + */ +void +emit_sizeof(void) +{ + sprintf(arg[0], "\"0t%%d\""); + sprintf(arg[1], "sizeof (struct %s)", struct_name); + emit_call("printf", 2); +} + +/* + * Emit call to printf an arbitrary C expression. + */ +void +emit_expr(void) +{ + sprintf(arg[0], "\"0t%%d\""); + sprintf(arg[1], "(%s)", format); + emit_call("printf", 2); +} + +/* + * Emit call to set offset to end of struct. + */ +void +emit_end(void) +{ + sprintf(arg[0], "sizeof (struct %s)", struct_name); + emit_call("offset", 1); +} + +/* + * Emit call to subroutine name with nargs arguments from arg array. + */ +void +emit_call(char *name, int nargs) +{ + int i; + + printf("\t%s(", name); /* name of subroutine */ + for (i = 0; i < nargs; i++) { + if (i > 0) { + printf(", "); /* argument separator */ + } + printf("%s", arg[i]); /* argument */ + } + printf(");\n"); /* end of call */ +} diff --git a/usr/src/cmd/adbgen/common/adbgen3.c b/usr/src/cmd/adbgen/common/adbgen3.c new file mode 100644 index 0000000000..c98df9d797 --- /dev/null +++ b/usr/src/cmd/adbgen/common/adbgen3.c @@ -0,0 +1,82 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Post-process adb script. + * All we do is collapse repeated formats into number*format. + * E.g. XXX is collapsed to 3X. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main() +{ + int c, quote, paren, savec, count, dispcmd; + + savec = count = 0; + quote = 0; /* not in quoted string */ + paren = 0; /* not in parenthesized string */ + dispcmd = 0; /* not in display command */ + while ((c = getchar()) != EOF) { + if (c == '"') { + quote = !quote; + } else if (c == '(') { + paren++; + } else if (c == ')') { + paren--; + } else if (c == '/' || c == '?') { + dispcmd = 1; + } else if (c == '\n') { + dispcmd = 0; + } + if (c == savec) { + count++; + continue; + } + if (savec) { + if (count > 1) { + printf("%d", count); + } + putchar(savec); + savec = 0; + } + if (quote == 0 && paren == 0 && dispcmd && + strchr("KJFXOQDUfYpPxoqdubcC+IaAtrn-", c)) { + savec = c; + count = 1; + } else { + putchar(c); + } + } + if (savec) + putchar(savec); + return (0); +} diff --git a/usr/src/cmd/adbgen/common/adbgen4.c b/usr/src/cmd/adbgen/common/adbgen4.c new file mode 100644 index 0000000000..ee389bba66 --- /dev/null +++ b/usr/src/cmd/adbgen/common/adbgen4.c @@ -0,0 +1,148 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Post-process adb scripts to move increment and decrement around. + * The reason is that at the start of each +/ line, adb prints out + * the current location. If the line then increments or decrements + * dot before printing the user may be confused. So we move the + * increment or decrement to the preceeding line. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#define BUFSIZE 1024 /* gross enough to never be exceeded (we hope) */ + +char buf1[BUFSIZE], buf2[BUFSIZE]; + +static char *scanpastnum(char *); +static int goodstart(char *); + +int +main() +{ + char *cur, *last, *cp1, *cp2, *ep, *t; + int len; + + gets(buf1); + last = buf1; + cur = buf2; + while (gets(cur) != NULL) { + if (goodstart(cur) && goodstart(last)) { + /* + * Scan cur for initial increment. + * Ignore quoted strings, tabbing, adb newlines. + */ + cp1 = cur + 2; + while (*cp1) { + if (*cp1 == '"') { + /* scan past quoted string */ + while (*++cp1 && *cp1 != '"') + ; + cp1++; + continue; + } + if (*cp1 >= '0' && *cp1 <= '9') { + cp2 = scanpastnum(cp1); + } else { + cp2 = cp1; + } + if (*cp2 == 't' || *cp2 == 'n' || + *cp2 == ' ') { + /* ok to skip over this one */ + cp1 = cp2 + 1; + continue; + } else { + break; + } + } + /* + * Cp1 now points at the first non-quoted string and + * non adb tab specification. + * Now determine if it's an increment or decrement. + */ + cp2 = scanpastnum(cp1); + if (*cp2 == '+' || *cp2 == '-') { + /* + * This is what we were hoping to find. + * Move increment or decrement into last. + */ + cp2++; + ep = last + strlen(last); + len = cp2 - cp1; + strncpy(ep, cp1, len); + ep[len] = '\0'; + /* + * Remove it from cur. + */ + strcpy(cp1, cp2); + } + } + /* + * Prepare for next iteration. + */ + puts(last); + t = cur; + cur = last; + last = t; + } + puts(last); + return (0); +} + +/* + * Cp points at a digit. + * Return pointer to next char that isn't a digit. + */ +static char * +scanpastnum(char *cp1) +{ + char *cp2; + + for (cp2 = cp1; isdigit(*cp2); cp2++) + ; + return (cp2); +} + +/* + * Check whether a line has a good starting string. + * We need ./ or +/ at the beginning to even think + * of doing this motion stuff. + */ +static int +goodstart(char *cp) +{ + if (*cp == '.' || *cp == '+') { + if (*++cp == '/') + return (1); + } + return (0); +} diff --git a/usr/src/cmd/adbgen/common/adbsub.c b/usr/src/cmd/adbgen/common/adbsub.c new file mode 100644 index 0000000000..d9b7a37273 --- /dev/null +++ b/usr/src/cmd/adbgen/common/adbsub.c @@ -0,0 +1,230 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Copyright (c) 1983-1998 by Sun Microsystems, Inc. + * All rights reserved. + */ + +/* + * Subroutines to be called by adbgen2.c, the C program generated + * by adbgen1.c. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> + +off_t last_off; +int warnings = 1; +int warns = 0; + +/* + * User claims offset is ok. + * This usually follows call to another script, which we cannot handle. + */ +void +offsetok(void) +{ + last_off = -1; +} + +/* + * Get adb.s dot to the right offset. + */ +void +offset(off_t off) +{ + off_t off_diff; + + if (last_off == -1) { + last_off = off; + return; + } + off_diff = off - last_off; + if (off_diff) { + if (off_diff > 0) { + if (off_diff > 1) { + printf("%ld", off_diff); + } + printf("+"); + } + if (off_diff < 0) { + if (off_diff < -1) { + printf("%ld", -off_diff); + } + printf("-"); + } + } + last_off = off; +} + +/* + * Emit the format command, return the size. + */ +int +do_fmt(char *acp) +{ + int rcount, width, sum, i; + char *cp; + + cp = acp; + sum = rcount = 0; + do { + while (*cp >= '0' && *cp <= '9') { + rcount = rcount * 10 + *cp++ - '0'; + } + if (rcount == 0) { + rcount = 1; + } + switch (*cp) { + case 'e': + case 'E': + case 'F': + case 'g': + case 'G': + case 'J': + width = 8; + break; + case 'K': +#ifdef _LP64 + width = 8; +#else /* _LP64 */ + width = 4; +#endif /* _LP64 */ + break; + case 'X': + case 'O': + case 'Q': + case 'D': + case 'U': + case 'f': + case 'Y': + case 'p': + case 'P': + width = 4; + break; + case 'x': + case 'o': + case 'q': + case 'd': + case 'u': + width = 2; + break; + case 'v': + case 'V': + case 'b': + case 'B': + case 'c': + case 'C': + case '+': + width = 1; + break; + case 'I': + case 'a': + case 'A': + case 't': + case 'r': + case 'n': + width = 0; + break; + case '-': + width = -1; + break; + case 's': + case 'S': + case 'i': + if (warnings) { + fprintf(stderr, + "Unknown format size \"%s\", assuming zero\n", + acp); + warns++; + } + width = 0; + break; + default: + fprintf(stderr, "Unknown format size: %s\n", acp); + exit(1); + } + for (i = 0; i < rcount; i++) { + putchar(*cp); + } + cp++; + sum += width * rcount; + } while (*cp); + return (sum); +} + +/* + * Format struct member, checking size. + */ +void +format(char *name, size_t size, char *fmt) +{ + int fs; + + fs = do_fmt(fmt); + if (fs != size && warnings) { + fprintf(stderr, + "warning: \"%s\" size is %ld, \"%s\" width is %d\n", + name, size, fmt, fs); + warns++; + } + last_off += fs; +} + +/* + * Get the value at offset based on base. + */ +void +indirect(off_t offset, size_t size, char *base, char *member) +{ + if (size == 8 || size == 4) { + if (offset == 0) { + printf("*%s", base); + } else { + printf("*(%s+0t%ld)", base, offset); + } + } else if (size == 2) { + if (offset == 2) { + printf("(*%s&0xffff)", base); + } else { + printf("(*(%s+0t%ld)&0xffff)", base, offset - 2); + } + } else if (size == 1) { + if (offset == 3) { + printf("(*%s&0xff)", base); + } else { + if ((offset & 0x1) == 0x1) { + printf("(*(%s+0t%ld)&0xff)", base, offset - 3); + } else { + printf("((*(%s+0t%ld)&0xff00)/0x100)", + base, offset - 2); + } + } + } else { + fprintf(stderr, "Indirect size %ld not 1, 2, or 4: %s\n", + size, member); + exit(1); + } +} diff --git a/usr/src/cmd/adbgen/i386/Makefile b/usr/src/cmd/adbgen/i386/Makefile new file mode 100644 index 0000000000..340f45b60c --- /dev/null +++ b/usr/src/cmd/adbgen/i386/Makefile @@ -0,0 +1,29 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com diff --git a/usr/src/cmd/adbgen/sparc/Makefile b/usr/src/cmd/adbgen/sparc/Makefile new file mode 100644 index 0000000000..340f45b60c --- /dev/null +++ b/usr/src/cmd/adbgen/sparc/Makefile @@ -0,0 +1,29 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com diff --git a/usr/src/cmd/adbgen/sparcv9/Makefile b/usr/src/cmd/adbgen/sparcv9/Makefile new file mode 100644 index 0000000000..98369f820f --- /dev/null +++ b/usr/src/cmd/adbgen/sparcv9/Makefile @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com +include ../../Makefile.cmd.64 + +PROGS = +SCRIPTS = + +ROOTADBDIR = $(ROOTADBDIR64) |
