summaryrefslogtreecommitdiff
path: root/usr/src/cmd/adbgen/common/adbsub.c
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/adbgen/common/adbsub.c
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/adbgen/common/adbsub.c')
-rw-r--r--usr/src/cmd/adbgen/common/adbsub.c230
1 files changed, 230 insertions, 0 deletions
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);
+ }
+}