X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gprof%2Fcall_graph.c;h=1ccf94994fe9a14d0ddaaab929f6831ba17fcbcb;hb=d835a58baae720abe909795cb68763040d1750a8;hp=6eee251ff0849cbf5fa5d239502288949dec26f1;hpb=abd8680d6efd97e7ba848a6392ee3ad72be18cd0;p=deliverable%2Fbinutils-gdb.git diff --git a/gprof/call_graph.c b/gprof/call_graph.c index 6eee251ff0..1ccf94994f 100644 --- a/gprof/call_graph.c +++ b/gprof/call_graph.c @@ -1,14 +1,37 @@ +/* call_graph.c - Create call graphs. + + Copyright (C) 1999-2020 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" #include "cg_arcs.h" #include "call_graph.h" #include "corefile.h" #include "gmon_io.h" #include "gmon_out.h" -#include "symtab.h" #include "sym_ids.h" -extern void -DEFUN (cg_tally, (from_pc, self_pc, count), - bfd_vma from_pc AND bfd_vma self_pc AND unsigned long count) +void +cg_tally (bfd_vma from_pc, bfd_vma self_pc, unsigned long count) { Sym *parent; Sym *child; @@ -25,20 +48,17 @@ DEFUN (cg_tally, (from_pc, self_pc, count), line number in the calling routing, but the child should always point to a function entry point, so we back up in the symbol table until we find it. - + For normal profiling, is_func will be set on all symbols, so this code will do nothing. */ - while (child >= symtab.base && ! child->is_func) --child; if (child < symtab.base) return; - /* - * Keep arc if it is on INCL_ARCS table or if the INCL_ARCS table - * is empty and it is not in the EXCL_ARCS table. - */ + /* Keep arc if it is on INCL_ARCS table or if the INCL_ARCS table + is empty and it is not in the EXCL_ARCS table. */ if (sym_id_arc_is_present (&syms[INCL_ARCS], parent, child) || (syms[INCL_ARCS].len == 0 && !sym_id_arc_is_present (&syms[EXCL_ARCS], parent, child))) @@ -51,47 +71,41 @@ DEFUN (cg_tally, (from_pc, self_pc, count), } } +/* Read a record from file IFP describing an arc in the function + call-graph and the count of how many times the arc has been + traversed. FILENAME is the name of file IFP and is provided + for formatting error-messages only. */ -/* - * Read a record from file IFP describing an arc in the function - * call-graph and the count of how many times the arc has been - * traversed. FILENAME is the name of file IFP and is provided - * for formatting error-messages only. - */ void -DEFUN (cg_read_rec, (ifp, filename), FILE * ifp AND CONST char *filename) +cg_read_rec (FILE *ifp, const char *filename) { bfd_vma from_pc, self_pc; - struct gmon_cg_arc_record arc; - unsigned long count; + unsigned int count; - if (fread (&arc, sizeof (arc), 1, ifp) != 1) + if (gmon_io_read_vma (ifp, &from_pc) + || gmon_io_read_vma (ifp, &self_pc) + || gmon_io_read_32 (ifp, &count)) { fprintf (stderr, _("%s: %s: unexpected end of file\n"), whoami, filename); done (1); } - from_pc = get_vma (core_bfd, (bfd_byte *) arc.from_pc); - self_pc = get_vma (core_bfd, (bfd_byte *) arc.self_pc); - count = bfd_get_32 (core_bfd, (bfd_byte *) arc.count); + DBG (SAMPLEDEBUG, printf ("[cg_read_rec] frompc 0x%lx selfpc 0x%lx count %lu\n", - (unsigned long) from_pc, (unsigned long) self_pc, count)); - /* add this arc: */ + (unsigned long) from_pc, (unsigned long) self_pc, + (unsigned long) count)); + /* Add this arc: */ cg_tally (from_pc, self_pc, count); } +/* Write all the arcs in the call-graph to file OFP. FILENAME is + the name of OFP and is provided for formatting error-messages + only. */ -/* - * Write all the arcs in the call-graph to file OFP. FILENAME is - * the name of OFP and is provided for formatting error-messages - * only. - */ void -DEFUN (cg_write_arcs, (ofp, filename), FILE * ofp AND const char *filename) +cg_write_arcs (FILE *ofp, const char *filename) { - const unsigned char tag = GMON_TAG_CG_ARC; - struct gmon_cg_arc_record raw_arc; Arc *arc; Sym *sym; @@ -99,11 +113,10 @@ DEFUN (cg_write_arcs, (ofp, filename), FILE * ofp AND const char *filename) { for (arc = sym->cg.children; arc; arc = arc->next_child) { - put_vma (core_bfd, arc->parent->addr, (bfd_byte *) raw_arc.from_pc); - put_vma (core_bfd, arc->child->addr, (bfd_byte *) raw_arc.self_pc); - bfd_put_32 (core_bfd, arc->count, (bfd_byte *) raw_arc.count); - if (fwrite (&tag, sizeof (tag), 1, ofp) != 1 - || fwrite (&raw_arc, sizeof (raw_arc), 1, ofp) != 1) + if (gmon_io_write_8 (ofp, GMON_TAG_CG_ARC) + || gmon_io_write_vma (ofp, arc->parent->addr) + || gmon_io_write_vma (ofp, arc->child->addr) + || gmon_io_write_32 (ofp, arc->count)) { perror (filename); done (1);