summaryrefslogtreecommitdiff
path: root/linkers/rtems-utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linkers/rtems-utils.cpp')
-rw-r--r--linkers/rtems-utils.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/linkers/rtems-utils.cpp b/linkers/rtems-utils.cpp
new file mode 100644
index 0000000..8fda105
--- /dev/null
+++ b/linkers/rtems-utils.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2012, Chris Johns <chrisj@rtems.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * @file
+ *
+ * @ingroup RLD
+ *
+ * @brief A memory dump routine.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iomanip>
+#include <iostream>
+#include <vector>
+
+#include <rtems-utils.h>
+
+namespace rtems
+{
+ namespace utils
+ {
+ void
+ dump (const void* addr,
+ size_t length,
+ size_t size,
+ bool real,
+ size_t line_length,
+ uint32_t offset)
+ {
+ char* data;
+ size_t b = 0;
+ uint8_t d8 = 0;
+ uint16_t d16 = 0;
+ uint32_t d32 = 0;
+ uint64_t d64 = 0;
+
+ const uint8_t* addr8 = static_cast <const uint8_t*> (addr);
+
+ data = new char[line_length];
+
+ try
+ {
+ std::cout << std::hex << std::setfill ('0');
+
+ while (true)
+ {
+ if (((b % line_length) == 0) || (b >= length))
+ {
+ if (b)
+ {
+ size_t line = b % line_length;
+
+ if (line)
+ {
+ size_t remaining = line_length - line;
+ remaining = (remaining * 2) + (remaining / size);
+ std::cout << std::setfill (' ')
+ << std::setw (remaining) << ' '
+ << std::setfill ('0');
+ }
+ else
+ line = line_length;
+
+ std::cout << ' ';
+
+ for (size_t c = 0; c < line; c++)
+ {
+ if ((data[c] < 0x20) || (data[c] > 0x7e))
+ std::cout << '.';
+ else
+ std::cout << data[c];
+ }
+
+ if (b >= length)
+ {
+ std::cout << std::dec << std::setfill (' ')
+ << std::endl << std::flush;
+ break;
+ }
+
+ std::cout << std::endl;
+ }
+
+ if (real)
+ std::cout << std::setw (sizeof(void*)) << (uint64_t) (addr8 + b);
+ else
+ std::cout << std::setw (8) << (uint32_t) (offset + b);
+ }
+
+ if ((b & (line_length - 1)) == (line_length >> 1))
+ std::cout << "-";
+ else
+ std::cout << " ";
+
+ switch (size)
+ {
+ case sizeof (uint8_t):
+ default:
+ d8 = *(addr8 + b);
+ std::cout << std::setw (2) << (uint32_t) d8;
+ data[(b % line_length) + 0] = d8;
+ break;
+
+ case sizeof (uint16_t):
+ d16 = *((const uint16_t*) (addr8 + b));
+ std::cout << std::setw (4) << d16;
+ data[(b % line_length) + 0] = (uint8_t) (d16 >> 8);
+ data[(b % line_length) + 1] = (uint8_t) d16;
+ break;
+
+ case sizeof (uint32_t):
+ d32 = *((const uint32_t*) (addr8 + b));
+ std::cout << std::setw (8) << d32;
+ for (int i = sizeof (uint32_t); i > 0; --i)
+ {
+ data[(b % line_length) + i] = (uint8_t) d32;
+ d32 >>= 8;
+ }
+ break;
+
+ case sizeof (uint64_t):
+ d64 = *((const uint64_t*) (addr8 + b));
+ std::cout << std::setw (16) << d64;
+ for (int i = sizeof (uint64_t); i > 0; --i)
+ {
+ data[(b % line_length) + i] = (uint8_t) d64;
+ d64 >>= 8;
+ }
+ break;
+ }
+ b += size;
+ }
+ }
+ catch (...)
+ {
+ delete [] data;
+ throw;
+ }
+
+ delete [] data;
+
+ std::cout << std::dec << std::setfill (' ');
+ }
+ }
+}