summaryrefslogtreecommitdiff
path: root/usr.bin/nm/byte.c
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>1999-05-10 16:14:08 +0000
committerMarc Espie <espie@cvs.openbsd.org>1999-05-10 16:14:08 +0000
commitd077e4952475b4d4eb95c5c1298b066e30faa111 (patch)
treef544fb34e49e353bf75db63355cf162028859746 /usr.bin/nm/byte.c
parentc606ee6a29b096ead9a5b55824175725213f4afe (diff)
Fixes endianess problems with old a.out tools. This makes building
some cross toolchains possible. This also changes some utilities's behavior slightly: - nm, strip, size now handle any a.out format they know about. - ranlib complains if it detects mixed archives (several object formats for different boxes). In the presence of mixed objects, you still have file, ranlib or ld to prevent you from getting too confused...
Diffstat (limited to 'usr.bin/nm/byte.c')
-rw-r--r--usr.bin/nm/byte.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/usr.bin/nm/byte.c b/usr.bin/nm/byte.c
new file mode 100644
index 00000000000..7aa2408f9e4
--- /dev/null
+++ b/usr.bin/nm/byte.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: byte.c,v 1.1 1999/05/10 16:14:07 espie Exp $ */
+/*
+ * Copyright (c) 1999
+ * Marc Espie. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ */
+
+/* a set of routines to read object files and compensate for host
+ * endianness
+ */
+
+
+static int byte_sex(mid)
+ int mid;
+{
+ switch(mid) {
+ case MID_I386:
+ case MID_VAX:
+ case MID_ALPHA:
+ case MID_PMAX:
+ return LITTLE_ENDIAN;
+ case MID_M68K:
+ case MID_M68K4K:
+ case MID_M88K:
+ case MID_SUN010:
+ case MID_SUN020:
+ case MID_HP200:
+ case MID_HP300:
+ case MID_HPUX800:
+ case MID_HPUX:
+ case MID_SPARC:
+ case MID_MIPS:
+ return BIG_ENDIAN;
+ default: /* we don't know what this is, so we don't want to process it */
+ return 0;
+ }
+}
+
+#define BAD_OBJECT(h) (N_BADMAG(h) || !byte_sex(N_GETMID(h)))
+
+/* handles endianess swaps */
+static void swap_u32s(h, n)
+ u_int32_t *h;
+ size_t n;
+{
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ h[i] = swap32(h[i]);
+}
+
+static void fix_header_order(h)
+ struct exec *h;
+{
+ if (byte_sex(N_GETMID(*h)) != BYTE_ORDER)
+ swap_u32s( ((u_int32_t *)(h))+1, sizeof *h/sizeof(u_int32_t) - 1);
+}
+
+static long fix_long_order(l, mid)
+ long l;
+ int mid;
+{
+ if (byte_sex(mid) != BYTE_ORDER)
+ return swap32(l);
+ else
+ return l;
+}
+
+static void swap_nlist(p)
+ struct nlist *p;
+{
+ p->n_un.n_strx = swap32(p->n_un.n_strx);
+ p->n_desc = swap16(p->n_desc);
+ p->n_value = swap32(p->n_value);
+}
+
+static void fix_nlist_order(p, mid)
+ struct nlist *p;
+ int mid;
+{
+ if (byte_sex(mid) != BYTE_ORDER)
+ swap_nlist(p);
+}
+
+static void fix_nlists_order(p, n, mid)
+ struct nlist *p;
+ size_t n;
+ int mid;
+{
+ int i;
+
+ if (byte_sex(mid) != BYTE_ORDER)
+ for (i = 0; i < n; i++)
+ swap_nlist(p+i);
+}
+
+static fix_ranlib_order(r, mid)
+ struct ranlib *r;
+ int mid;
+{
+ if (byte_sex(mid) != BYTE_ORDER) {
+ r->ran_un.ran_strx = swap32(r->ran_un.ran_strx);
+ r->ran_off = swap32(r->ran_off);
+ }
+}