# # 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 # Hammerhead: amd64-only 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 # # 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. # # Copyright 2015 RackTop Systems. # # Copyright (c) 2018, Joyent, Inc. PROGS = adbgen1 adbgen3 adbgen4 OBJS = adbsub.o SCRIPTS = adbgen CLOBBERFILES = $(PROGS) $(OBJS) $(SCRIPTS) .PARALLEL: $(PROGS) $(OBJS) $(SCRIPTS) .KEEP_STATE: include ../../Makefile.cmd include ../../Makefile.targ # not linted SMATCH=off 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 $@ $< $(LDLIBS) $(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) # # 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) #! /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] " 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 /* * 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. */ /* * 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 #include #include #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] < \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 \n"); printf("#include \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 * 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 */ } /* * 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. */ /* * Post-process adb script. * All we do is collapse repeated formats into number*format. * E.g. XXX is collapsed to 3X. */ #include #include #include 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); } /* * 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. */ /* * 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 #include #include #include #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); } /* * 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) 1983-1998 by Sun Microsystems, Inc. * All rights reserved. */ /* * Subroutines to be called by adbgen2.c, the C program generated * by adbgen1.c. */ #include #include #include 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); } }