summaryrefslogtreecommitdiffstats
path: root/src/usr/trace/runtime/rt_service.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/trace/runtime/rt_service.C')
-rw-r--r--src/usr/trace/runtime/rt_service.C119
1 files changed, 114 insertions, 5 deletions
diff --git a/src/usr/trace/runtime/rt_service.C b/src/usr/trace/runtime/rt_service.C
index 2bb697d3e..e7eda7280 100644
--- a/src/usr/trace/runtime/rt_service.C
+++ b/src/usr/trace/runtime/rt_service.C
@@ -25,10 +25,15 @@
#include <limits.h>
#include <assert.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
#include <runtime/interface.h>
namespace TRACE
{
+ // Value was chosen empirically from trace lengths during the IPL.
+ static const size_t DEFAULT_TRACE_LENGTH = 128;
Service::Service()
{
@@ -55,14 +60,34 @@ namespace TRACE
}
}
- char output[KILOBYTE];
- vsprintf(output, i_fmt, i_args); // TODO: RTC 79420 :
- // Potential buffer overrun.
- g_hostInterfaces->puts(output);
+ size_t compName_len = strnlen(i_td->iv_compName,
+ sizeof(i_td->iv_compName));
+
+ char output[DEFAULT_TRACE_LENGTH];
+ memcpy(output, i_td->iv_compName, compName_len);
+ output[compName_len] = ':';
+ size_t length = vsnprintf(&output[compName_len+1],
+ DEFAULT_TRACE_LENGTH-(compName_len+1),
+ i_fmt, i_args);
+
+ if (unlikely((compName_len + 1 + length + 1) > DEFAULT_TRACE_LENGTH))
+ {
+ char* long_output = new char[compName_len + 1 + length + 1];
+ memcpy(long_output, i_td->iv_compName, compName_len);
+ long_output[compName_len] = ':';
+ vsprintf(&long_output[compName_len+1], i_fmt, i_args);
+ g_hostInterfaces->puts(long_output);
+ delete[] long_output;
+ }
+ else
+ {
+ g_hostInterfaces->puts(output);
+ }
}
void Service::writeBinEntry(ComponentDesc* i_td,
trace_hash_val i_hash,
+ const char * i_fmt,
uint32_t i_ine,
const void* i_ptr,
uint32_t i_size,
@@ -76,7 +101,91 @@ namespace TRACE
}
}
- // TODO: RTC 79420
+ size_t compName_len = strnlen(i_td->iv_compName,
+ sizeof(i_td->iv_compName));
+
+ // Output header.
+ char output[DEFAULT_TRACE_LENGTH];
+ memcpy(output, i_td->iv_compName, compName_len);
+ output[compName_len] = ':';
+ size_t length = vsnprintf(&output[compName_len+1],
+ DEFAULT_TRACE_LENGTH-(compName_len+1),
+ i_fmt, NULL);
+
+ if(unlikely((compName_len + 1 + length + 1) > DEFAULT_TRACE_LENGTH))
+ {
+ char* long_output = new char[compName_len + length + 1];
+ memcpy(long_output, i_td->iv_compName, compName_len);
+ long_output[compName_len] = ':';
+ vsprintf(&long_output[compName_len+1], i_fmt, NULL);
+ g_hostInterfaces->puts(long_output);
+ delete[] long_output;
+ }
+ else
+ {
+ g_hostInterfaces->puts(output);
+ }
+
+ // Output binary data.
+ // Format is:
+ // ~[0x0000] 01234567 01234567 01234567 01234567 *012345689abcdef*
+ static size_t BINARY_FORMAT_LENGTH =
+ 68 + sizeof(ComponentDesc::iv_compName) + 1;
+
+ size_t pos = 0;
+ while (pos < i_size)
+ {
+ char bin_output[BINARY_FORMAT_LENGTH];
+ memcpy(bin_output, i_td->iv_compName, compName_len);
+ size_t output_pos = compName_len +
+ sprintf(&bin_output[compName_len],
+ ":~[0x%04hx]", (int) pos);
+
+ for (int i = 0; i < 16; ++i)
+ {
+ if ((i % 4) == 0)
+ {
+ bin_output[output_pos++] = ' ';
+ }
+ if ((pos + i) < i_size)
+ {
+ output_pos +=
+ sprintf(&bin_output[output_pos], "%02x",
+ ((const char*)i_ptr)[pos+i]);
+ }
+ else
+ {
+ bin_output[output_pos++] = ' ';
+ bin_output[output_pos++] = ' ';
+ }
+ }
+
+ for (int i = 0; i < 4; i++)
+ {
+ bin_output[output_pos++] = ' ';
+ }
+ bin_output[output_pos++] = '*';
+
+ for (int i = 0; i < 16; ++i)
+ {
+ char ch = ' ';
+ if ((pos + i) < i_size)
+ {
+ ch = ((const char*) i_ptr)[pos+i];
+ if (!isprint(ch))
+ {
+ ch = '.';
+ }
+ }
+ bin_output[output_pos++] = ch;
+ }
+ bin_output[output_pos++] = '*';
+ bin_output[output_pos++] = '\0';
+
+ g_hostInterfaces->puts(bin_output);
+
+ pos += 16;
+ }
}
OpenPOWER on IntegriCloud