Mercurial > hg > CbC > CbC_gcc
diff gcc/libgcov.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | 77e2b8dfacca |
children |
line wrap: on
line diff
--- a/gcc/libgcov.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/libgcov.c Tue Mar 22 17:18:12 2011 +0900 @@ -1,7 +1,7 @@ /* Routines required for instrumenting a program. */ /* Compile this one with gcc. */ /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 + 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -87,7 +87,6 @@ /* Size of the longest file name. */ static size_t gcov_max_filename = 0; -#ifdef TARGET_POSIX_IO /* Make sure path component of the given FILENAME exists, create missing directories. FILENAME must be writable. Returns zero on success, or -1 if an error occurred. */ @@ -95,9 +94,19 @@ static int create_file_directory (char *filename) { +#if !defined(TARGET_POSIX_IO) && !defined(_WIN32) + (void) filename; + return -1; +#else char *s; - for (s = filename + 1; *s != '\0'; s++) + s = filename; + + if (HAS_DRIVE_SPEC(s)) + s += 2; + if (IS_DIR_SEPARATOR(*s)) + ++s; + for (; *s != '\0'; s++) if (IS_DIR_SEPARATOR(*s)) { char sep = *s; @@ -105,7 +114,11 @@ /* Try to make directory if it doesn't already exist. */ if (access (filename, F_OK) == -1 +#ifdef TARGET_POSIX_IO && mkdir (filename, 0755) == -1 +#else + && mkdir (filename) == -1 +#endif /* The directory might have been made by another process. */ && errno != EEXIST) { @@ -118,8 +131,8 @@ *s = sep; }; return 0; +#endif } -#endif /* Check if VERSION of the info block PTR matches libgcov one. Return 1 on success, or zero in case of versions mismatch. @@ -190,20 +203,21 @@ } } + { + /* Check if the level of dirs to strip off specified. */ + char *tmp = getenv("GCOV_PREFIX_STRIP"); + if (tmp) + { + gcov_prefix_strip = atoi (tmp); + /* Do not consider negative values. */ + if (gcov_prefix_strip < 0) + gcov_prefix_strip = 0; + } + } /* Get file name relocation prefix. Non-absolute values are ignored. */ gcov_prefix = getenv("GCOV_PREFIX"); - if (gcov_prefix && IS_ABSOLUTE_PATH (gcov_prefix)) + if (gcov_prefix) { - /* Check if the level of dirs to strip off specified. */ - char *tmp = getenv("GCOV_PREFIX_STRIP"); - if (tmp) - { - gcov_prefix_strip = atoi (tmp); - /* Do not consider negative values. */ - if (gcov_prefix_strip < 0) - gcov_prefix_strip = 0; - } - prefix_length = strlen(gcov_prefix); /* Remove an unnecessary trailing '/' */ @@ -213,8 +227,15 @@ else prefix_length = 0; - /* Allocate and initialize the filename scratch space. */ - gi_filename = (char *) alloca (prefix_length + gcov_max_filename + 1); + /* If no prefix was specified and a prefix stip, then we assume + relative. */ + if (gcov_prefix_strip != 0 && prefix_length == 0) + { + gcov_prefix = "."; + prefix_length = 1; + } + /* Allocate and initialize the filename scratch space plus one. */ + gi_filename = (char *) alloca (prefix_length + gcov_max_filename + 2); if (prefix_length) memcpy (gi_filename, gcov_prefix, prefix_length); gi_filename_up = gi_filename + prefix_length; @@ -233,31 +254,42 @@ gcov_unsigned_t tag, length; gcov_position_t summary_pos = 0; gcov_position_t eof_pos = 0; + const char *fname, *s; + + fname = gi_ptr->filename; memset (&this_object, 0, sizeof (this_object)); memset (&object, 0, sizeof (object)); + /* Avoid to add multiple drive letters into combined path. */ + if (prefix_length != 0 && HAS_DRIVE_SPEC(fname)) + fname += 2; + /* Build relocated filename, stripping off leading directories from the initial filename if requested. */ if (gcov_prefix_strip > 0) { int level = 0; - const char *fname = gi_ptr->filename; - const char *s; + s = fname; + if (IS_DIR_SEPARATOR(*s)) + ++s; /* Skip selected directory levels. */ - for (s = fname + 1; (*s != '\0') && (level < gcov_prefix_strip); s++) + for (; (*s != '\0') && (level < gcov_prefix_strip); s++) if (IS_DIR_SEPARATOR(*s)) { fname = s; level++; - }; - - /* Update complete filename with stripped original. */ - strcpy (gi_filename_up, fname); + } } + /* Update complete filename with stripped original. */ + if (!IS_DIR_SEPARATOR (*fname) && !HAS_DRIVE_SPEC(fname)) + { + strcpy (gi_filename_up, "/"); + strcpy (gi_filename_up + 1, fname); + } else - strcpy (gi_filename_up, gi_ptr->filename); + strcpy (gi_filename_up, fname); /* Totals for this object file. */ ci_ptr = gi_ptr->counts; @@ -297,7 +329,6 @@ if (!gcov_open (gi_filename)) { -#ifdef TARGET_POSIX_IO /* Open failed likely due to missed directory. Create directory and retry to open file. */ if (create_file_directory (gi_filename)) @@ -305,7 +336,6 @@ fprintf (stderr, "profiling:%s:Skip\n", gi_filename); continue; } -#endif if (!gcov_open (gi_filename)) { fprintf (stderr, "profiling:%s:Cannot open\n", gi_filename); @@ -768,6 +798,24 @@ #endif #ifdef L_gcov_indirect_call_profiler + +/* By default, the C++ compiler will use function addresses in the + vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero + tells the compiler to use function descriptors instead. The value + of this macro says how many words wide the descriptor is (normally 2), + but it may be dependent on target flags. Since we do not have access + to the target flags here we just check to see if it is set and use + that to set VTABLE_USES_DESCRIPTORS to 0 or 1. + + It is assumed that the address of a function descriptor may be treated + as a pointer to a function. */ + +#ifdef TARGET_VTABLE_USES_DESCRIPTORS +#define VTABLE_USES_DESCRIPTORS 1 +#else +#define VTABLE_USES_DESCRIPTORS 0 +#endif + /* Tries to determine the most common value among its inputs. */ void __gcov_indirect_call_profiler (gcov_type* counter, gcov_type value, @@ -777,7 +825,7 @@ function may have multiple descriptors and we need to dereference the descriptors to see if they point to the same function. */ if (cur_func == callee_func - || (TARGET_VTABLE_USES_DESCRIPTORS && callee_func + || (VTABLE_USES_DESCRIPTORS && callee_func && *(void **) cur_func == *(void **) callee_func)) __gcov_one_value_profiler_body (counter, value); }