(root)/
binutils-2.41/
gprof/
aarch64.c
       1  /* Gprof -c option support for AArch64.
       2     Copyright 2013 Linaro Ltd.
       3  
       4     Based upon gprof/i386.c.
       5  
       6     Copyright (c) 1983, 1993, 2001
       7     The Regents of the University of California.  All rights reserved.
       8  
       9     Redistribution and use in source and binary forms, with or without
      10     modification, are permitted provided that the following conditions
      11     are met:
      12  
      13     1.  Redistributions of source code must retain the above copyright
      14         notice, this list of conditions and the following disclaimer.
      15     2.  Redistributions in binary form must reproduce the above copyright
      16         notice, this list of conditions and the following disclaimer in the
      17         documentation and/or other materials provided with the distribution.
      18     3.  Neither the name of the University nor the names of its contributors
      19         may be used to endorse or promote products derived from this software
      20         without specific prior written permission.
      21  
      22     THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      23     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      24     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      25     ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      26     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      27     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      28     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      29     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      30     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      31     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      32     SUCH DAMAGE.  */
      33  
      34  #include "gprof.h"
      35  #include "search_list.h"
      36  #include "source.h"
      37  #include "symtab.h"
      38  #include "cg_arcs.h"
      39  #include "corefile.h"
      40  #include "hist.h"
      41  
      42  #define BRANCH_MASK    0x7c000000
      43  #define BRANCH_PATTERN 0x14000000
      44  
      45  void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
      46  
      47  void
      48  aarch64_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
      49  {
      50    bfd_vma pc, dest_pc, offset;
      51    unsigned int insn;
      52    Sym *child;
      53  
      54    DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
      55  			  parent->name, (unsigned long) p_lowpc,
      56  			  (unsigned long) p_highpc));
      57  
      58    for (pc = p_lowpc; pc < p_highpc; pc += 4)
      59      {
      60  
      61        insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space
      62  				    + pc - core_text_sect->vma));
      63  
      64        if ((insn & BRANCH_MASK) == BRANCH_PATTERN)
      65  	{
      66  	  DBG (CALLDEBUG,
      67  	       printf ("[find_call] 0x%lx: bl", (unsigned long) pc));
      68  
      69  	  /* Regular pc relative addressing check that this is the
      70  	     address of a function.  */
      71  	  offset = ((((bfd_vma) insn & 0x3ffffff) ^ 0x2000000) - 0x2000000) << 2;
      72  
      73  	  dest_pc = pc + offset;
      74  
      75  	  if (hist_check_address (dest_pc))
      76  	    {
      77  	      child = sym_lookup (&symtab, dest_pc);
      78  
      79  	      if (child)
      80  		{
      81  		  DBG (CALLDEBUG,
      82  		       printf ("\tdest_pc=0x%lx, (name=%s, addr=0x%lx)\n",
      83  			       (unsigned long) dest_pc, child->name,
      84  			       (unsigned long) child->addr));
      85  
      86  		  if (child->addr == dest_pc)
      87  		    {
      88  		      /* a hit.  */
      89  		      arc_add (parent, child, (unsigned long) 0);
      90  		      continue;
      91  		    }
      92  		}
      93  	    }
      94  
      95  	  /* Something funny going on.  */
      96  	  DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
      97  	}
      98      }
      99  }