Kernel build does not link in libgcc, which defines the function.

David

On Fri, Dec 21, 2012 at 8:31 AM, Teresa Johnson <tejohn...@google.com> wrote:
> On Wed, Dec 19, 2012 at 12:11 PM, Rong Xu <x...@google.com> wrote:
>> Hi,
>>
>> This patch updates the support for FDO build in linux kernel for gcc 4.7.
>> Tested with 2.6.34 kernel and google internal benchmarks.
>>
>> Thanks,
>>
>> -Rong
>>
>> 2012-12-19  Rong Xu  <x...@google.com>
>>
>>         * libgcc/libgcov.c
>>         (gcov_counter_active): v4.7 kernel fdo support.
>>         (crc32_unsigned): Include in GCOV_KERNEL build.
>>         (gcov_alloc_filename): Remove from GCOV_KERNEL build.
>>         (gcov_sort_icall_topn_counter): Ditto.
>>         (gcov_dump_module_info): Ditto.
>>         (gcov_compute_histogram): v4.7 kernel fdo support.
>>         (gcov_merge_gcda_file): Ditto.
>>         (gcov_gcda_file_size): Ditto.
>>         (gcov_write_gcda_file): Ditto.
>>         (__gcov_topn_value_profiler_body): Ditto.
>>         (gcov_set_vfile): Ditto.
>>         (gcov_kernel_dump_gcov_init): Ditto.
>>         (gcov_kernel_dump_one_gcov): Ditto.
>>         * gcc/gcov-io.c (gcov_read_string): Ditto.
>>         (static int k_popcountll): Ditto.
>>         (gcov_read_summary): Ditto.
>>         (kernel_file_fclose): Ditto.
>>         (kernel_file_ftell): Ditto.
>>         (kernel_file_fwrite): Ditto.
>>         * gcc/gcov-io.h (struct gcov_info): remove const keyword.
>>
>> Index: libgcc/libgcov.c
>> ===================================================================
>> --- libgcc/libgcov.c    (revision 194562)
>> +++ libgcc/libgcov.c    (working copy)
>> @@ -46,11 +46,11 @@ see the files COPYING3 and COPYING.RUNTIME respect
>>  #include "tsystem.h"
>>  #include "coretypes.h"
>>  #include "tm.h"
>> -#endif /* __KERNEL__ */
>>  #include "libgcc_tm.h"
>>  #include "gthr.h"
>> +#endif /* __KERNEL__ */
>>
>> -#if 1
>> +#ifndef __KERNEL__
>>  #define THREAD_PREFIX __thread
>>  #else
>>  #define THREAD_PREFIX
>> @@ -120,6 +120,7 @@ extern int gcov_dump_complete ATTRIBUTE_HIDDEN;
>>  #ifdef L_gcov
>>  #include "gcov-io.c"
>>
>> +#ifndef __GCOV_KERNEL__
>>  /* Create a strong reference to these symbols so that they are
>>     unconditionally pulled into the instrumented binary, even when
>>     the only reference is a weak reference. This is necessary because
>> @@ -134,6 +135,7 @@ extern int gcov_dump_complete ATTRIBUTE_HIDDEN;
>>     these symbols will always need to be resolved.  */
>>  void (*__gcov_dummy_ref1)() = &__gcov_reset;
>>  void (*__gcov_dummy_ref2)() = &__gcov_dump;
>> +#endif /* __GCOV_KERNEL__ */
>>
>>  /* Utility function for outputing errors.  */
>>  static int
>> @@ -151,6 +153,10 @@ gcov_error (const char *fmt, ...)
>>    return ret;
>>  }
>>
>> +/* A program checksum allows us to distinguish program data for an
>> +   object file included in multiple programs.  */
>> +static gcov_unsigned_t gcov_crc32;
>> +
>>  #ifndef __GCOV_KERNEL__
>>  /* Emitted in coverage.c.  */
>>  extern char * __gcov_pmu_profile_filename;
>> @@ -183,10 +189,6 @@ THREAD_PREFIX gcov_unsigned_t __gcov_sample_counte
>>  /* Chain of per-object gcov structures.  */
>>  extern struct gcov_info *__gcov_list;
>>
>> -/* A program checksum allows us to distinguish program data for an
>> -   object file included in multiple programs.  */
>> -static gcov_unsigned_t gcov_crc32;
>> -
>>  /* Size of the longest file name. */
>>  static size_t gcov_max_filename = 0;
>>
>> @@ -323,8 +325,6 @@ gcov_counter_active (const struct gcov_info *info,
>>    return (info->merge[type] != 0);
>>  }
>>
>> -#ifndef __GCOV_KERNEL__
>> -
>>  /* Add an unsigned value to the current crc */
>>
>>  static gcov_unsigned_t
>> @@ -344,6 +344,8 @@ crc32_unsigned (gcov_unsigned_t crc32, gcov_unsign
>>    return crc32;
>>  }
>>
>> +#ifndef __GCOV_KERNEL__
>> +
>>  /* Check if VERSION of the info block PTR matches libgcov one.
>>     Return 1 on success, or zero in case of versions mismatch.
>>     If FILENAME is not NULL, its value used for reporting purposes
>> @@ -464,6 +466,8 @@ gcov_alloc_filename (void)
>>    gi_filename_up = gi_filename + prefix_length;
>>  }
>>
>> +#endif /* __GCOV_KERNEL__ */
>> +
>>  /* Sort N entries in VALUE_ARRAY in descending order.
>>     Each entry in VALUE_ARRAY has two values. The sorting
>>     is based on the second value.  */
>> @@ -509,6 +513,8 @@ gcov_sort_icall_topn_counter (const struct gcov_ct
>>      }
>>  }
>>
>> +#ifndef __GCOV_KERNEL__
>> +
>>  /* Write imported files (auxiliary modules) for primary module GI_PTR
>>     into file GI_FILENAME.  */
>>
>> @@ -586,6 +592,8 @@ gcov_dump_module_info (void)
>>    __gcov_finalize_dyn_callgraph ();
>>  }
>>
>> +#endif /* __GCOV_KERNEL__ */
>> +
>>  /* Insert counter VALUE into HISTOGRAM.  */
>>
>>  static void
>> @@ -656,6 +664,8 @@ gcov_compute_histogram (struct gcov_summary *sum)
>>      }
>>  }
>>
>> +#ifndef __GCOV_KERNEL__
>> +
>>  /* Dump the coverage counts. We merge with existing counts when
>>     possible, to avoid growing the .da files ad infinitum. We use this
>>     program's checksum to make sure we only accumulate whole program
>> @@ -1013,12 +1023,7 @@ gcov_merge_gcda_file (struct gcov_info *gi_ptr)
>>               goto read_error;
>>         }
>>       if (tag && tag != GCOV_TAG_MODULE_INFO)
>> -       {
>> -         read_mismatch:;
>> -        fprintf (stderr, "profiling:%s:Merge mismatch for %s\n",
>> -                 gi_filename, f_ix + 1 ? "function" : "summaries");
>> -         goto read_fatal;
>> -       }
>> +       goto read_mismatch;
>>      }
>>    goto rewrite;
>>
>> @@ -1031,6 +1036,11 @@ read_error:;
>>
>>      goto rewrite;
>>
>> +read_mismatch:;
>> +    gcov_error ("profiling:%s:Merge mismatch for %s\n",
>> +            gi_filename, f_ix + 1 ? "function" : "summaries");
>> +    goto read_fatal;
>> +
>>  read_fatal:;
>>      gcov_close ();
>>      return 1;
>> @@ -1076,7 +1086,7 @@ rewrite:;
>>                                sizeof (*cs_all) - (sizeof (gcov_bucket_type)
>>                                                    * GCOV_HISTOGRAM_SIZE)))
>>            {
>> -            fprintf (stderr, "profiling:%s:Invocation mismatch - "
>> +            gcov_error ("profiling:%s:Invocation mismatch - "
>>                  "some data files may have been removed%s\n",
>>              gi_filename, GCOV_LOCKED
>>              ? "" : " or concurrent update without locking support");
>> @@ -1093,14 +1103,14 @@ rewrite:;
>>     the size is in units of gcov_type.  */
>>
>>  GCOV_LINKAGE unsigned
>> -gcov_gcda_file_size (struct gcov_info *gi_ptr,
>> -                     struct gcov_summary *sum)
>> +gcov_gcda_file_size (struct gcov_info *gi_ptr)
>>  {
>>    unsigned size;
>>    const struct gcov_fn_info *fi_ptr;
>>    unsigned f_ix, t_ix, h_ix, h_cnt = 0;
>>    unsigned n_counts;
>>    const struct gcov_ctr_info *ci_ptr;
>> +  struct gcov_summary *sum = &this_program;
>>    const struct gcov_ctr_summary *csum;
>>
>>    /* GCOV_DATA_MAGIC, GCOV_VERSION and time_stamp.  */
>> @@ -1181,13 +1191,14 @@ gcov_write_gcda_file (struct gcov_info *gi_ptr)
>>        ci_ptr = gfi_ptr->ctrs;
>>        for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
>>          {
>> +          gcov_type *c_ptr;
>>            if (!gi_ptr->merge[t_ix])
>>              continue;
>>
>>            n_counts = ci_ptr->num;
>>            gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
>>                                   GCOV_TAG_COUNTER_LENGTH (n_counts));
>> -          gcov_type *c_ptr = ci_ptr->values;
>> +          c_ptr = ci_ptr->values;
>>            while (n_counts--)
>>              gcov_write_counter (*c_ptr++);
>>            ci_ptr++;
>> @@ -1692,7 +1703,7 @@ __gcov_topn_value_profiler_body (gcov_type *counte
>>       {
>>         unsigned i, j;
>>         gcov_type *p, minv;
>> -       gcov_type* tmp_cnts
>> +       gcov_type* tmp_cnts
>>             = (gcov_type *)alloca (topn_val * sizeof(gcov_type));
>>
>>         *num_eviction = 0;
>> @@ -2050,15 +2061,20 @@ gcov_set_vfile (gcov_kernel_vfile *file)
>>    gcov_current_file = file;
>>  }
>>
>> +/* Init function before dumping the gcda file in kernel.  */
>> +
>> +void
>> +gcov_kernel_dump_gcov_init (void)
>> +{
>> +  gcov_exit_init ();
>> +}
>> +
>>  /* Dump one entry in the gcov_info list (for one object) in kernel.  */
>>
>>  void
>>  gcov_kernel_dump_one_gcov (struct gcov_info *info)
>>  {
>>    gcc_assert (gcov_current_file);
>> -
>> -  gcov_exit_init ();
>> -
>>    gcov_dump_one_gcov (info);
>>  }
>>
>> Index: gcc/gcov-io.c
>> ===================================================================
>> --- gcc/gcov-io.c       (revision 194562)
>> +++ gcc/gcov-io.c       (working copy)
>> @@ -662,6 +662,30 @@ gcov_read_string (void)
>>    return (const char *) gcov_read_words (length);
>>  }
>>
>> +#ifdef __GCOV_KERNEL__
>> +static const unsigned char __popcount_tab[256] =
>> +{
>> +    0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
>> +    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
>> +    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
>> +    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
>> +    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
>> +    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
>> +    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
>> +    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
>> +};
>> +
>> +static int k_popcountll (long long x)
>> +{
>> +  int i, ret = 0;
>> +
>> +  for (i = 0; i < 8*sizeof(long long) ; i += 8)
>> +    ret += __popcount_tab[(x >> i) & 0xff];
>> +
>> +  return ret;
>> +}
>> +#endif
>> +
>>  GCOV_LINKAGE void
>>  gcov_read_summary (struct gcov_summary *summary)
>>  {
>> @@ -683,7 +707,11 @@ gcov_read_summary (struct gcov_summary *summary)
>>        for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
>>          {
>>            histo_bitvector[bv_ix] = gcov_read_unsigned ();
>> +#ifndef __GCOV_KERNEL__
>>            h_cnt += __builtin_popcountll (histo_bitvector[bv_ix]);
>> +#else
>> +          h_cnt += k_popcountll (histo_bitvector[bv_ix]);
>> +#endif
>
> Is the issue here that __builtin_popcountll is not available? I just
> committed a fix to trunk to deal with a similar issue, can you see if
> this would address the problem here too?
>
> http://gcc.gnu.org/ml/gcc-bugs/2012-12/msg01976.html
>
> Thanks,
> Teresa
>
>>          }
>>        bv_ix = 0;
>>        h_ix = 0;
>> @@ -1137,7 +1165,6 @@ kernel_file_fclose (gcov_kernel_vfile *fp)
>>  long
>>  kernel_file_ftell (gcov_kernel_vfile *fp)
>>  {
>> -  gcc_assert (0);  /* should not reach here */
>>    return 0;
>>  }
>>
>> @@ -1192,8 +1219,9 @@ kernel_file_fwrite (const void *ptr, size_t size,
>>    if (vsize <= vpos)
>>      {
>>        printk (KERN_ERR
>> -         "GCOV_KERNEL: something wrong: vbuf=%p vsize=%u vpos=%u\n",
>> -          vbuf, vsize, vpos);
>> +         "GCOV_KERNEL: something wrong in file %s: vbuf=%p vsize=%u"
>> +         " vpos=%u\n",
>> +          fp->info->filename, vbuf, vsize, vpos);
>>        return 0;
>>      }
>>    len = vsize - vpos;
>> @@ -1207,8 +1235,9 @@ kernel_file_fwrite (const void *ptr, size_t size,
>>
>>    if (len != nitems)
>>      printk (KERN_ERR
>> -        "GCOV_KERNEL: something wrong: size=%lu nitems=%lu ret=%d\n",
>> -        size, nitems, len);
>> +        "GCOV_KERNEL: something wrong in file %s: size=%lu nitems=%lu"
>> +        " ret=%d, vsize=%u vpos=%u \n",
>> +        fp->info->filename, size, nitems, len, vsize, vpos);
>>    return len;
>>  }
>>
>> Index: gcc/gcov-io.h
>> ===================================================================
>> --- gcc/gcov-io.h       (revision 194562)
>> +++ gcc/gcov-io.h       (working copy)
>> @@ -300,6 +300,14 @@ typedef unsigned gcov_type_unsigned __attribute__
>>
>>  #endif  /* BITS_PER_UNIT == 8  */
>>
>> +#if LONG_LONG_TYPE_SIZE > 32
>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD_FN __sync_fetch_and_add_8
>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD BUILT_IN_SYNC_FETCH_AND_ADD_8
>> +#else
>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD_FN __sync_fetch_and_add_4
>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD BUILT_IN_SYNC_FETCH_AND_ADD_4
>> +#endif
>> +
>>  #undef EXTRACT_MODULE_ID_FROM_GLOBAL_ID
>>  #undef EXTRACT_FUNC_ID_FROM_GLOBAL_ID
>>  #undef GEN_FUNC_GLOBAL_ID
>> @@ -322,6 +330,18 @@ typedef unsigned gcov_type_unsigned __attribute__
>>  typedef unsigned gcov_unsigned_t;
>>  typedef unsigned gcov_position_t;
>>
>> +#if LONG_LONG_TYPE_SIZE > 32
>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD_FN __sync_fetch_and_add_8
>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD BUILT_IN_SYNC_FETCH_AND_ADD_8
>> +#else
>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD_FN __sync_fetch_and_add_4
>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD BUILT_IN_SYNC_FETCH_AND_ADD_4
>> +#endif
>> +#define PROFILE_GEN_EDGE_ATOMIC (flag_profile_gen_atomic == 1 || \
>> +                                 flag_profile_gen_atomic == 3)
>> +#define PROFILE_GEN_VALUE_ATOMIC (flag_profile_gen_atomic == 2 || \
>> +                                  flag_profile_gen_atomic == 3)
>> +
>>  /* gcov_type is typedef'd elsewhere for the compiler */
>>  #if IN_GCOV
>>  #define GCOV_LINKAGE static
>> @@ -781,8 +801,8 @@ struct gcov_info
>>                                           unused) */
>>
>>    unsigned n_functions;                /* number of functions */
>> -  const struct gcov_fn_info *const *functions; /* pointer to pointers
>> -                                                 to function information  */
>> +  const struct gcov_fn_info **functions; /* pointer to pointers
>> +                                           to function information  */
>>  };
>>
>>  /* Information about a single imported module.  */
>> @@ -988,8 +1008,7 @@ static void gcov_rewrite (void);
>>  GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
>>  GCOV_LINKAGE void gcov_truncate (void) ATTRIBUTE_HIDDEN;
>>  GCOV_LINKAGE gcov_unsigned_t gcov_string_length (const char *) 
>> ATTRIBUTE_HIDDEN;
>> -GCOV_LINKAGE unsigned gcov_gcda_file_size (struct gcov_info *,
>> -                                           struct gcov_summary *);
>> +GCOV_LINKAGE unsigned gcov_gcda_file_size (struct gcov_info *);
>>  #else
>>  /* Available outside libgcov */
>>  GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/,
>>
>> --
>> This patch is available for review at http://codereview.appspot.com/6968046
>
>
>
> --
> Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413

Reply via email to