[AArch64] gprof support for AArch64

Message ID CAJK_mQ0v_KJme4JqoQh34y=L7+G-Vq3xkX+R2GGSnYMU8KrKCw@mail.gmail.com
State New
Headers show

Commit Message

Venkataramanan Kumar May 21, 2013, 2:22 p.m.
Hi Maintainers,

The attached patch adds gprof support for aarch64.

ChangeLog

2013-05-21  Venkataramanan Kumar  <Venkataramanan.kumar@linaro.org>

        * aarch64.c: New file.
        * corefile.c(find_call): Call aarch64_find_call for bfd_arch_aarch64.
        * Makefile.am (sources): Add aarch64.c.
        * Makefile.in: Regenerate.

is ok for trunk?

regards,
Venkat.

Comments

Alan Modra May 21, 2013, 11:54 p.m. | #1
OK, except

On Tue, May 21, 2013 at 07:52:58PM +0530, Venkataramanan Kumar wrote:
> +      if (((insn & 0xfc000000) == BRANCHANDLINK)
> +	  ||((insn & 0xfc000000) == BRANCH))

Remove excess parentheses, add space after ||.

> +	{
> +	  DBG (CALLDEBUG,
> +	       printf ("[find_call] 0x%lx: bl", (unsigned long) pc));
> +
> +	  /* Regular pc relative addressing check that this is the
> +	      address of a function.  */
> +	  offset = ((insn & 0x3ffffff) << 2)  & ((1U << 28) - 1);

No need to mask with "& ((1U << 28) - 1)".
Venkataramanan Kumar May 22, 2013, 8:01 a.m. | #2
Hi Alan,

I have incorporated your comments.

I do'nt have write access, so will wait for someone  to commit on my behalf.

regards,
Venkat.

On 22 May 2013 05:24, Alan Modra <> wrote:
> OK, except
>
> On Tue, May 21, 2013 at 07:52:58PM +0530, Venkataramanan Kumar wrote:
>> +      if (((insn & 0xfc000000) == BRANCHANDLINK)
>> +       ||((insn & 0xfc000000) == BRANCH))
>
> Remove excess parentheses, add space after ||.
>
>> +     {
>> +       DBG (CALLDEBUG,
>> +            printf ("[find_call] 0x%lx: bl", (unsigned long) pc));
>> +
>> +       /* Regular pc relative addressing check that this is the
>> +           address of a function.  */
>> +       offset = ((insn & 0x3ffffff) << 2)  & ((1U << 28) - 1);
>
> No need to mask with "& ((1U << 28) - 1)".
>
> --
> Alan Modra
> Australia Development Lab, IBM
Marcus Shawcroft May 22, 2013, 8:26 a.m. | #3
On 21/05/13 15:22, Venkataramanan Kumar wrote:
> +/* Opcode of the "bl" and "b" instructions.  */
> +#define BRANCHANDLINK (0x94000000)
> +#define BRANCH        (0x14000000)
> +
> +void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
> +
> +void
> +aarch64_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
> +{
> +  bfd_vma pc, dest_pc, offset;
> +  unsigned int insn;
> +  Sym *child;
> +
> +  DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
> +			  parent->name, (unsigned long) p_lowpc,
> +			  (unsigned long) p_highpc));
> +
> +  for (pc = p_lowpc; pc < p_highpc; pc += 4)
> +    {
> +
> +      insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space
> +				    + pc - core_text_sect->vma));
> +
> +      if (((insn & 0xfc000000) == BRANCHANDLINK)
> +	  ||((insn & 0xfc000000) == BRANCH))
> +	{

The encoding for the branch instruction is:

31 30 29 28 27 26 25 .. 0
  L  0  0  1  0  1 imm26

.. where L is the link flag that distinguishes between BRANCH and 
BRANCHANDLINK, therefore the above can be written as:

#define BRANCH_MASK    0x7c000000
#define BRANCH_PATTERN 0x14000000

(insn & BRANCH_MASK) == BRANCH_PATTERN

/Marcus

Patch hide | download patch | download mbox

diff -urN src/gprof/aarch64.c src-patch/gprof/aarch64.c
--- src/gprof/aarch64.c	1970-01-01 05:30:00.000000000 +0530
+++ src-patch/gprof/aarch64.c	2013-05-21 17:09:20.559403142 +0530
@@ -0,0 +1,102 @@ 
+/* Gprof -c option support for AArch64.
+   Copyright 2013 Linaro Ltd.
+
+   Based upon gprof/i386.c.
+
+   Copyright (c) 1983, 1993, 2001
+   The Regents of the University of California.  All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   1.  Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+   2.  Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+   3.  Neither the name of the University nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+   SUCH DAMAGE.  */
+
+#include "gprof.h"
+#include "search_list.h"
+#include "source.h"
+#include "symtab.h"
+#include "cg_arcs.h"
+#include "corefile.h"
+#include "hist.h"
+
+/* Opcode of the "bl" and "b" instructions.  */
+#define BRANCHANDLINK (0x94000000)
+#define BRANCH        (0x14000000)
+
+void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
+
+void
+aarch64_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
+{
+  bfd_vma pc, dest_pc, offset;
+  unsigned int insn;
+  Sym *child;
+
+  DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
+			  parent->name, (unsigned long) p_lowpc,
+			  (unsigned long) p_highpc));
+
+  for (pc = p_lowpc; pc < p_highpc; pc += 4)
+    {
+
+      insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space
+				    + pc - core_text_sect->vma));
+
+      if (((insn & 0xfc000000) == BRANCHANDLINK)
+	  ||((insn & 0xfc000000) == BRANCH))
+	{
+	  DBG (CALLDEBUG,
+	       printf ("[find_call] 0x%lx: bl", (unsigned long) pc));
+
+	  /* Regular pc relative addressing check that this is the
+	      address of a function.  */
+	  offset = ((insn & 0x3ffffff) << 2)  & ((1U << 28) - 1);
+
+	  dest_pc = pc + ((offset ^ 0x8000000) - 0x8000000);
+
+	  if (hist_check_address (dest_pc))
+	    {
+
+	      child = sym_lookup (&symtab, dest_pc);
+
+	      if (child)
+		{
+		  DBG (CALLDEBUG,
+		       printf ("\tdest_pc=0x%lx, (name=%s, addr=0x%lx)\n",
+			       (unsigned long) dest_pc, child->name,
+			       (unsigned long) child->addr));
+
+		  if (child->addr == dest_pc)
+		    {
+		      /* a hit.  */
+		      arc_add (parent, child, (unsigned long) 0);
+		      continue;
+		    }
+		}
+	   }
+
+	  /* Something funny going on.  */
+	  DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
+	}
+    }
+}
diff -urN src/gprof/corefile.c src-patch/gprof/corefile.c
--- src/gprof/corefile.c	2012-09-20 18:45:48.000000000 +0530
+++ src-patch/gprof/corefile.c	2013-05-21 11:59:02.851672653 +0530
@@ -54,6 +54,7 @@ 
 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)
@@ -320,6 +321,10 @@ 
       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));
diff -urN src/gprof/Makefile.am src-patch/gprof/Makefile.am
--- src/gprof/Makefile.am	2012-12-17 22:26:03.000000000 +0530
+++ src-patch/gprof/Makefile.am	2013-05-21 11:59:02.851672653 +0530
@@ -43,7 +43,7 @@ 
 sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
 	cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
 	search_list.c symtab.c sym_ids.c utils.c \
-	i386.c alpha.c vax.c tahoe.c sparc.c mips.c
+	i386.c alpha.c vax.c tahoe.c sparc.c mips.c aarch64.c
 gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
 gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL_DEP)
 gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL)
diff -urN src/gprof/Makefile.in src-patch/gprof/Makefile.in
--- src/gprof/Makefile.in	2012-12-17 22:26:03.000000000 +0530
+++ src-patch/gprof/Makefile.in	2013-05-21 16:52:49.107417494 +0530
@@ -92,7 +92,8 @@ 
 	hertz.$(OBJEXT) hist.$(OBJEXT) source.$(OBJEXT) \
 	search_list.$(OBJEXT) symtab.$(OBJEXT) sym_ids.$(OBJEXT) \
 	utils.$(OBJEXT) i386.$(OBJEXT) alpha.$(OBJEXT) vax.$(OBJEXT) \
-	tahoe.$(OBJEXT) sparc.$(OBJEXT) mips.$(OBJEXT)
+	tahoe.$(OBJEXT) sparc.$(OBJEXT) mips.$(OBJEXT) \
+	aarch64.$(OBJEXT)
 am_gprof_OBJECTS = $(am__objects_1) flat_bl.$(OBJEXT) \
 	bsd_callg_bl.$(OBJEXT) fsf_callg_bl.$(OBJEXT)
 gprof_OBJECTS = $(am_gprof_OBJECTS)
@@ -309,7 +310,7 @@ 
 sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
 	cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
 	search_list.c symtab.c sym_ids.c utils.c \
-	i386.c alpha.c vax.c tahoe.c sparc.c mips.c
+	i386.c alpha.c vax.c tahoe.c sparc.c mips.c aarch64.c
 
 gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
 gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL_DEP)
@@ -451,6 +452,7 @@ 
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic_blocks.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_callg_bl.Po@am__quote@