diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2012-09-19 14:23:54 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-10-09 17:06:49 -0500 |
commit | fb1836fd7b1b8839815595db08ae740ec7b86347 (patch) | |
tree | 54ff93536489c27b80af1f503520bd9894cdcfd3 /src/include/usr/gcov.h | |
parent | 84e4274fe412a577f67805cc701f4fb66a3feb2f (diff) | |
download | talos-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.h | 141 |
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 |