Browse Source

Initial revision

ceriel 37 years ago
parent
commit
9a3d983659
1 changed files with 214 additions and 0 deletions
  1. 214 0
      util/amisc/ashow.c

+ 214 - 0
util/amisc/ashow.c

@@ -0,0 +1,214 @@
+static char	rcsid[] = "$Header$";
+/*
+ * show - make the contents of an ACK object file human readable.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <out.h>
+
+#define OK	0	/* Return value of gethead if Orl Korekt. */
+#define BMASK	0xFF	/* To extract least significant 8 bits from an int. */
+
+/* ARGSUSED */
+main(argc, argv)
+	int	argc;
+	char	*argv[];
+#		define prog	argv[0]
+{
+	register char	**arg = argv;
+	struct outhead	header;
+
+	while (*++arg) {
+		if (! rd_open(*arg)) {
+			error("%s: cannot read %s\n", prog, *arg);
+			continue;
+		}
+		rd_ohead(&header);
+		if (BADMAGIC(header)) {
+			error("%s: %s not an ACK object file\n", prog, *arg);
+		} else {
+			printf("%s:\n", *arg);
+			show(&header);
+		}
+		rd_close();
+	}
+}
+
+/*
+ * Read an ACK object file from `fp' and show it in a human readable way.
+ * NB. The header has already been read and is in the struct outhead `headp'
+ * points to.
+ */
+show(headp)
+	register struct outhead	*headp;
+{
+	register int		i;
+	register struct outname	*np;
+	register struct outname	*name;	/* Dynamically allocated name-array. */
+	register char		*string;/* Base of string area. */
+	extern char		*myalloc();
+
+	printf("Version %d\n", headp->oh_stamp);
+	showflags(headp->oh_flags);
+	/*
+	 * Show all sections.
+	 */
+	for (i = 0; i < headp->oh_nsect; i++) {
+		printf("Section %d:\n", i);
+		showsect();
+	}
+	/*
+	 * Show relocation information.
+	 */
+	for (i = 0; i < headp->oh_nrelo; i++) {
+		printf("Relocation record %d:\n", i);
+		showrelo();
+	}
+	/*
+	 * We get all struct outname's and the strings in core first.
+	 */
+	name = (struct outname *) myalloc(headp->oh_nname * SZ_NAME);
+	string = myalloc((unsigned) headp->oh_nchar);
+	for (np = &name[0]; np < &name[headp->oh_nname]; np++) {
+		rd_name(np, 1);
+		if (np->on_foff != 0)
+			np->on_mptr = string + np->on_foff - OFF_CHAR(*headp);
+/* 			                  	  Weird:  ^^^^^^^^^^^^^^^^^^^ */
+	}
+	/*
+	 * Transfer strings from file to core.
+	 */
+	rd_string(string, headp->oh_nchar);
+	/*
+	 * Now we can show all names.
+	 */
+	for (np = &name[0]; np < &name[headp->oh_nname]; np++) {
+		printf("Name %d:\n", np - name);
+		showname(np);
+	}
+}
+
+/*
+ * Show flags from header.
+ */
+showflags(flagword)
+	ushort	flagword;
+{
+	if (flagword & HF_LINK) printf("unresolved references left\n");
+}
+
+/*
+ * Show a section.
+ */
+showsect()
+{
+	struct outsect	section;
+
+	rd_sect(&section, 1);
+	printf("\tstartaddress in machine\t%ld\n",	section.os_base);
+	printf("\tsection size in machine\t%ld\n",	section.os_size);
+	printf("\tstartaddress in file\t%ld\n",		section.os_foff);
+	printf("\tsection size in file\t%ld\n",		section.os_flen);
+	printf("\tsection alignment\t%ld\n",		section.os_lign);
+}
+
+/*
+ * Show a relocation record.
+ */
+showrelo()
+{
+	struct outrelo	relrec;
+
+	rd_relo(&relrec, 1);
+	switch (relrec.or_type & RELSZ) {
+	case RELO1:
+		printf("\t1 byte\n");
+		break;
+	case RELO2:
+		printf("\t2 bytes\n");
+		break;
+	case RELO4:
+		printf("\t4 bytes\n");
+		break;
+	default:
+		error("\tunexpected relocation length\n");
+		break;
+	}
+	if (relrec.or_type & RELPC) printf("\tpc relative\n");
+	if (relrec.or_type & RELBR) printf("\tbytes reversed\n");
+	if (relrec.or_type & RELWR) printf("\twords reversed\n");
+	printf("\treferencing section\t%d\n", (relrec.or_sect & BMASK) - S_MIN);
+	printf("\treferenced symbol index\t%d\n", relrec.or_nami);
+	printf("\treferencing address\t%ld\n", relrec.or_addr);
+}
+
+/*
+ * Show the name in the struct `namep' points to.
+ */
+showname(namep)
+	struct outname	*namep;
+{
+	if (namep->on_mptr)
+		printf("\t%s\n", namep->on_mptr);
+	else
+		printf("\tno name\n");
+	switch (namep->on_type & S_TYP) {
+	case S_UND:
+		printf("\tundefined\n");
+		break;
+	case S_ABS:
+		printf("\tabsolute\n");
+		break;
+	default:
+		printf("\tin section %ld\n", (namep->on_type & S_TYP) - S_MIN);
+		break;
+	}
+	if (namep->on_type & S_EXT) printf("\texternal\n");
+	switch (namep->on_type & S_ETC) {
+	case S_SCT:
+		printf("\tsection name\n"); break;
+	case S_LIN:
+		printf("\thll source line item\n"); break;
+	case S_FIL:
+		printf("\thll source file item\n"); break;
+	case S_MOD:
+		printf("\tass src file item\n"); break;
+	case S_COM:
+		printf("\tcommon\n"); break;
+	}
+	printf("\tvalue %ld\n", namep->on_valu);
+}
+
+/*
+ * Core allocation via malloc() but fatal if no core.
+ */
+char *
+myalloc(u)
+	unsigned int	u;
+{
+	register char	*rcp;
+	extern char	*malloc();
+
+	rcp = malloc(u);
+	if (rcp == (char *) 0) {
+		error("Out of core\n");
+		exit(1);
+	}
+	return rcp;
+}
+
+/* VARARGS1 */
+error(s, a1, a2, a3, a4)
+	char	*s;
+{
+	fflush(stdout);
+	fprintf(stderr, s, a1, a2, a3, a4);
+}
+
+rd_fatal()
+{
+	error("Error in reading the object file\n");
+	exit(1);
+}