--- /dev/null
+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(§ion, 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);
+}