+struct tynames {
+ int ty_value;
+ char *ty_name;
+} tynames[] = {
+ N_UNDF, "undefined",
+ N_ABS, "absolute",
+ N_TEXT, "text",
+ N_DATA, "data",
+ N_BSS, "bss",
+ N_COMM, "common",
+ 0, 0,
+};
+
+tracesym()
+{
+ register struct tynames *tp;
+
+ if (cursym.n_type & N_STAB)
+ return;
+ printf("%s", filname);
+ if (archdr.ar_name[0])
+ printf("(%s)", archdr.ar_name);
+ printf(": ");
+ if ((cursym.n_type&N_TYPE) == N_UNDF && cursym.n_value) {
+ printf("definition of common %s size %d\n",
+ cursym.n_un.n_name, cursym.n_value);
+ return;
+ }
+ for (tp = tynames; tp->ty_name; tp++)
+ if (tp->ty_value == (cursym.n_type&N_TYPE))
+ break;
+ printf((cursym.n_type&N_TYPE) ? "definition of" : "reference to");
+ if (cursym.n_type&N_EXT)
+ printf(" external");
+ if (tp->ty_name)
+ printf(" %s", tp->ty_name);
+ printf(" %s\n", cursym.n_un.n_name);
+}
+
+#if !defined(tahoe)
+/* for machines which allow arbitrarily aligned word and longword accesses */
+#define getw(cp) (*(short *)(cp))
+#define getl(cp) (*(long *)(cp))
+#define putw(cp, w) (*(short *)(cp) = (w))
+#define putl(cp, l) (*(long *)(cp) = (l))
+#else
+short
+getw(cp)
+ char *cp;
+{
+ union {
+ short w;
+ char c[2];
+ } w;
+
+ w.c[0] = *cp++;
+ w.c[1] = *cp++;
+ return (w.w);
+}
+
+getl(cp)
+ char *cp;
+{
+ union {
+ long l;
+ char c[4];
+ } l;
+
+ l.c[0] = *cp++;
+ l.c[1] = *cp++;
+ l.c[2] = *cp++;
+ l.c[3] = *cp++;
+ return (l.l);
+}
+
+putw(cp, v)
+ char *cp;
+ short v;
+{
+ union {
+ short w;
+ char c[2];
+ } w;
+
+ w.w = v;
+ *cp++ = w.c[0];
+ *cp++ = w.c[1];
+}
+
+putl(cp, v)
+ char *cp;
+ long v;
+{
+ union {
+ long l;
+ char c[4];
+ } l;
+
+ l.l = v;
+ *cp++ = l.c[0];
+ *cp++ = l.c[1];
+ *cp++ = l.c[2];
+ *cp++ = l.c[3];
+}
+#endif
+
+/*
+ * This routine relocates the single text or data segment argument.
+ * Offsets from external symbols are resolved by adding the value
+ * of the external symbols. Non-external reference are updated to account
+ * for the relative motion of the segments (ctrel, cdrel, ...). If
+ * a relocation was pc-relative, then we update it to reflect the
+ * change in the positioning of the segments by adding the displacement
+ * of the referenced segment and subtracting the displacement of the
+ * current segment (creloc).
+ *
+ * If we are saving the relocation information, then we increase
+ * each relocation datum address by our base position in the new segment.
+ */
+load2td(creloc, position, b1, b2)
+ long creloc, position;