Remove use of alloca.
[deliverable/binutils-gdb.git] / gprof / corefile.c
index 5c6fe6b51def1e89af5c412f717ba4d51ca3cf75..37942b564addb3bf91829ff81e83a851a9f9992c 100644 (file)
@@ -1,7 +1,6 @@
 /* corefile.c
 
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 1999-2016 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
@@ -22,6 +21,7 @@
 \f
 #include "gprof.h"
 #include "libiberty.h"
+#include "filenames.h"
 #include "search_list.h"
 #include "source.h"
 #include "symtab.h"
@@ -53,6 +53,7 @@ extern void vax_find_call   (Sym *, bfd_vma, bfd_vma);
 extern void tahoe_find_call (Sym *, bfd_vma, bfd_vma);
 extern void sparc_find_call (Sym *, bfd_vma, bfd_vma);
 extern void mips_find_call  (Sym *, bfd_vma, bfd_vma);
+extern void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
 
 static void
 parse_error (const char *filename)
@@ -67,7 +68,7 @@ parse_error (const char *filename)
 static int
 cmp_symbol_map (const void * l, const void * r)
 {
-  return strcmp (((struct function_map *) l)->function_name, 
+  return strcmp (((struct function_map *) l)->function_name,
                 ((struct function_map *) r)->function_name);
 }
 
@@ -140,7 +141,7 @@ read_function_mappings (const char *filename)
        }
 
       /* dummy has the filename, go ahead and copy it.  */
-      symbol_map[count].file_name = xmalloc (strlen (dummy) + 1);
+      symbol_map[count].file_name = (char *) xmalloc (strlen (dummy) + 1);
       strcpy (symbol_map[count].file_name, dummy);
 
       /* Now we need the function name.  */
@@ -148,7 +149,7 @@ read_function_mappings (const char *filename)
       if (!matches)
        parse_error (filename);
       tmp = strrchr (dummy, ' ') + 1;
-      symbol_map[count].function_name = xmalloc (strlen (tmp) + 1);
+      symbol_map[count].function_name = (char *) xmalloc (strlen (tmp) + 1);
       strcpy (symbol_map[count].function_name, tmp);
       count++;
     }
@@ -157,10 +158,13 @@ read_function_mappings (const char *filename)
   symbol_map_count = count;
 
   for (i = 0; i < symbol_map_count; ++i)
-    if (i == 0 || strcmp (symbol_map[i].file_name, symbol_map[i - 1].file_name))
+    if (i == 0
+        || filename_cmp (symbol_map[i].file_name, symbol_map[i - 1].file_name))
       symbol_map[i].is_first = 1;
 
   qsort (symbol_map, symbol_map_count, sizeof (struct function_map), cmp_symbol_map);
+
+  fclose (file);
 }
 
 void
@@ -227,7 +231,7 @@ core_init (const char * aout_name)
       long i;
 
       new_size = (core_num_syms + synth_count + 1) * sizeof (*core_syms);
-      core_syms = xrealloc (core_syms, new_size);
+      core_syms = (asymbol **) xrealloc (core_syms, new_size);
       symp = core_syms + core_num_syms;
       core_num_syms += synth_count;
       for (i = 0; i < synth_count; i++)
@@ -318,6 +322,10 @@ find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
       mips_find_call (parent, p_lowpc, p_highpc);
       break;
 
+    case bfd_arch_aarch64:
+      aarch64_find_call (parent, p_lowpc, p_highpc);
+      break;
+
     default:
       fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
               whoami, bfd_printable_name(core_bfd));
@@ -385,12 +393,34 @@ core_sym_class (asymbol *sym)
       if (*name == '$')
         return 0;
 
-      /* Do not discard nested subprograms (those
-        which end with .NNN, where N are digits).  */
-      if (*name == '.')
-       for (name++; *name; name++)
-         if (! ISDIGIT (*name))
-           return 0;
+      while (*name == '.')
+       {
+         /* Allow both nested subprograms (which end with ".NNN", where N is
+            a digit) and GCC cloned functions (which contain ".clone").
+            Allow for multiple iterations of both - apparently GCC can clone
+            clones and subprograms.  */
+         int digit_seen = 0;
+#define CLONE_NAME         ".clone."
+#define CLONE_NAME_LEN     strlen (CLONE_NAME)
+#define CONSTPROP_NAME     ".constprop."
+#define CONSTPROP_NAME_LEN  strlen (CONSTPROP_NAME)
+
+         if (strlen (name) > CLONE_NAME_LEN
+             && strncmp (name, CLONE_NAME, CLONE_NAME_LEN) == 0)
+           name += CLONE_NAME_LEN - 1;
+
+         else if (strlen (name) > CONSTPROP_NAME_LEN
+             && strncmp (name, CONSTPROP_NAME, CONSTPROP_NAME_LEN) == 0)
+           name += CONSTPROP_NAME_LEN - 1;
+
+         for (name++; *name; name++)
+           if (digit_seen && *name == '.')
+             break;
+           else if (ISDIGIT (*name))
+             digit_seen = 1;
+           else
+             return 0;
+       }
     }
 
   /* On systems where the C compiler adds an underscore to all
@@ -452,7 +482,7 @@ get_src_info (bfd_vma addr, const char **filename, const char **name, int *line_
 
 /* Return number of symbols in a symbol-table file.  */
 
-static int 
+static int
 num_of_syms_in (FILE * f)
 {
   const int BUFSIZE = 1024;
@@ -461,7 +491,7 @@ num_of_syms_in (FILE * f)
   char   type;
   char * name = (char *) xmalloc (BUFSIZE);
   int num = 0;
-  
+
   while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
     {
       if (sscanf (buf, "%s %c %s", address, &type, name) == 3)
@@ -517,7 +547,7 @@ core_create_syms_from (const char * sym_table_file)
       done (1);
     }
 
-  while (!feof (f) && fgets (buf, sizeof (buf), f))
+  while (!feof (f) && fgets (buf, BUFSIZE - 1, f))
     {
       if (sscanf (buf, "%s %c %s", address, &type, name) == 3)
         if (type != 't' && type != 'T')
@@ -564,7 +594,21 @@ core_create_function_syms (void)
   bfd_vma max_vma = 0;
   int cxxclass;
   long i;
-  struct function_map * found;
+  struct function_map * found = NULL;
+  int core_has_func_syms = 0;
+
+  switch (core_bfd->xvec->flavour)
+    {
+    default:
+      break;
+    case bfd_target_coff_flavour:
+    case bfd_target_ecoff_flavour:
+    case bfd_target_xcoff_flavour:
+    case bfd_target_elf_flavour:
+    case bfd_target_nlm_flavour:
+    case bfd_target_som_flavour:
+      core_has_func_syms = 1;
+    }
 
   /* Pass 1 - determine upper bound on number of function names.  */
   symtab.len = 0;
@@ -577,8 +621,14 @@ core_create_function_syms (void)
       /* Don't create a symtab entry for a function that has
         a mapping to a file, unless it's the first function
         in the file.  */
-      found = bsearch (core_syms[i]->name, symbol_map, symbol_map_count,
-                      sizeof (struct function_map), search_mapped_symbol);
+      if (symbol_map_count != 0)
+       {
+         /* Note: some systems (SunOS 5.8) crash if bsearch base argument
+            is NULL.  */
+         found = (struct function_map *) bsearch
+           (core_syms[i]->name, symbol_map, symbol_map_count,
+            sizeof (struct function_map), search_mapped_symbol);
+       }
       if (found == NULL || found->is_first)
        ++symtab.len;
     }
@@ -609,8 +659,14 @@ core_create_function_syms (void)
          continue;
        }
 
-      found = bsearch (core_syms[i]->name, symbol_map, symbol_map_count,
-                      sizeof (struct function_map), search_mapped_symbol);
+      if (symbol_map_count != 0)
+       {
+         /* Note: some systems (SunOS 5.8) crash if bsearch base argument
+            is NULL.  */
+         found = (struct function_map *) bsearch
+           (core_syms[i]->name, symbol_map, symbol_map_count,
+            sizeof (struct function_map), search_mapped_symbol);
+       }
       if (found && ! found->is_first)
        continue;
 
@@ -667,7 +723,8 @@ core_create_function_syms (void)
          }
       }
 
-      symtab.limit->is_func = (core_syms[i]->flags & BSF_FUNCTION) != 0; 
+      symtab.limit->is_func = (!core_has_func_syms
+                              || (core_syms[i]->flags & BSF_FUNCTION) != 0);
       symtab.limit->is_bb_head = TRUE;
 
       if (cxxclass == 't')
@@ -726,8 +783,8 @@ core_create_line_syms (void)
      BFD would provide an iterator for enumerating all line infos.  */
   prev_name_len = PATH_MAX;
   prev_filename_len = PATH_MAX;
-  prev_name = xmalloc (prev_name_len);
-  prev_filename = xmalloc (prev_filename_len);
+  prev_name = (char *) xmalloc (prev_name_len);
+  prev_filename = (char *) xmalloc (prev_filename_len);
   ltab.len = 0;
   prev_line_num = 0;
 
@@ -740,7 +797,7 @@ core_create_line_syms (void)
          || (prev_line_num == dummy.line_num
              && prev_name != NULL
              && strcmp (prev_name, dummy.name) == 0
-             && strcmp (prev_filename, filename) == 0))
+             && filename_cmp (prev_filename, filename) == 0))
        continue;
 
       ++ltab.len;
@@ -751,7 +808,7 @@ core_create_line_syms (void)
        {
          prev_name_len = len + 1024;
          free (prev_name);
-         prev_name = xmalloc (prev_name_len);
+         prev_name = (char *) xmalloc (prev_name_len);
        }
 
       strcpy (prev_name, dummy.name);
@@ -761,7 +818,7 @@ core_create_line_syms (void)
        {
          prev_filename_len = len + 1024;
          free (prev_filename);
-         prev_filename = xmalloc (prev_filename_len);
+         prev_filename = (char *) xmalloc (prev_filename_len);
        }
 
       strcpy (prev_filename, filename);
@@ -805,7 +862,7 @@ core_create_line_syms (void)
       if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
          || (prev && prev->line_num == ltab.limit->line_num
              && strcmp (prev->name, ltab.limit->name) == 0
-             && strcmp (prev->file->name, filename) == 0))
+             && filename_cmp (prev->file->name, filename) == 0))
        continue;
 
       /* Make name pointer a malloc'ed string.  */
This page took 0.028596 seconds and 4 git commands to generate.