[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Endian options for "od"
From: |
dcoffin |
Subject: |
Endian options for "od" |
Date: |
Sun, 27 Nov 2005 02:57:59 -0500 |
User-agent: |
Mutt/1.5.9i |
Hello,
It's well-known that "od" displays different output
depending on whether your CPU is big-endian or little-endian.
With this simple patch, "od -I" is little-endian on all CPUs,
and "od -M" is big-endian. (Think "Intel" and "Motorola").
This patch is very useful for reading files with the
"wrong" byte order. "dd conv=swab" only works with shorts,
not ints, floats, or doubles.
"od" with neither option uses CPU byte order (same as
before), while "od -I -M" uses the opposite of CPU order.
Dave Coffin 11/27/2005
--- od.c 2005-09-23 16:13:49.000000000 -0400
+++ od.c 2005-11-27 02:41:12.000000000 -0500
@@ -222,6 +222,9 @@
input is formatted. */
static bool limit_bytes_to_format = false;
+/* When true, reverse the byte order of numeric data. */
+static bool byte_swap = false;
+
/* The maximum number of bytes that will be formatted. */
static uintmax_t max_bytes_to_format;
@@ -271,7 +274,7 @@
#define MAX_FP_TYPE_SIZE sizeof (LONG_DOUBLE)
static enum size_spec fp_type_size[MAX_FP_TYPE_SIZE + 1];
-static char const short_options[] = "A:aBbcDdeFfHhIij:LlN:OoS:st:vw::Xx";
+static char const short_options[] = "A:aBbcDdeFfHhIij:LlMN:OoS:st:vw::Xx";
/* For long options that have no equivalent short option, use a
non-character as a pseudo short option, starting with CHAR_MAX + 1. */
@@ -285,6 +288,8 @@
{"skip-bytes", required_argument, NULL, 'j'},
{"address-radix", required_argument, NULL, 'A'},
{"read-bytes", required_argument, NULL, 'N'},
+ {"little-endian", no_argument, NULL, 'I'},
+ {"big-endian", no_argument, NULL, 'M'},
{"format", required_argument, NULL, 't'},
{"output-duplicates", no_argument, NULL, 'v'},
{"strings", optional_argument, NULL, 'S'},
@@ -327,6 +332,8 @@
fputs (_("\
-N, --read-bytes=BYTES limit dump to BYTES input bytes\n\
-S, --strings[=BYTES] output strings of at least BYTES graphic chars\n\
+ -I, --little-endian force Intel (little-endian) byte order\n\
+ -M, --big-endian force Motorola (big-endian) byte order\n\
-t, --format=TYPE select output format or formats\n\
-v, --output-duplicates do not use * to mark line suppression\n\
-w, --width[=BYTES] output BYTES bytes per output line\n\
@@ -1194,7 +1201,8 @@
}
else
{
- size_t i;
+ size_t i, j, width;
+ char *disp_block;
prev_pair_equal = false;
for (i = 0; i < n_specs; i++)
@@ -1203,7 +1211,14 @@
format_address (current_offset, '\0');
else
printf ("%*s", address_pad_len, "");
- (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
+ if (byte_swap && (disp_block = xmalloc (n_bytes))) {
+ width = width_bytes[spec[i].size];
+ for (j=0; j < n_bytes; j++)
+ disp_block[j] = curr_block[j + width-1 - j % width * 2];
+ (*spec[i].print_function) (n_bytes, disp_block, spec[i].fmt_string);
+ free (disp_block);
+ } else
+ (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
if (spec[i].hexl_mode_trailer)
{
/* space-pad out to full line width, then dump the trailer */
@@ -1682,6 +1697,18 @@
flag_dump_strings = true;
break;
+ case 'I':
+#ifdef WORDS_BIGENDIAN
+ byte_swap = true;
+#endif
+ break;
+
+ case 'M':
+#ifndef WORDS_BIGENDIAN
+ byte_swap = true;
+#endif
+ break;
+
case 't':
modern = true;
ok &= decode_format_string (optarg);
@@ -1719,7 +1746,7 @@
case 'X': /* obsolescent and undocumented alias */
CASE_OLD_ARG ('H', "x4"); /* obsolescent and undocumented */
CASE_OLD_ARG ('i', "dI");
- case 'I': case 'L': /* obsolescent and undocumented aliases */
+ case 'L': /* obsolescent and undocumented alias */
CASE_OLD_ARG ('l', "dL");
CASE_OLD_ARG ('O', "o4"); /* obsolesent and undocumented */
case 'B': /* obsolescent and undocumented alias */
- Endian options for "od",
dcoffin <=