summaryrefslogtreecommitdiffstats
path: root/src/include/usr/gcov.h
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2012-09-19 14:23:54 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-10-09 17:06:49 -0500
commitfb1836fd7b1b8839815595db08ae740ec7b86347 (patch)
tree54ff93536489c27b80af1f503520bd9894cdcfd3 /src/include/usr/gcov.h
parent84e4274fe412a577f67805cc701f4fb66a3feb2f (diff)
downloadtalos-hostboot-fb1836fd7b1b8839815595db08ae740ec7b86347.tar.gz
talos-hostboot-fb1836fd7b1b8839815595db08ae740ec7b86347.zip
Support code coverage in extended modules.
- Reduce optimization (to -Os) to fit when doing coverage profile. - Remove errl storage area from base image. - Add GCC function attributes to sys library functions. RTC: 36933 Change-Id: Ic83011a2444ef5b735db0446a14a0af34187eebf Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1908 Tested-by: Jenkins Server Reviewed-by: Brian H. Horton <brianh@linux.ibm.com> Reviewed-by: ADAM R. MUHLE <armuhle@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: Melissa J. Connell <missyc@us.ibm.com> Reviewed-by: Paul Nguyen <nguyenp@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/include/usr/gcov.h')
-rw-r--r--src/include/usr/gcov.h141
1 files changed, 112 insertions, 29 deletions
diff --git a/src/include/usr/gcov.h b/src/include/usr/gcov.h
index dd249e1d5..a8e20f4fc 100644
--- a/src/include/usr/gcov.h
+++ b/src/include/usr/gcov.h
@@ -1,25 +1,25 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/include/usr/gcov.h $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 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
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/gcov.h $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 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 otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
#ifndef __USR_GCOV_H
#define __USR_GCOV_H
@@ -37,31 +37,54 @@
*/
#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
/** @struct gcov_info
* @brief Structure generated by gcc. Do not use.
*
* This structure is automatically generated and instances of it created by
* gcc when the --coverage compile option is used. We don't need to
- * manipulate this structure from code except to fix up the chains as objects
- * are added to the chain. The rest of this structure is parsed by the
- * Gcov.pm debug tool.
+ * manipulate this structure from code except:
+ * 1) To fix up the chains as objects are added to the chain.
+ * 2) To copy the gcov_info and counters into the base-chain when we
+ * unload a module.
+ *
+ * The rest of this structure is parsed by the Gcov.pm debug tool.
+ *
+ * Most of the items in here are used as uint32_t's by gcov but are still
+ * aligned on a 64-bit boundary. The unusedN fields are to ensure proper
+ * alignment.
*/
struct gcov_info
{
- unsigned int version; // Purposefully chose 'unsigned int' to match gcc.
+ uint32_t version;
+ uint32_t unused0;
gcov_info* next;
- // Really there is more after here in the structure, but this is all
- // we care about from an in-memory perspective.
-};
+ uint32_t timestamp;
+ uint32_t unused1;
+ char* filename;
+ uint32_t n_functions;
+ uint32_t unused2;
+ void* functions;
+ uint32_t counter_mask;
+ uint32_t unused3;
+ uint32_t n_counters;
+ uint32_t unused4;
+ uint64_t* counters;
+} PACKED;
// Preprocessor magic to create a variable name based off the module name.
// GCOV_INFO_OBJ() will create a post-processed name like
// 'foobar_gcov_info_head' or 'core_gcov_info_head'.
#ifdef __HOSTBOOT_MODULE
#define __GCOV_PREFIX __HOSTBOOT_MODULE
+ #define ___GCOV_STRINGIFY(X) #X
+ #define __GCOV_STRINGIFY(X) ___GCOV_STRINGIFY(X)
+ #define __GCOV_PREFIX_NAME __GCOV_STRINGIFY(__HOSTBOOT_MODULE)
#else
#define __GCOV_PREFIX core
+ #define __GCOV_PREFIX_NAME "core"
#endif
#define __GCOV_INFO_OBJ(X,Y) X ## Y
@@ -85,6 +108,66 @@ void __gcov_init(gcov_info* i_info)
i_info->next, i_info));
}
+// This ifdef has two pieces of code which are used in module unloading.
+//
+// In the modules themselves we have a function that is registered via atexit
+// to call to copy the contents of their own gcov_info chain into the base
+// gcov_info chain. This is required because the module's memory is going
+// away as it is unloaded.
+//
+// In the base code (non-modules) we have a single implementation of the
+// code for actually doing a copy of the gcov_info chain into the base code's
+// own chain. This is kept in just the base code for space savings.
+//
+#ifdef __HOSTBOOT_MODULE
+// Forward declaration of __gcov_module_copychain for modules.
+extern "C" void __gcov_module_copychain(gcov_info* chain);
+
+/** Function called by module unloading to move the module's gcov_info
+ * instances to the global chain.
+ */
+extern "C"
+void __gcov_module_unload(void* unused)
+{
+ __gcov_module_copychain(GCOV_INFO_OBJ());
+}
+ // Register __gcov_module_unload with __cxa_atexit.
+extern void* __dso_handle;
+extern "C" int __cxa_atexit(void(*)(void*),void*,void*);
+int __unused_gcov_cxa_register =
+ __cxa_atexit(&__gcov_module_unload, NULL, __dso_handle);
+#else
+/** Function called by a module being unloaded (via __gcov_module_unload) to
+ * copy the module's gcov_info chain into the base gcov_info chain.
+ */
+extern "C"
+void __gcov_module_copychain(gcov_info* chain)
+{
+ while(chain != NULL)
+ {
+ // Copy old info.
+ gcov_info* new_info = new gcov_info;
+ memcpy(new_info, chain, sizeof(gcov_info));
+
+ // Copy old counters.
+ uint64_t* new_counters = new uint64_t[chain->n_counters];
+ memcpy(new_counters, chain->counters,
+ chain->n_counters*sizeof(uint64_t));
+ new_info->counters = new_counters;
+
+ // Atomically push new_info onto the core_gcov_info_head stack.
+ do
+ {
+ new_info->next = GCOV_INFO_OBJ();
+ } while (!__sync_bool_compare_and_swap(&GCOV_INFO_OBJ(),
+ new_info->next, new_info));
+
+ // Advance to next info in this modules chain.
+ chain = chain->next;
+ }
+}
+#endif
+
/** Unneeded function but must be defined to compile.
*
* This function appears to be typically used by libgcov.so when instrumented
OpenPOWER on IntegriCloud