summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2013-09-20 12:39:54 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-10-08 21:24:27 -0500
commitcf3d24d5e0d78e4e8fe1c155a7c556164ae42a51 (patch)
tree7592703a4504d7860af0d9a81872ef17b29104d7
parentaa0428221628fdb25c980f5764a3b4400004ee5d (diff)
downloadtalos-hostboot-cf3d24d5e0d78e4e8fe1c155a7c556164ae42a51.tar.gz
talos-hostboot-cf3d24d5e0d78e4e8fe1c155a7c556164ae42a51.zip
Runtime trace interfaces.
Change-Id: Ie261eba4bd790150d520bb0261f56c8329cb6a80 RTC: 79420 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/6400 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rwxr-xr-xsrc/include/string.h3
-rw-r--r--src/include/usr/trace/interface.H4
-rw-r--r--src/include/usr/trace/trace.H4
-rw-r--r--src/lib/string.C55
-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
8 files changed, 158 insertions, 35 deletions
diff --git a/src/include/string.h b/src/include/string.h
index 62e6107d7..8fa88044f 100755
--- a/src/include/string.h
+++ b/src/include/string.h
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2010,2012 */
+/* COPYRIGHT International Business Machines Corp. 2010,2013 */
/* */
/* p1 */
/* */
@@ -40,6 +40,7 @@ extern "C"
char* strcpy(char* d, const char* s);
int strcmp(const char* s1, const char* s2) __attribute__((pure));
size_t strlen(const char* s1) __attribute__((pure));
+ size_t strnlen(const char* s1, size_t n) __attribute__((pure));
char* strcat(char* d, const char* s);
char* strncat(char* d, const char* s, size_t n);
diff --git a/src/include/usr/trace/interface.H b/src/include/usr/trace/interface.H
index 6b7dee2f7..aa2909315 100644
--- a/src/include/usr/trace/interface.H
+++ b/src/include/usr/trace/interface.H
@@ -163,7 +163,7 @@ const uint32_t TRACE_FIELD = 0; //Indicates trace is field
{ \
__TRACE_HASH_STRUCTURES(printf_string); \
TRACE::trace_adal_write_bin((des), \
- __traceData_codeInfo.hash, \
+ &__traceData_codeInfo, \
__LINE__, \
address, \
len, \
@@ -218,7 +218,7 @@ const uint32_t TRACE_FIELD = 0; //Indicates trace is field
{ \
__TRACE_HASH_STRUCTURES(printf_string); \
TRACE::trace_adal_write_bin((des), \
- __traceData_codeInfo.hash, \
+ &__traceData_codeInfo, \
__LINE__, \
address, \
len, \
diff --git a/src/include/usr/trace/trace.H b/src/include/usr/trace/trace.H
index ffbf3a5cb..d4f05b381 100644
--- a/src/include/usr/trace/trace.H
+++ b/src/include/usr/trace/trace.H
@@ -130,7 +130,7 @@ namespace TRACE
* name of this function as is.
*
* @param [in,out] io_td Trace descriptor of buffer to write to.
- * @param [in] i_hash Descriptive string hash value
+ * @param [in] i_info Info struct for the hash and format string.
* @param [in] i_line Line number trace was done at
* @param [in] i_ptr Pointer to binary data
* @param [in] i_size Size of binary data
@@ -139,7 +139,7 @@ namespace TRACE
* @return void
*/
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,
diff --git a/src/lib/string.C b/src/lib/string.C
index 18cfec530..52c54a56b 100644
--- a/src/lib/string.C
+++ b/src/lib/string.C
@@ -1,26 +1,25 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/lib/string.C $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2011-2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/lib/string.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2011,2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
#include <string.h>
extern "C" void *memset(void *vdest, int ch, size_t len)
@@ -202,6 +201,16 @@ extern "C" size_t strlen(const char* a)
return length;
}
+extern "C" size_t strnlen(const char* s, size_t n)
+{
+ size_t length = 0;
+ while((length < n) && (*s++))
+ {
+ length++;
+ }
+ return length;
+}
+
extern "C" char* strcat(char* d, const char* s)
{
char* _d = d;
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