@@ -0,0 +1,100 @@
+/* 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"
+
+#define BRANCH_MASK 0x7c000000
+#define BRANCH_PATTERN 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 & BRANCH_MASK) == BRANCH_PATTERN)
+ {
+ 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);
+
+ 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"));
+ }
+ }
+}
@@ -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));
@@ -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)
@@ -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@