summaryrefslogtreecommitdiffstats
path: root/src/usr/trace
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/trace')
-rw-r--r--src/usr/trace/interface.C5
-rw-r--r--src/usr/trace/runtime/rt_service.C119
-rw-r--r--src/usr/trace/service.C1
-rw-r--r--src/usr/trace/service.H2
4 files changed, 120 insertions, 7 deletions
diff --git a/src/usr/trace/interface.C b/src/usr/trace/interface.C
index 5ca18db37..947ae4eb9 100644
--- a/src/usr/trace/interface.C
+++ b/src/usr/trace/interface.C
@@ -84,13 +84,14 @@ namespace TRACE
}
void trace_adal_write_bin(ComponentDesc * io_td,
- const trace_hash_val i_hash,
+ const traceCodeInfo* i_info,
const uint32_t i_line,
const void * i_ptr,
const uint32_t i_size,
const uint32_t i_type)
{
- Singleton<Service>::instance().writeBinEntry(io_td, i_hash, i_line,
+ Singleton<Service>::instance().writeBinEntry(io_td, i_info->hash,
+ i_info->format, i_line,
i_ptr, i_size, i_type);
}
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;
+ }
}
diff --git a/src/usr/trace/service.C b/src/usr/trace/service.C
index ad9105499..05938d920 100644
--- a/src/usr/trace/service.C
+++ b/src/usr/trace/service.C
@@ -208,6 +208,7 @@ namespace TRACE
void Service::writeBinEntry(ComponentDesc* i_td,
trace_hash_val i_hash,
+ const char * i_fmt,
uint32_t i_line,
const void* i_ptr,
uint32_t i_size,
diff --git a/src/usr/trace/service.H b/src/usr/trace/service.H
index 61e9bc494..e1d4f1aba 100644
--- a/src/usr/trace/service.H
+++ b/src/usr/trace/service.H
@@ -107,6 +107,7 @@ namespace TRACE
* @param[in] i_td - Component Descriptor to write to.
*
* @param[in] i_hash - Hash value.
+ * @param[in] i_fmt - Printf-style format string.
* @param[in] i_line - Line number.
* @param[in] i_ptr - Data to write.
* @param[in] i_size - Bytes to write.
@@ -114,6 +115,7 @@ namespace TRACE
*/
void writeBinEntry(ComponentDesc* i_td,
trace_hash_val i_hash,
+ const char * i_fmt,
uint32_t i_line,
const void* i_ptr,
uint32_t i_size,
OpenPOWER on IntegriCloud