mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 10:03:47 +08:00
David Mosberger's fixes for cross compiling gprof.
This commit is contained in:
parent
04847a4d3e
commit
0eee5820aa
@ -1,3 +1,66 @@
|
||||
2001-03-13 David Mosberger <davidm@hpl.hp.com>
|
||||
|
||||
* hist.c (hist_dimension): Declare as an array of 16 characters.
|
||||
(hist_read_rec): If SAMPLEDEBUG, print each histogram bin count.
|
||||
|
||||
* basic_blocks.c: Whitespace and formatting changes.
|
||||
* bb_exit_func.c: Ditto.
|
||||
* call_graph.c: Ditto.
|
||||
* call_graph.h: Ditto.
|
||||
* cg_arcs.c: Ditto.
|
||||
* cg_print.c: Ditto.
|
||||
* cg_print.h: Ditto.
|
||||
* corefile.c: Ditto.
|
||||
* corefile.h: Ditto.
|
||||
* gmon_io.c: Ditto.
|
||||
* gmon_io.h: Ditto.
|
||||
* gmon_out.h: Ditto.
|
||||
* gprof.c: Ditto.
|
||||
* hist.c: Ditto.
|
||||
* hist.h: Ditto.
|
||||
* i386.c: Ditto.
|
||||
* search_list.c: Ditto.
|
||||
* search_list.h: Ditto.
|
||||
* source.c: Ditto.
|
||||
* source.h: Ditto.
|
||||
* sym_ids.c: Ditto.
|
||||
* sym_ids.h: Ditto.
|
||||
* symtab.c: Ditto.
|
||||
* symtab.h: Ditto.
|
||||
* tahoe.c: Ditto.
|
||||
* utils.c: Ditto.
|
||||
* vax.c: Ditto.
|
||||
|
||||
* gmon_out.h (gmon_hist_hdr): Delete.
|
||||
(gmon_cg_arc_record): Delete.
|
||||
|
||||
* gmon_io.c (put_vma): Declare "static".
|
||||
(get_vma): Ditto.
|
||||
(gmon_io_write): New function.
|
||||
(gmon_io_write_8): Ditto.
|
||||
(gmon_io_write_32): Ditto.
|
||||
(gmon_io_write_vma): Ditto.
|
||||
(gmon_io_read): Ditto.
|
||||
(gmon_io_read_32): Ditto.
|
||||
(gmon_io_read_vma): Ditto.
|
||||
* basic_blocks.c (bb_read_rec): Use gmon_io_read* / gmon_io_write*
|
||||
to read/write data file in a more portable fashion.
|
||||
(bb_write_blocks): Ditto.
|
||||
* call_graph.c (cg_read_rec): Ditto.
|
||||
(cg_write_arcs): Ditto.
|
||||
* hist.c (hist_read_rec): Ditto.
|
||||
(hist_write_hist): Ditto.
|
||||
|
||||
From Jes Sorensen <jes@linuxcare.com>
|
||||
* gmon_out.h: Use GMON_PTR_SIZE instead of sizeof(char*).
|
||||
* gmon.h: Ditto.
|
||||
* configure.in: Get GMON_PTR_SIZE from existing <sys/gmon_out.h>
|
||||
if it exists.
|
||||
* acconfig.h: New file. Mention and document GMON_PTR_SIZE.
|
||||
* gconfig.h: Regenerate.
|
||||
* configure: Regenerate.
|
||||
* Makefile.in: Regenerate.
|
||||
|
||||
2001-02-27 Alan Modra <alan@linuxcare.com.au>
|
||||
|
||||
* configure.in (BFD_VERSION): New.
|
||||
|
@ -182,12 +182,12 @@ NROFF = nroff
|
||||
HEADERS = $(noinst_HEADERS)
|
||||
|
||||
DIST_COMMON = ./stamp-h.in ChangeLog Makefile.am Makefile.in TODO \
|
||||
acinclude.m4 aclocal.m4 configure configure.in gconfig.in
|
||||
acconfig.h acinclude.m4 aclocal.m4 configure configure.in gconfig.in
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = gtar
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
SOURCES = $(gprof_SOURCES)
|
||||
OBJECTS = $(gprof_OBJECTS)
|
||||
@ -225,7 +225,7 @@ $(srcdir)/gconfig.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
|
||||
rm -f $(srcdir)/stamp-h.in; \
|
||||
$(MAKE) $(srcdir)/stamp-h.in; \
|
||||
else :; fi
|
||||
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
|
||||
cd $(top_srcdir) && $(AUTOHEADER)
|
||||
@echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
|
||||
|
||||
|
2
gprof/acconfig.h
Normal file
2
gprof/acconfig.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* Define as the size of a pointer in the target profile file format. */
|
||||
#undef GMON_PTR_SIZE
|
@ -58,7 +58,7 @@ DEFUN (cmp_bb, (lp, rp), const void *lp AND const void *rp)
|
||||
if (left->file && right->file)
|
||||
{
|
||||
r = strcmp (left->file->name, right->file->name);
|
||||
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@ -116,18 +116,17 @@ void
|
||||
DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
|
||||
{
|
||||
int nblocks, b;
|
||||
bfd_vma addr;
|
||||
unsigned long ncalls;
|
||||
bfd_vma addr, ncalls;
|
||||
Sym *sym;
|
||||
|
||||
if (fread (&nblocks, sizeof (nblocks), 1, ifp) != 1)
|
||||
if (gmon_io_read_32 (ifp, &nblocks))
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: unexpected end of file\n"), whoami, filename);
|
||||
fprintf (stderr, _("%s: %s: unexpected end of file\n"),
|
||||
whoami, filename);
|
||||
done (1);
|
||||
}
|
||||
|
||||
nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks);
|
||||
|
||||
if (gmon_file_version == 0)
|
||||
fskip_string (ifp);
|
||||
|
||||
@ -136,7 +135,7 @@ DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
|
||||
if (gmon_file_version == 0)
|
||||
{
|
||||
int line_num;
|
||||
|
||||
|
||||
/* Version 0 had lots of extra stuff that we don't
|
||||
care about anymore. */
|
||||
if ((fread (&ncalls, sizeof (ncalls), 1, ifp) != 1)
|
||||
@ -149,24 +148,17 @@ DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
|
||||
done (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (gmon_io_read_vma (ifp, &addr)
|
||||
|| gmon_io_read_vma (ifp, &ncalls))
|
||||
{
|
||||
if (fread (&addr, sizeof (addr), 1, ifp) != 1
|
||||
|| fread (&ncalls, sizeof (ncalls), 1, ifp) != 1)
|
||||
{
|
||||
perror (filename);
|
||||
done (1);
|
||||
}
|
||||
perror (filename);
|
||||
done (1);
|
||||
}
|
||||
|
||||
/* Basic-block execution counts are meaningful only if we're
|
||||
profiling at the line-by-line level: */
|
||||
profiling at the line-by-line level: */
|
||||
if (line_granularity)
|
||||
{
|
||||
/* Convert from target to host endianness: */
|
||||
addr = get_vma (core_bfd, (bfd_byte *) & addr);
|
||||
ncalls = bfd_get_32 (core_bfd, (bfd_byte *) &ncalls);
|
||||
|
||||
sym = sym_lookup (&symtab, addr);
|
||||
|
||||
if (sym)
|
||||
@ -176,7 +168,7 @@ DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
|
||||
DBG (BBDEBUG,
|
||||
printf ("[bb_read_rec] 0x%lx->0x%lx (%s:%d) cnt=%lu\n",
|
||||
(unsigned long) addr, (unsigned long) sym->addr,
|
||||
sym->name, sym->line_num, ncalls));
|
||||
sym->name, sym->line_num, (unsigned long) ncalls));
|
||||
|
||||
for (i = 0; i < NBBS; i++)
|
||||
{
|
||||
@ -211,10 +203,7 @@ DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
|
||||
void
|
||||
DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename)
|
||||
{
|
||||
const unsigned char tag = GMON_TAG_BB_COUNT;
|
||||
int nblocks = 0;
|
||||
bfd_vma addr;
|
||||
unsigned long ncalls;
|
||||
Sym *sym;
|
||||
int i;
|
||||
|
||||
@ -227,9 +216,8 @@ DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename)
|
||||
}
|
||||
|
||||
/* Write header: */
|
||||
bfd_put_32 (core_bfd, nblocks, (bfd_byte *) & nblocks);
|
||||
if (fwrite (&tag, sizeof (tag), 1, ofp) != 1
|
||||
|| fwrite (&nblocks, sizeof (nblocks), 1, ofp) != 1)
|
||||
if (gmon_io_write_8 (ofp, GMON_TAG_BB_COUNT)
|
||||
|| gmon_io_write_32 (ofp, nblocks))
|
||||
{
|
||||
perror (filename);
|
||||
done (1);
|
||||
@ -240,11 +228,8 @@ DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename)
|
||||
{
|
||||
for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
|
||||
{
|
||||
put_vma (core_bfd, sym->bb_addr[i], (bfd_byte *) & addr);
|
||||
bfd_put_32 (core_bfd, sym->bb_calls[i], (bfd_byte *) & ncalls);
|
||||
|
||||
if (fwrite (&addr, sizeof (addr), 1, ofp) != 1
|
||||
|| fwrite (&ncalls, sizeof (ncalls), 1, ofp) != 1)
|
||||
if (gmon_io_write_vma (ofp, sym->bb_addr[i])
|
||||
|| gmon_io_write_vma (ofp, sym->bb_calls[i]))
|
||||
{
|
||||
perror (filename);
|
||||
done (1);
|
||||
@ -255,8 +240,8 @@ DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename)
|
||||
|
||||
/* Output basic-block statistics in a format that is easily parseable.
|
||||
Current the format is:
|
||||
|
||||
<filename>:<line-number>: (<function-name>:<bb-addr): <ncalls> */
|
||||
|
||||
<filename>:<line-number>: (<function-name>:<bb-addr): <ncalls> */
|
||||
|
||||
void
|
||||
DEFUN_VOID (print_exec_counts)
|
||||
@ -272,12 +257,12 @@ DEFUN_VOID (print_exec_counts)
|
||||
/* Sort basic-blocks according to function name and line number: */
|
||||
sorted_bbs = (Sym **) xmalloc (symtab.len * sizeof (sorted_bbs[0]));
|
||||
len = 0;
|
||||
|
||||
|
||||
for (sym = symtab.base; sym < symtab.limit; ++sym)
|
||||
{
|
||||
/* Accept symbol if it's in the INCL_EXEC table
|
||||
or there is no INCL_EXEC table
|
||||
and it does not appear in the EXCL_EXEC table. */
|
||||
or there is no INCL_EXEC table
|
||||
and it does not appear in the EXCL_EXEC table. */
|
||||
if (sym_lookup (&syms[INCL_EXEC], sym->addr)
|
||||
|| (syms[INCL_EXEC].len == 0
|
||||
&& !sym_lookup (&syms[EXCL_EXEC], sym->addr)))
|
||||
@ -285,7 +270,7 @@ DEFUN_VOID (print_exec_counts)
|
||||
sorted_bbs[len++] = sym;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qsort (sorted_bbs, len, sizeof (sorted_bbs[0]), cmp_bb);
|
||||
|
||||
/* Output basic-blocks: */
|
||||
@ -299,7 +284,7 @@ DEFUN_VOID (print_exec_counts)
|
||||
sym->file ? sym->file->name : _("<unknown>"), sym->line_num,
|
||||
sym->name, (unsigned long) sym->addr, sym->ncalls);
|
||||
}
|
||||
|
||||
|
||||
for (j = 0; j < NBBS && sym->bb_addr[j]; j ++)
|
||||
{
|
||||
if (sym->bb_calls[j] > 0 || ! ignore_zeros)
|
||||
@ -318,7 +303,7 @@ DEFUN_VOID (print_exec_counts)
|
||||
/* Helper for bb_annotated_source: format annotation containing
|
||||
number of line executions. Depends on being called on each
|
||||
line of a file in sequential order.
|
||||
|
||||
|
||||
Global variable bb_annotate_all_lines enables execution count
|
||||
compression (counts are supressed if identical to the last one)
|
||||
and prints counts on all executed lines. Otherwise, print
|
||||
@ -336,7 +321,7 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg),
|
||||
unsigned long last_print = (unsigned long) -1;
|
||||
|
||||
b = NULL;
|
||||
|
||||
|
||||
if (line_num <= sf->num_lines)
|
||||
b = sf->line[line_num - 1];
|
||||
|
||||
@ -363,11 +348,11 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg),
|
||||
ncalls_set = 0;
|
||||
|
||||
/* If this is a function entry point, label the line no matter what.
|
||||
Otherwise, we're in the middle of a function, so check to see
|
||||
if the first basic-block address is larger than the starting
|
||||
address of the line. If so, then this line begins with a
|
||||
a portion of the previous basic-block, so print that prior
|
||||
execution count (if bb_annotate_all_lines is set). */
|
||||
Otherwise, we're in the middle of a function, so check to see
|
||||
if the first basic-block address is larger than the starting
|
||||
address of the line. If so, then this line begins with a
|
||||
a portion of the previous basic-block, so print that prior
|
||||
execution count (if bb_annotate_all_lines is set). */
|
||||
if (b->is_func)
|
||||
{
|
||||
sprintf (p, "%lu", b->ncalls);
|
||||
@ -388,8 +373,8 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg),
|
||||
}
|
||||
|
||||
/* Loop through all of this line's basic-blocks. For each one,
|
||||
update last_count, then compress sequential identical counts
|
||||
(if bb_annotate_all_lines) and print the execution count. */
|
||||
update last_count, then compress sequential identical counts
|
||||
(if bb_annotate_all_lines) and print the execution count. */
|
||||
|
||||
for (i = 0; i < NBBS && b->bb_addr[i]; i++)
|
||||
{
|
||||
@ -413,10 +398,10 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg),
|
||||
}
|
||||
|
||||
/* We're done. If nothing has been printed on this line,
|
||||
print the last execution count (bb_annotate_all_lines),
|
||||
which could be from either a previous line (if there were
|
||||
no BBs on this line), or from this line (if all our BB
|
||||
counts were compressed out because they were identical). */
|
||||
print the last execution count (bb_annotate_all_lines),
|
||||
which could be from either a previous line (if there were
|
||||
no BBs on this line), or from this line (if all our BB
|
||||
counts were compressed out because they were identical). */
|
||||
|
||||
if (bb_annotate_all_lines && p == tmpbuf)
|
||||
{
|
||||
@ -481,9 +466,9 @@ DEFUN_VOID (print_annotated_source)
|
||||
for (sym = symtab.base; sym < symtab.limit; ++sym)
|
||||
{
|
||||
/* Accept symbol if it's file is known, its line number is
|
||||
bigger than anything we have seen for that file so far and
|
||||
if it's in the INCL_ANNO table or there is no INCL_ANNO
|
||||
table and it does not appear in the EXCL_ANNO table. */
|
||||
bigger than anything we have seen for that file so far and
|
||||
if it's in the INCL_ANNO table or there is no INCL_ANNO
|
||||
table and it does not appear in the EXCL_ANNO table. */
|
||||
if (sym->file && sym->line_num > sym->file->num_lines
|
||||
&& (sym_lookup (&syms[INCL_ANNO], sym->addr)
|
||||
|| (syms[INCL_ANNO].len == 0
|
||||
@ -513,7 +498,7 @@ DEFUN_VOID (print_annotated_source)
|
||||
{
|
||||
sym->file->ncalls += sym->ncalls;
|
||||
line_stats = sym->file->line[sym->line_num - 1];
|
||||
|
||||
|
||||
if (!line_stats)
|
||||
{
|
||||
/* Common case has at most one basic-block per source line: */
|
||||
@ -543,7 +528,7 @@ DEFUN_VOID (print_annotated_source)
|
||||
continue;
|
||||
|
||||
num_executable_lines = num_lines_executed = 0;
|
||||
|
||||
|
||||
ofp = annotate_source (sf, 16, annotate_with_count, sf);
|
||||
if (!ofp)
|
||||
continue;
|
||||
@ -556,14 +541,14 @@ DEFUN_VOID (print_annotated_source)
|
||||
/* Abuse line arrays---it's not needed anymore: */
|
||||
qsort (sf->line, sf->num_lines, sizeof (sf->line[0]), cmp_ncalls);
|
||||
table_len = bb_table_length;
|
||||
|
||||
|
||||
if (table_len > sf->num_lines)
|
||||
table_len = sf->num_lines;
|
||||
|
||||
|
||||
for (i = 0; i < table_len; ++i)
|
||||
{
|
||||
sym = sf->line[i];
|
||||
|
||||
|
||||
if (!sym || sym->ncalls == 0)
|
||||
break;
|
||||
|
||||
@ -588,7 +573,7 @@ DEFUN_VOID (print_annotated_source)
|
||||
num_executable_lines
|
||||
? (double) sf->ncalls / (double) num_executable_lines
|
||||
: 0.0);
|
||||
|
||||
|
||||
if (ofp != stdout)
|
||||
fclose (ofp);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* bb_exit_func.c - dumps all the basic-block statistics linked into
|
||||
the bb_head chain to .d files.
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -30,64 +30,64 @@
|
||||
#include "gmon_out.h"
|
||||
|
||||
/* structure emitted by -a */
|
||||
struct bb {
|
||||
long zero_word;
|
||||
const char *filename;
|
||||
long *counts;
|
||||
long ncounts;
|
||||
struct bb *next;
|
||||
const unsigned long *addresses;
|
||||
struct bb
|
||||
{
|
||||
long zero_word;
|
||||
const char *filename;
|
||||
long *counts;
|
||||
long ncounts;
|
||||
struct bb *next;
|
||||
const unsigned long *addresses;
|
||||
};
|
||||
|
||||
struct bb *__bb_head = (struct bb *)0;
|
||||
struct bb *__bb_head = (struct bb *) 0;
|
||||
|
||||
|
||||
void
|
||||
__bb_exit_func (void)
|
||||
{
|
||||
const int version = GMON_VERSION;
|
||||
struct gmon_hdr ghdr;
|
||||
struct bb *ptr;
|
||||
FILE *fp;
|
||||
/*
|
||||
* GEN_GMON_CNT_FILE should be defined on systems with mcleanup()
|
||||
* functions that do not write basic-block to gmon.out. In such
|
||||
* cases profiling with "-pg -a" would result in a gmon.out file
|
||||
* without basic-block info (because the file written here would
|
||||
* be overwritten. Thus, a separate file is generated instead.
|
||||
* The two files can easily be combined by specifying them
|
||||
* on gprof's command line (and possibly generating a gmon.sum
|
||||
* file with "gprof -s").
|
||||
*/
|
||||
const int version = GMON_VERSION;
|
||||
struct gmon_hdr ghdr;
|
||||
struct bb *ptr;
|
||||
FILE *fp;
|
||||
/* GEN_GMON_CNT_FILE should be defined on systems with mcleanup()
|
||||
functions that do not write basic-block to gmon.out. In such
|
||||
cases profiling with "-pg -a" would result in a gmon.out file
|
||||
without basic-block info (because the file written here would be
|
||||
overwritten. Thus, a separate file is generated instead. The
|
||||
two files can easily be combined by specifying them on gprof's
|
||||
command line (and possibly generating a gmon.sum file with "gprof
|
||||
-s"). */
|
||||
#ifndef GEN_GMON_CNT_FILE
|
||||
# define OUT_NAME "gmon.out"
|
||||
#else
|
||||
# define OUT_NAME "gmon.cnt"
|
||||
#endif
|
||||
fp = fopen(OUT_NAME, "wb");
|
||||
if (!fp) {
|
||||
perror(OUT_NAME);
|
||||
return;
|
||||
} /* if */
|
||||
memcpy(&ghdr.cookie[0], GMON_MAGIC, 4);
|
||||
memcpy(&ghdr.version, &version, sizeof(version));
|
||||
fwrite(&ghdr, sizeof(ghdr), 1, fp);
|
||||
fp = fopen (OUT_NAME, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
perror (OUT_NAME);
|
||||
return;
|
||||
}
|
||||
memcpy (&ghdr.cookie[0], GMON_MAGIC, 4);
|
||||
memcpy (&ghdr.version, &version, sizeof (version));
|
||||
fwrite (&ghdr, sizeof (ghdr), 1, fp);
|
||||
|
||||
for (ptr = __bb_head; ptr != 0; ptr = ptr->next) {
|
||||
u_int ncounts = ptr->ncounts;
|
||||
u_char tag;
|
||||
u_int i;
|
||||
for (ptr = __bb_head; ptr != 0; ptr = ptr->next)
|
||||
{
|
||||
u_int ncounts = ptr->ncounts;
|
||||
u_char tag;
|
||||
u_int i;
|
||||
|
||||
tag = GMON_TAG_BB_COUNT;
|
||||
fwrite(&tag, sizeof(tag), 1, fp);
|
||||
fwrite(&ncounts, sizeof(ncounts), 1, fp);
|
||||
tag = GMON_TAG_BB_COUNT;
|
||||
fwrite (&tag, sizeof (tag), 1, fp);
|
||||
fwrite (&ncounts, sizeof (ncounts), 1, fp);
|
||||
|
||||
for (i = 0; i < ncounts; ++i) {
|
||||
fwrite(&ptr->addresses[i], sizeof(ptr->addresses[0]), 1, fp);
|
||||
fwrite(&ptr->counts[i], sizeof(ptr->counts[0]), 1, fp);
|
||||
} /* for */
|
||||
} /* for */
|
||||
fclose (fp);
|
||||
} /* __bb_exit_func */
|
||||
|
||||
/*** end of __bb_exit_func.c ***/
|
||||
for (i = 0; i < ncounts; ++i)
|
||||
{
|
||||
fwrite (&ptr->addresses[i], sizeof (ptr->addresses[0]), 1, fp);
|
||||
fwrite (&ptr->counts[i], sizeof (ptr->counts[0]), 1, fp);
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* call_graph.c - Create call graphs.
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -46,7 +46,7 @@ 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)
|
||||
@ -78,22 +78,21 @@ void
|
||||
DEFUN (cg_read_rec, (ifp, filename), FILE * ifp AND 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));
|
||||
(unsigned long) from_pc, (unsigned long) self_pc,
|
||||
(unsigned long) count));
|
||||
/* Add this arc: */
|
||||
cg_tally (from_pc, self_pc, count);
|
||||
}
|
||||
@ -105,8 +104,6 @@ DEFUN (cg_read_rec, (ifp, filename), FILE * ifp AND CONST char *filename)
|
||||
void
|
||||
DEFUN (cg_write_arcs, (ofp, filename), FILE * ofp AND const char *filename)
|
||||
{
|
||||
const unsigned char tag = GMON_TAG_CG_ARC;
|
||||
struct gmon_cg_arc_record raw_arc;
|
||||
Arc *arc;
|
||||
Sym *sym;
|
||||
|
||||
@ -114,11 +111,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);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* call_graph.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* Copyright (c) 1983, 2001 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
@ -102,7 +102,7 @@ DEFUN (arc_add, (parent, child, count),
|
||||
if (maxarcs == 0)
|
||||
maxarcs = 1;
|
||||
maxarcs *= 2;
|
||||
|
||||
|
||||
/* Allocate the new array. */
|
||||
newarcs = (Arc **)xmalloc(sizeof (Arc *) * maxarcs);
|
||||
|
||||
|
142
gprof/cg_print.c
142
gprof/cg_print.c
@ -1,6 +1,6 @@
|
||||
/* cg_print.c - Print routines for displaying call graphs.
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -47,7 +47,7 @@ DEFUN_VOID (print_header)
|
||||
first_output = FALSE;
|
||||
else
|
||||
printf ("\f\n");
|
||||
|
||||
|
||||
if (!bsd_style_output)
|
||||
{
|
||||
if (print_descriptions)
|
||||
@ -55,21 +55,21 @@ DEFUN_VOID (print_header)
|
||||
else
|
||||
printf (_("\t\t\tCall graph\n\n"));
|
||||
}
|
||||
|
||||
|
||||
printf (_("\ngranularity: each sample hit covers %ld byte(s)"),
|
||||
(long) hist_scale * sizeof (UNIT));
|
||||
|
||||
|
||||
if (print_time > 0.0)
|
||||
printf (_(" for %.2f%% of %.2f seconds\n\n"),
|
||||
100.0 / print_time, print_time / hz);
|
||||
else
|
||||
{
|
||||
printf (_(" no time propagated\n\n"));
|
||||
|
||||
|
||||
/* This doesn't hurt, since all the numerators will be 0.0. */
|
||||
print_time = 1.0;
|
||||
}
|
||||
|
||||
|
||||
if (bsd_style_output)
|
||||
{
|
||||
printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
|
||||
@ -100,7 +100,7 @@ DEFUN (print_cycle, (cyc), Sym * cyc)
|
||||
: "%-6.6s %5.1f %7.2f %7.2f %7lu", buf,
|
||||
100 * (cyc->cg.prop.self + cyc->cg.prop.child) / print_time,
|
||||
cyc->cg.prop.self / hz, cyc->cg.prop.child / hz, cyc->ncalls);
|
||||
|
||||
|
||||
if (cyc->cg.self_calls != 0)
|
||||
printf ("+%-7lu", cyc->cg.self_calls);
|
||||
else
|
||||
@ -141,22 +141,22 @@ static void
|
||||
DEFUN (sort_members, (cyc), Sym * cyc)
|
||||
{
|
||||
Sym *todo, *doing, *prev;
|
||||
|
||||
|
||||
/* Detach cycle members from cyclehead,
|
||||
and insertion sort them back on. */
|
||||
todo = cyc->cg.cyc.next;
|
||||
cyc->cg.cyc.next = 0;
|
||||
|
||||
|
||||
for (doing = todo; doing && doing->cg.cyc.next; doing = todo)
|
||||
{
|
||||
todo = doing->cg.cyc.next;
|
||||
|
||||
|
||||
for (prev = cyc; prev->cg.cyc.next; prev = prev->cg.cyc.next)
|
||||
{
|
||||
if (cmp_member (doing, prev->cg.cyc.next) == GREATERTHAN)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
doing->cg.cyc.next = prev->cg.cyc.next;
|
||||
prev->cg.cyc.next = doing;
|
||||
}
|
||||
@ -170,7 +170,7 @@ DEFUN (print_members, (cyc), Sym * cyc)
|
||||
Sym *member;
|
||||
|
||||
sort_members (cyc);
|
||||
|
||||
|
||||
for (member = cyc->cg.cyc.next; member; member = member->cg.cyc.next)
|
||||
{
|
||||
printf (bsd_style_output
|
||||
@ -178,7 +178,7 @@ DEFUN (print_members, (cyc), Sym * cyc)
|
||||
: "%6.6s %5.5s %7.2f %7.2f %7lu",
|
||||
"", "", member->cg.prop.self / hz, member->cg.prop.child / hz,
|
||||
member->ncalls);
|
||||
|
||||
|
||||
if (member->cg.self_calls != 0)
|
||||
printf ("+%-7lu", member->cg.self_calls);
|
||||
else
|
||||
@ -191,12 +191,12 @@ DEFUN (print_members, (cyc), Sym * cyc)
|
||||
}
|
||||
|
||||
/* Compare two arcs to/from the same child/parent.
|
||||
- if one arc is a self arc, it's least.
|
||||
- if one arc is within a cycle, it's less than.
|
||||
- if both arcs are within a cycle, compare arc counts.
|
||||
- if neither arc is within a cycle, compare with
|
||||
time + child_time as major key
|
||||
arc count as minor key. */
|
||||
- if one arc is a self arc, it's least.
|
||||
- if one arc is within a cycle, it's less than.
|
||||
- if both arcs are within a cycle, compare arc counts.
|
||||
- if neither arc is within a cycle, compare with
|
||||
time + child_time as major key
|
||||
arc count as minor key. */
|
||||
|
||||
static int
|
||||
DEFUN (cmp_arc, (left, right), Arc * left AND Arc * right)
|
||||
@ -222,7 +222,7 @@ DEFUN (cmp_arc, (left, right), Arc * left AND Arc * right)
|
||||
right->count, right_child->ncalls);
|
||||
printf ("\n");
|
||||
);
|
||||
|
||||
|
||||
if (left_parent == left_child)
|
||||
return LESSTHAN; /* Left is a self call. */
|
||||
|
||||
@ -265,7 +265,7 @@ DEFUN (cmp_arc, (left, right), Arc * left AND Arc * right)
|
||||
/* Neither is a call within a cycle. */
|
||||
left_time = left->time + left->child_time;
|
||||
right_time = right->time + right->child_time;
|
||||
|
||||
|
||||
if (left_time < right_time)
|
||||
return LESSTHAN;
|
||||
|
||||
@ -291,12 +291,12 @@ DEFUN (sort_parents, (child), Sym * child)
|
||||
|
||||
/* Unlink parents from child, then insertion sort back on to
|
||||
sorted's parents.
|
||||
*arc the arc you have detached and are inserting.
|
||||
*detached the rest of the arcs to be sorted.
|
||||
sorted arc list onto which you insertion sort.
|
||||
*prev arc before the arc you are comparing. */
|
||||
*arc the arc you have detached and are inserting.
|
||||
*detached the rest of the arcs to be sorted.
|
||||
sorted arc list onto which you insertion sort.
|
||||
*prev arc before the arc you are comparing. */
|
||||
sorted.next_parent = 0;
|
||||
|
||||
|
||||
for (arc = child->cg.parents; arc; arc = detached)
|
||||
{
|
||||
detached = arc->next_parent;
|
||||
@ -307,7 +307,7 @@ DEFUN (sort_parents, (child), Sym * child)
|
||||
if (cmp_arc (arc, prev->next_parent) != GREATERTHAN)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
arc->next_parent = prev->next_parent;
|
||||
prev->next_parent = arc;
|
||||
}
|
||||
@ -328,7 +328,7 @@ DEFUN (print_parents, (child), Sym * child)
|
||||
cycle_head = child->cg.cyc.head;
|
||||
else
|
||||
cycle_head = child;
|
||||
|
||||
|
||||
if (!child->cg.parents)
|
||||
{
|
||||
printf (bsd_style_output
|
||||
@ -337,9 +337,9 @@ DEFUN (print_parents, (child), Sym * child)
|
||||
"", "", "", "", "", "");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
sort_parents (child);
|
||||
|
||||
|
||||
for (arc = child->cg.parents; arc; arc = arc->next_parent)
|
||||
{
|
||||
parent = arc->parent;
|
||||
@ -375,15 +375,15 @@ static void
|
||||
DEFUN (sort_children, (parent), Sym * parent)
|
||||
{
|
||||
Arc *arc, *detached, sorted, *prev;
|
||||
|
||||
|
||||
/* Unlink children from parent, then insertion sort back on to
|
||||
sorted's children.
|
||||
*arc the arc you have detached and are inserting.
|
||||
*detached the rest of the arcs to be sorted.
|
||||
sorted arc list onto which you insertion sort.
|
||||
*prev arc before the arc you are comparing. */
|
||||
*arc the arc you have detached and are inserting.
|
||||
*detached the rest of the arcs to be sorted.
|
||||
sorted arc list onto which you insertion sort.
|
||||
*prev arc before the arc you are comparing. */
|
||||
sorted.next_child = 0;
|
||||
|
||||
|
||||
for (arc = parent->cg.children; arc; arc = detached)
|
||||
{
|
||||
detached = arc->next_child;
|
||||
@ -394,7 +394,7 @@ DEFUN (sort_children, (parent), Sym * parent)
|
||||
if (cmp_arc (arc, prev->next_child) != LESSTHAN)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
arc->next_child = prev->next_child;
|
||||
prev->next_child = arc;
|
||||
}
|
||||
@ -412,7 +412,7 @@ DEFUN (print_children, (parent), Sym * parent)
|
||||
|
||||
sort_children (parent);
|
||||
arc = parent->cg.children;
|
||||
|
||||
|
||||
for (arc = parent->cg.children; arc; arc = arc->next_child)
|
||||
{
|
||||
child = arc->child;
|
||||
@ -454,11 +454,11 @@ DEFUN (print_line, (np), Sym * np)
|
||||
: "%-6.6s %5.1f %7.2f %7.2f", buf,
|
||||
100 * (np->cg.prop.self + np->cg.prop.child) / print_time,
|
||||
np->cg.prop.self / hz, np->cg.prop.child / hz);
|
||||
|
||||
|
||||
if ((np->ncalls + np->cg.self_calls) != 0)
|
||||
{
|
||||
printf (" %7lu", np->ncalls);
|
||||
|
||||
|
||||
if (np->cg.self_calls != 0)
|
||||
printf ("+%-7lu ", np->cg.self_calls);
|
||||
else
|
||||
@ -468,7 +468,7 @@ DEFUN (print_line, (np), Sym * np)
|
||||
{
|
||||
printf (" %7.7s %7.7s ", "", "");
|
||||
}
|
||||
|
||||
|
||||
print_name (np);
|
||||
printf ("\n");
|
||||
}
|
||||
@ -490,14 +490,14 @@ DEFUN (cg_print, (timesortsym), Sym ** timesortsym)
|
||||
for (index = 0; index < symtab.len + num_cycles; ++index)
|
||||
{
|
||||
parent = timesortsym[index];
|
||||
|
||||
|
||||
if ((ignore_zeros && parent->ncalls == 0
|
||||
&& parent->cg.self_calls == 0 && parent->cg.prop.self == 0
|
||||
&& parent->cg.prop.child == 0)
|
||||
|| !parent->cg.print_flag
|
||||
|| (line_granularity && ! parent->is_func))
|
||||
continue;
|
||||
|
||||
|
||||
if (!parent->name && parent->cg.cyc.num != 0)
|
||||
{
|
||||
/* Cycle header. */
|
||||
@ -510,18 +510,18 @@ DEFUN (cg_print, (timesortsym), Sym ** timesortsym)
|
||||
print_line (parent);
|
||||
print_children (parent);
|
||||
}
|
||||
|
||||
|
||||
if (bsd_style_output)
|
||||
printf ("\n");
|
||||
|
||||
|
||||
printf ("-----------------------------------------------\n");
|
||||
|
||||
|
||||
if (bsd_style_output)
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
|
||||
free (timesortsym);
|
||||
|
||||
|
||||
if (print_descriptions && !bsd_style_output)
|
||||
fsf_callg_blurb (stdout);
|
||||
}
|
||||
@ -547,11 +547,11 @@ DEFUN_VOID (cg_print_index)
|
||||
const char *filename;
|
||||
char buf[20];
|
||||
int column_width = (output_width - 1) / 3; /* Don't write in last col! */
|
||||
|
||||
|
||||
/* Now, sort regular function name
|
||||
alphabetically to create an index. */
|
||||
name_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *));
|
||||
|
||||
|
||||
for (index = 0, nnames = 0; index < symtab.len; index++)
|
||||
{
|
||||
if (ignore_zeros && symtab.base[index].ncalls == 0
|
||||
@ -560,25 +560,25 @@ DEFUN_VOID (cg_print_index)
|
||||
|
||||
name_sorted_syms[nnames++] = &symtab.base[index];
|
||||
}
|
||||
|
||||
|
||||
qsort (name_sorted_syms, nnames, sizeof (Sym *), cmp_name);
|
||||
|
||||
|
||||
for (index = 1, todo = nnames; index <= num_cycles; index++)
|
||||
name_sorted_syms[todo++] = &cycle_header[index];
|
||||
|
||||
printf ("\f\n");
|
||||
printf (_("Index by function name\n\n"));
|
||||
index = (todo + 2) / 3;
|
||||
|
||||
|
||||
for (i = 0; i < index; i++)
|
||||
{
|
||||
col = 0;
|
||||
starting_col = 0;
|
||||
|
||||
|
||||
for (j = i; j < todo; j += index)
|
||||
{
|
||||
sym = name_sorted_syms[j];
|
||||
|
||||
|
||||
if (sym->cg.print_flag)
|
||||
sprintf (buf, "[%d]", sym->cg.index);
|
||||
else
|
||||
@ -593,27 +593,27 @@ DEFUN_VOID (cg_print_index)
|
||||
else
|
||||
{
|
||||
col += strlen (buf);
|
||||
|
||||
|
||||
for (; col < starting_col + 5; ++col)
|
||||
putchar (' ');
|
||||
|
||||
printf (" %s ", buf);
|
||||
col += print_name_only (sym);
|
||||
|
||||
|
||||
if (!line_granularity && sym->is_static && sym->file)
|
||||
{
|
||||
filename = sym->file->name;
|
||||
|
||||
|
||||
if (!print_path)
|
||||
{
|
||||
filename = strrchr (filename, '/');
|
||||
|
||||
|
||||
if (filename)
|
||||
++filename;
|
||||
else
|
||||
filename = sym->file->name;
|
||||
}
|
||||
|
||||
|
||||
printf (" (%s)", filename);
|
||||
col += strlen (filename) + 3;
|
||||
}
|
||||
@ -638,13 +638,13 @@ DEFUN_VOID (cg_print_index)
|
||||
col += strlen (buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
starting_col += column_width;
|
||||
}
|
||||
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
|
||||
free (name_sorted_syms);
|
||||
}
|
||||
|
||||
@ -714,7 +714,7 @@ DEFUN (cmp_fun_nuses, (left, right), const PTR left AND const PTR right)
|
||||
Of course, profiling errors, machine limitations (PA long calls), and
|
||||
poor cutoff values for the placement algorithm may limit the usefullness
|
||||
of the resulting function order. Improvements would be greatly appreciated.
|
||||
|
||||
|
||||
Suggestions:
|
||||
|
||||
* Place the functions with many callers near the middle of the
|
||||
@ -749,7 +749,7 @@ DEFUN (cmp_fun_nuses, (left, right), const PTR left AND const PTR right)
|
||||
ordering which shares the same arc placement algorithm with
|
||||
the function ordering code (in fact it is a degenerate case
|
||||
of function ordering). */
|
||||
|
||||
|
||||
void
|
||||
DEFUN_VOID (cg_print_function_ordering)
|
||||
{
|
||||
@ -856,13 +856,13 @@ DEFUN_VOID (cg_print_function_ordering)
|
||||
Unfortunately, we don't know all these functions
|
||||
until we're done. So we keep track of all the arcs
|
||||
to the functions we care about, then prune out those
|
||||
which are uninteresting.
|
||||
which are uninteresting.
|
||||
|
||||
An interesting variation would be to quit when we found
|
||||
multi-call site functions which account for some percentage
|
||||
of the arcs. */
|
||||
arc = sym->cg.children;
|
||||
|
||||
|
||||
while (arc)
|
||||
{
|
||||
if (arc->parent != arc->child)
|
||||
@ -872,7 +872,7 @@ DEFUN_VOID (cg_print_function_ordering)
|
||||
}
|
||||
|
||||
arc = sym->cg.parents;
|
||||
|
||||
|
||||
while (arc)
|
||||
{
|
||||
if (arc->parent != arc->child)
|
||||
@ -992,7 +992,7 @@ order_and_dump_functions_by_arcs (arcs, numarcs, all,
|
||||
total_arcs = 0;
|
||||
|
||||
tmp_arcs = 0;
|
||||
|
||||
|
||||
for (index = 0; index < numarcs; index++)
|
||||
{
|
||||
Sym *sym1, *sym2;
|
||||
@ -1049,7 +1049,7 @@ order_and_dump_functions_by_arcs (arcs, numarcs, all,
|
||||
prev = prev->prev;
|
||||
prev_count++;
|
||||
}
|
||||
|
||||
|
||||
/* Choose the closest. */
|
||||
child = next_count < prev_count ? next : prev;
|
||||
}
|
||||
@ -1263,5 +1263,5 @@ DEFUN_VOID (cg_print_file_ordering)
|
||||
if (index2 == symtab.len)
|
||||
printf ("%s\n", symbol_map[index].file_name);
|
||||
last = symbol_map[index].file_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* cg_print.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
|
89
gprof/configure
vendored
89
gprof/configure
vendored
@ -4256,6 +4256,95 @@ echo "$ac_t""${ac_cv_exeext}" 1>&6
|
||||
ac_exeext=$EXEEXT
|
||||
|
||||
|
||||
for ac_hdr in sys/gmon_out.h
|
||||
do
|
||||
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
||||
echo "configure:4264: checking for $ac_hdr" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 4269 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <$ac_hdr>
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:4274: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_header_$ac_safe=yes"
|
||||
else
|
||||
echo "$ac_err" >&5
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_header_$ac_safe=no"
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
|
||||
echo "$ac_t""yes" 1>&6
|
||||
ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
|
||||
cat >> confdefs.h <<EOF
|
||||
#define $ac_tr_hdr 1
|
||||
EOF
|
||||
|
||||
else
|
||||
echo "$ac_t""no" 1>&6
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
echo $ac_n "checking the size of gmon pointers""... $ac_c" 1>&6
|
||||
echo "configure:4302: checking the size of gmon pointers" >&5
|
||||
if test "$cross_compiling" = yes; then
|
||||
gmon_ptr_size=4
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 4307 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if HAVE_SYS_GMON_OUT_H
|
||||
#include <sys/gmon_out.h>
|
||||
#endif
|
||||
main()
|
||||
{
|
||||
#if HAVE_SYS_GMON_OUT_H
|
||||
struct gmon_cg_arc_record arc;
|
||||
FILE *f=fopen("conftestval", "w");
|
||||
if (!f) exit(1);
|
||||
fprintf(f, "%d\n", sizeof(arc.from_pc));
|
||||
exit(0);
|
||||
#else
|
||||
FILE *f=fopen("conftestval", "w");
|
||||
if (!f) exit(1);
|
||||
fprintf(f, "%d\n", (int) sizeof(char *));
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
EOF
|
||||
if { (eval echo configure:4330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
gmon_ptr_size=`cat conftestval`
|
||||
else
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -fr conftest*
|
||||
gmon_ptr_size=4
|
||||
fi
|
||||
rm -fr conftest*
|
||||
fi
|
||||
|
||||
echo "$ac_t""$gmon_ptr_size" 1>&6
|
||||
|
||||
cat >> confdefs.h <<EOF
|
||||
#define GMON_PTR_SIZE $gmon_ptr_size
|
||||
EOF
|
||||
|
||||
|
||||
build_warnings="-W -Wall"
|
||||
# Check whether --enable-build-warnings or --disable-build-warnings was given.
|
||||
if test "${enable_build_warnings+set}" = set; then
|
||||
|
@ -29,6 +29,33 @@ CY_GNU_GETTEXT
|
||||
AM_MAINTAINER_MODE
|
||||
AC_EXEEXT
|
||||
|
||||
AC_CHECK_HEADERS(sys/gmon_out.h)
|
||||
|
||||
AC_MSG_CHECKING(the size of gmon pointers)
|
||||
AC_TRY_RUN([#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if HAVE_SYS_GMON_OUT_H
|
||||
#include <sys/gmon_out.h>
|
||||
#endif
|
||||
main()
|
||||
{
|
||||
#if HAVE_SYS_GMON_OUT_H
|
||||
struct gmon_cg_arc_record arc;
|
||||
FILE *f=fopen("conftestval", "w");
|
||||
if (!f) exit(1);
|
||||
fprintf(f, "%d\n", sizeof(arc.from_pc));
|
||||
exit(0);
|
||||
#else
|
||||
FILE *f=fopen("conftestval", "w");
|
||||
if (!f) exit(1);
|
||||
fprintf(f, "%d\n", (int) sizeof(char *));
|
||||
exit(1);
|
||||
#endif
|
||||
}], gmon_ptr_size=`cat conftestval`, gmon_ptr_size=4, gmon_ptr_size=4)
|
||||
AC_MSG_RESULT($gmon_ptr_size)
|
||||
|
||||
AC_DEFINE_UNQUOTED(GMON_PTR_SIZE, $gmon_ptr_size)
|
||||
|
||||
build_warnings="-W -Wall"
|
||||
AC_ARG_ENABLE(build-warnings,
|
||||
[ --enable-build-warnings Enable build-time compiler warnings if gcc is used],
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* corefile.c
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -178,7 +178,7 @@ DEFUN (core_init, (a_out_name), const char *a_out_name)
|
||||
|
||||
core_syms = (asymbol **) xmalloc (core_num_syms);
|
||||
core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
|
||||
|
||||
|
||||
if (core_num_syms < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
|
||||
@ -221,7 +221,7 @@ DEFUN (core_get_text_space, (core_bfd), bfd * core_bfd)
|
||||
whoami, (unsigned long) core_text_sect->_raw_size);
|
||||
done (1);
|
||||
}
|
||||
|
||||
|
||||
if (!bfd_get_section_contents (core_bfd, core_text_sect, core_text_space,
|
||||
0, core_text_sect->_raw_size))
|
||||
{
|
||||
@ -229,7 +229,7 @@ DEFUN (core_get_text_space, (core_bfd), bfd * core_bfd)
|
||||
free (core_text_space);
|
||||
core_text_space = 0;
|
||||
}
|
||||
|
||||
|
||||
if (!core_text_space)
|
||||
fprintf (stderr, _("%s: can't do -c\n"), whoami);
|
||||
}
|
||||
@ -271,9 +271,9 @@ DEFUN (find_call, (parent, p_lowpc, p_highpc),
|
||||
}
|
||||
|
||||
/* Return class of symbol SYM. The returned class can be any of:
|
||||
0 -> symbol is not interesting to us
|
||||
'T' -> symbol is a global name
|
||||
't' -> symbol is a local (static) name. */
|
||||
0 -> symbol is not interesting to us
|
||||
'T' -> symbol is a global name
|
||||
't' -> symbol is a local (static) name. */
|
||||
|
||||
static int
|
||||
DEFUN (core_sym_class, (sym), asymbol * sym)
|
||||
@ -328,7 +328,7 @@ DEFUN (core_sym_class, (sym), asymbol * sym)
|
||||
if (*name == '.' || *name == '$')
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* On systems where the C compiler adds an underscore to all
|
||||
names, static names without underscores seem usually to be
|
||||
labels in hand written assembler in the library. We don't want
|
||||
@ -337,10 +337,10 @@ DEFUN (core_sym_class, (sym), asymbol * sym)
|
||||
division). I don't know whether it has harmful side effects on
|
||||
other systems. Perhaps it should be made configurable. */
|
||||
sym_prefix = bfd_get_symbol_leading_char (core_bfd);
|
||||
|
||||
|
||||
if ((sym_prefix && sym_prefix != sym->name[0])
|
||||
/* GCC may add special symbols to help gdb figure out the file
|
||||
language. We want to ignore these, since sometimes they mask
|
||||
language. We want to ignore these, since sometimes they mask
|
||||
the real function. (dj@ctron) */
|
||||
|| !strncmp (sym->name, "__gnu_compiled", 14)
|
||||
|| !strncmp (sym->name, "___gnu_compiled", 15))
|
||||
@ -401,14 +401,14 @@ core_create_function_syms (core_bfd)
|
||||
|
||||
/* Pass 1 - determine upper bound on number of function names. */
|
||||
symtab.len = 0;
|
||||
|
||||
|
||||
for (i = 0; i < core_num_syms; ++i)
|
||||
{
|
||||
if (!core_sym_class (core_syms[i]))
|
||||
continue;
|
||||
|
||||
/* This should be replaced with a binary search or hashed
|
||||
search. Gross.
|
||||
search. Gross.
|
||||
|
||||
Don't create a symtab entry for a function that has
|
||||
a mapping to a file, unless it's the first function
|
||||
@ -418,13 +418,13 @@ core_create_function_syms (core_bfd)
|
||||
if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
|
||||
{
|
||||
if (j > 0 && ! strcmp (symbol_map [j].file_name,
|
||||
symbol_map [j - 1].file_name))
|
||||
symbol_map [j - 1].file_name))
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!skip)
|
||||
++symtab.len;
|
||||
++symtab.len;
|
||||
}
|
||||
|
||||
if (symtab.len == 0)
|
||||
@ -438,11 +438,11 @@ core_create_function_syms (core_bfd)
|
||||
|
||||
/* Pass 2 - create symbols. */
|
||||
symtab.limit = symtab.base;
|
||||
|
||||
|
||||
for (i = 0; i < core_num_syms; ++i)
|
||||
{
|
||||
class = core_sym_class (core_syms[i]);
|
||||
|
||||
|
||||
if (!class)
|
||||
{
|
||||
DBG (AOUTDEBUG,
|
||||
@ -451,17 +451,17 @@ core_create_function_syms (core_bfd)
|
||||
core_syms[i]->name));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* This should be replaced with a binary search or hashed
|
||||
search. Gross. */
|
||||
skip = 0;
|
||||
found = 0;
|
||||
|
||||
|
||||
for (j = 0; j < symbol_map_count; j++)
|
||||
if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
|
||||
{
|
||||
if (j > 0 && ! strcmp (symbol_map [j].file_name,
|
||||
symbol_map [j - 1].file_name))
|
||||
symbol_map [j - 1].file_name))
|
||||
skip = 1;
|
||||
else
|
||||
found = j;
|
||||
@ -475,7 +475,7 @@ core_create_function_syms (core_bfd)
|
||||
|
||||
/* Symbol offsets are always section-relative. */
|
||||
symtab.limit->addr = core_syms[i]->value + core_syms[i]->section->vma;
|
||||
|
||||
|
||||
if (symbol_map_count
|
||||
&& !strcmp (core_syms[i]->name, symbol_map[found].function_name))
|
||||
{
|
||||
@ -491,18 +491,18 @@ core_create_function_syms (core_bfd)
|
||||
/* Lookup filename and line number, if we can. */
|
||||
{
|
||||
const char *filename, *func_name;
|
||||
|
||||
|
||||
if (get_src_info (symtab.limit->addr, &filename, &func_name,
|
||||
&symtab.limit->line_num))
|
||||
{
|
||||
symtab.limit->file = source_file_lookup_path (filename);
|
||||
|
||||
/* FIXME: Checking __osf__ here does not work with a cross
|
||||
gprof. */
|
||||
gprof. */
|
||||
#ifdef __osf__
|
||||
/* Suppress symbols that are not function names. This is
|
||||
useful to suppress code-labels and aliases.
|
||||
|
||||
|
||||
This is known to be useful under DEC's OSF/1. Under SunOS 4.x,
|
||||
labels do not appear in the symbol table info, so this isn't
|
||||
necessary. */
|
||||
@ -523,7 +523,7 @@ core_create_function_syms (core_bfd)
|
||||
|
||||
symtab.limit->is_func = TRUE;
|
||||
symtab.limit->is_bb_head = TRUE;
|
||||
|
||||
|
||||
if (class == 't')
|
||||
symtab.limit->is_static = TRUE;
|
||||
|
||||
@ -531,7 +531,7 @@ core_create_function_syms (core_bfd)
|
||||
max_vma = MAX (symtab.limit->addr, max_vma);
|
||||
|
||||
/* If we see "main" without an initial '_', we assume names
|
||||
are *not* prefixed by '_'. */
|
||||
are *not* prefixed by '_'. */
|
||||
if (symtab.limit->name[0] == 'm' && discard_underscores
|
||||
&& strcmp (symtab.limit->name, "main") == 0)
|
||||
discard_underscores = 0;
|
||||
@ -574,7 +574,7 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
|
||||
const char *filename;
|
||||
int prev_line_num;
|
||||
Sym_Table ltab;
|
||||
|
||||
|
||||
/* Create symbols for functions as usual. This is necessary in
|
||||
cases where parts of a program were not compiled with -g. For
|
||||
those parts we still want to get info at the function level. */
|
||||
@ -586,7 +586,7 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
|
||||
text-space addresses (one by one!) and get the debugging
|
||||
info for each address. When the debugging info changes,
|
||||
it is time to create a new symbol.
|
||||
|
||||
|
||||
Of course, this is rather slow and it would be better if
|
||||
bfd would provide an iterator for enumerating all line infos. */
|
||||
prev_name_len = PATH_MAX;
|
||||
@ -595,13 +595,13 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
|
||||
prev_filename = xmalloc (prev_filename_len);
|
||||
ltab.len = 0;
|
||||
prev_line_num = 0;
|
||||
|
||||
|
||||
for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
|
||||
{
|
||||
int len;
|
||||
|
||||
vma = core_text_sect->vma + offset;
|
||||
|
||||
|
||||
if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
|
||||
|| (prev_line_num == dummy.line_num
|
||||
&& prev_name != NULL
|
||||
@ -619,17 +619,17 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
|
||||
free (prev_name);
|
||||
prev_name = xmalloc (prev_name_len);
|
||||
}
|
||||
|
||||
|
||||
strcpy (prev_name, dummy.name);
|
||||
len = strlen (filename);
|
||||
|
||||
|
||||
if (len >= prev_filename_len)
|
||||
{
|
||||
prev_filename_len = len + 1024;
|
||||
free (prev_filename);
|
||||
prev_filename = xmalloc (prev_filename_len);
|
||||
}
|
||||
|
||||
|
||||
strcpy (prev_filename, filename);
|
||||
|
||||
min_vma = MIN (vma, min_vma);
|
||||
@ -663,11 +663,11 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
|
||||
distinction as well, but the current fix works and the code is a
|
||||
lot cleaner now. */
|
||||
prev = 0;
|
||||
|
||||
|
||||
for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
|
||||
{
|
||||
sym_init (ltab.limit);
|
||||
|
||||
|
||||
if (!get_src_info (core_text_sect->vma + offset, &filename,
|
||||
<ab.limit->name, <ab.limit->line_num)
|
||||
|| (prev && prev->line_num == ltab.limit->line_num
|
||||
@ -682,8 +682,8 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
|
||||
ltab.limit->addr = core_text_sect->vma + offset;
|
||||
|
||||
/* Set is_static based on the enclosing function, using either:
|
||||
1) the previous symbol, if it's from the same function, or
|
||||
2) a symtab lookup. */
|
||||
1) the previous symbol, if it's from the same function, or
|
||||
2) a symtab lookup. */
|
||||
if (prev && ltab.limit->file == prev->file &&
|
||||
strcmp (ltab.limit->name, prev->name) == 0)
|
||||
{
|
||||
@ -698,7 +698,7 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
|
||||
prev = ltab.limit;
|
||||
|
||||
/* If we see "main" without an initial '_', we assume names
|
||||
are *not* prefixed by '_'. */
|
||||
are *not* prefixed by '_'. */
|
||||
if (ltab.limit->name[0] == 'm' && discard_underscores
|
||||
&& strcmp (ltab.limit->name, "main") == 0)
|
||||
discard_underscores = 0;
|
||||
@ -712,13 +712,13 @@ DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
|
||||
|
||||
/* Update sentinels. */
|
||||
sentinel = sym_lookup (&symtab, 0);
|
||||
|
||||
|
||||
if (strcmp (sentinel->name, "<locore>") == 0
|
||||
&& min_vma <= sentinel->end_addr)
|
||||
sentinel->end_addr = min_vma - 1;
|
||||
|
||||
sentinel = sym_lookup (&symtab, ~0);
|
||||
|
||||
|
||||
if (strcmp (sentinel->name, "<hicore>") == 0 && max_vma >= sentinel->addr)
|
||||
sentinel->addr = max_vma + 1;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* corefile.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
|
@ -40,6 +40,9 @@
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define as the size of a pointer in the target profile file format. */
|
||||
#undef GMON_PTR_SIZE
|
||||
|
||||
/* Define if you have the __argz_count function. */
|
||||
#undef HAVE___ARGZ_COUNT
|
||||
|
||||
@ -100,6 +103,9 @@
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define if you have the <sys/gmon_out.h> header file. */
|
||||
#undef HAVE_SYS_GMON_OUT_H
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
|
36
gprof/gmon.h
36
gprof/gmon.h
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1991 The Regents of the University of California.
|
||||
* Copyright (c) 1991, 2001 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -39,13 +39,8 @@ struct raw_phdr
|
||||
{
|
||||
/* FIXME: Checking a host compiler define means that we can't use
|
||||
a cross gprof to the alpha. */
|
||||
#ifdef __alpha__
|
||||
char low_pc[8]; /* base pc address of sample buffer */
|
||||
char high_pc[8]; /* max pc address of sampled buffer */
|
||||
#else
|
||||
char low_pc[4]; /* base pc address of sample buffer */
|
||||
char high_pc[4]; /* max pc address of sampled buffer */
|
||||
#endif
|
||||
char low_pc[GMON_PTR_SIZE]; /* base pc address of sample buffer */
|
||||
char high_pc[GMON_PTR_SIZE];/* max pc address of sampled buffer */
|
||||
char ncnt[4]; /* size of sample buffer (plus this header) */
|
||||
|
||||
char version[4]; /* version number */
|
||||
@ -57,15 +52,8 @@ struct raw_phdr
|
||||
|
||||
struct old_raw_phdr
|
||||
{
|
||||
/* FIXME: Checking a host compiler define means that we can't use
|
||||
a cross gprof to the alpha. */
|
||||
#ifdef __alpha__
|
||||
char low_pc[8]; /* base pc address of sample buffer */
|
||||
char high_pc[8]; /* max pc address of sampled buffer */
|
||||
#else
|
||||
char low_pc[4]; /* base pc address of sample buffer */
|
||||
char high_pc[4]; /* max pc address of sampled buffer */
|
||||
#endif
|
||||
char low_pc[GMON_PTR_SIZE]; /* base pc address of sample buffer */
|
||||
char high_pc[GMON_PTR_SIZE];/* max pc address of sampled buffer */
|
||||
char ncnt[4]; /* size of sample buffer (plus this header) */
|
||||
|
||||
/* FIXME: Checking host compiler defines here means that we can't
|
||||
@ -103,7 +91,7 @@ struct old_raw_phdr
|
||||
* calls $0,(r0)
|
||||
* calls $0,(r0)
|
||||
*
|
||||
* which is separated by only three bytes, thus HASHFRACTION is
|
||||
* which is separated by only three bytes, thus HASHFRACTION is
|
||||
* calculated as:
|
||||
*
|
||||
* HASHFRACTION = 3 / (2 * 2 - 1) = 1
|
||||
@ -134,17 +122,9 @@ struct tostruct
|
||||
*/
|
||||
struct raw_arc
|
||||
{
|
||||
/* FIXME: Checking a host compiler define means that we can't use
|
||||
a cross gprof to the alpha. */
|
||||
#ifdef __alpha__
|
||||
char from_pc[8];
|
||||
char self_pc[8];
|
||||
char count[8];
|
||||
#else
|
||||
char from_pc[4];
|
||||
char self_pc[4];
|
||||
char from_pc[GMON_PTR_SIZE];
|
||||
char self_pc[GMON_PTR_SIZE];
|
||||
char count[4];
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
174
gprof/gmon_io.c
174
gprof/gmon_io.c
@ -1,6 +1,6 @@
|
||||
/* gmon_io.c - Input and output from/to gmon.out files.
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -35,9 +35,113 @@
|
||||
int gmon_input = 0;
|
||||
int gmon_file_version = 0; /* 0 == old (non-versioned) file format. */
|
||||
|
||||
/* This probably ought to be in libbfd. */
|
||||
int
|
||||
DEFUN (gmon_io_read_vma, (ifp, valp), FILE * ifp AND bfd_vma *valp)
|
||||
{
|
||||
char buf[8];
|
||||
bfd_vma val;
|
||||
|
||||
bfd_vma
|
||||
switch (GMON_PTR_SIZE)
|
||||
{
|
||||
case 4:
|
||||
if (fread (buf, 1, 4, ifp) != 4)
|
||||
return 1;
|
||||
val = bfd_get_32 (core_bfd, buf);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (fread (buf, 1, 8, ifp) != 8)
|
||||
return 1;
|
||||
val = bfd_get_64 (core_bfd, buf);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, _("%s: GMON_PTR_SIZE has unexpected value of %u\n"),
|
||||
whoami, GMON_PTR_SIZE);
|
||||
done (1);
|
||||
}
|
||||
*valp = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN (gmon_io_read_32, (ifp, valp), FILE * ifp AND unsigned int *valp)
|
||||
{
|
||||
char buf[4];
|
||||
|
||||
if (fread (buf, 1, 4, ifp) != 4)
|
||||
return 1;
|
||||
*valp = bfd_get_32 (core_bfd, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN (gmon_io_read, (ifp, valp), FILE * ifp AND char *buf AND size_t n)
|
||||
{
|
||||
if (fread (buf, 1, n, ifp) != n)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN (gmon_io_write_vma, (ofp, valp), FILE * ofp AND bfd_vma val)
|
||||
{
|
||||
char buf[8];
|
||||
|
||||
switch (GMON_PTR_SIZE)
|
||||
{
|
||||
case 4:
|
||||
bfd_put_32 (core_bfd, val, buf);
|
||||
if (fwrite (buf, 1, 4, ofp) != 4)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
bfd_put_64 (core_bfd, val, buf);
|
||||
if (fwrite (buf, 1, 8, ofp) != 8)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, _("%s: GMON_PTR_SIZE has unexpected value of %u\n"),
|
||||
whoami, GMON_PTR_SIZE);
|
||||
done (1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN (gmon_io_write_32, (ofp, valp), FILE * ofp AND unsigned int val)
|
||||
{
|
||||
char buf[4];
|
||||
|
||||
bfd_put_32 (core_bfd, val, buf);
|
||||
if (fwrite (buf, 1, 4, ofp) != 4)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN (gmon_io_write_8, (ofp, valp), FILE * ofp AND unsigned char val)
|
||||
{
|
||||
char buf[1];
|
||||
|
||||
bfd_put_8 (core_bfd, val, buf);
|
||||
if (fwrite (buf, 1, 1, ofp) != 1)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
DEFUN (gmon_io_write, (ofp, valp), FILE * ofp AND char *buf AND size_t n)
|
||||
{
|
||||
if (fwrite (buf, 1, n, ofp) != n)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get_vma and put_vma are for backwards compatibility only */
|
||||
static bfd_vma
|
||||
DEFUN (get_vma, (abfd, addr), bfd * abfd AND bfd_byte * addr)
|
||||
{
|
||||
switch (sizeof (char*))
|
||||
@ -53,10 +157,7 @@ DEFUN (get_vma, (abfd, addr), bfd * abfd AND bfd_byte * addr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This probably ought to be in libbfd. */
|
||||
|
||||
void
|
||||
static void
|
||||
DEFUN (put_vma, (abfd, val, addr), bfd * abfd AND bfd_vma val AND bfd_byte * addr)
|
||||
{
|
||||
switch (sizeof (char*))
|
||||
@ -74,7 +175,6 @@ DEFUN (put_vma, (abfd, val, addr), bfd * abfd AND bfd_vma val AND bfd_byte * add
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
{
|
||||
@ -94,14 +194,14 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
else
|
||||
{
|
||||
ifp = fopen (filename, FOPEN_RB);
|
||||
|
||||
|
||||
if (!ifp)
|
||||
{
|
||||
perror (filename);
|
||||
done (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (fread (&ghdr, sizeof (struct gmon_hdr), 1, ifp) != 1)
|
||||
{
|
||||
fprintf (stderr, _("%s: file too short to be a gmon file\n"),
|
||||
@ -109,8 +209,8 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
done (1);
|
||||
}
|
||||
|
||||
if ((file_format == FF_MAGIC) ||
|
||||
(file_format == FF_AUTO && !strncmp (&ghdr.cookie[0], GMON_MAGIC, 4)))
|
||||
if ((file_format == FF_MAGIC)
|
||||
|| (file_format == FF_AUTO && !strncmp (&ghdr.cookie[0], GMON_MAGIC, 4)))
|
||||
{
|
||||
if (file_format == FF_MAGIC && strncmp (&ghdr.cookie[0], GMON_MAGIC, 4))
|
||||
{
|
||||
@ -121,7 +221,7 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
|
||||
/* Right magic, so it's probably really a new gmon.out file. */
|
||||
gmon_file_version = bfd_get_32 (core_bfd, (bfd_byte *) ghdr.version);
|
||||
|
||||
|
||||
if (gmon_file_version != GMON_VERSION && gmon_file_version != 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
@ -181,18 +281,18 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
struct hdr tmp;
|
||||
|
||||
/* Information from a gmon.out file is in two parts: an array of
|
||||
sampling hits within pc ranges, and the arcs. */
|
||||
sampling hits within pc ranges, and the arcs. */
|
||||
gmon_input = INPUT_HISTOGRAM | INPUT_CALL_GRAPH;
|
||||
|
||||
/* This fseek() ought to work even on stdin as long as it's
|
||||
not an interactive device (heck, is there anybody who would
|
||||
want to type in a gmon.out at the terminal?). */
|
||||
not an interactive device (heck, is there anybody who would
|
||||
want to type in a gmon.out at the terminal?). */
|
||||
if (fseek (ifp, 0, SEEK_SET) < 0)
|
||||
{
|
||||
perror (filename);
|
||||
done (1);
|
||||
}
|
||||
|
||||
|
||||
if (fread (&raw, 1, sizeof (struct raw_phdr), ifp)
|
||||
!= sizeof (struct raw_phdr))
|
||||
{
|
||||
@ -200,7 +300,7 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
filename);
|
||||
done (1);
|
||||
}
|
||||
|
||||
|
||||
tmp.low_pc = get_vma (core_bfd, (bfd_byte *) &raw.low_pc[0]);
|
||||
tmp.high_pc = get_vma (core_bfd, (bfd_byte *) &raw.high_pc[0]);
|
||||
tmp.ncnt = bfd_get_32 (core_bfd, (bfd_byte *) &raw.ncnt[0]);
|
||||
@ -212,7 +312,7 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
|
||||
/* 4.4BSD format header. */
|
||||
profrate = bfd_get_32 (core_bfd, (bfd_byte *) &raw.profrate[0]);
|
||||
|
||||
|
||||
if (!s_highpc)
|
||||
hz = profrate;
|
||||
else if (hz != profrate)
|
||||
@ -244,14 +344,14 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
header_size = sizeof (struct old_raw_phdr);
|
||||
}
|
||||
|
||||
if (s_highpc && (tmp.low_pc != h.low_pc ||
|
||||
tmp.high_pc != h.high_pc || tmp.ncnt != h.ncnt))
|
||||
if (s_highpc && (tmp.low_pc != h.low_pc
|
||||
|| tmp.high_pc != h.high_pc || tmp.ncnt != h.ncnt))
|
||||
{
|
||||
fprintf (stderr, _("%s: incompatible with first gmon file\n"),
|
||||
filename);
|
||||
done (1);
|
||||
}
|
||||
|
||||
|
||||
h = tmp;
|
||||
s_lowpc = (bfd_vma) h.low_pc;
|
||||
s_highpc = (bfd_vma) h.high_pc;
|
||||
@ -259,7 +359,7 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
highpc = (bfd_vma) h.high_pc / sizeof (UNIT);
|
||||
samp_bytes = h.ncnt - header_size;
|
||||
hist_num_bins = samp_bytes / sizeof (UNIT);
|
||||
|
||||
|
||||
DBG (SAMPLEDEBUG,
|
||||
printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n",
|
||||
(unsigned long) h.low_pc, (unsigned long) h.high_pc,
|
||||
@ -273,12 +373,12 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
|
||||
/* Make sure that we have sensible values. */
|
||||
if (samp_bytes < 0 || lowpc > highpc)
|
||||
{
|
||||
fprintf (stderr,
|
||||
{
|
||||
fprintf (stderr,
|
||||
_("%s: file '%s' does not appear to be in gmon.out format\n"),
|
||||
whoami, filename);
|
||||
done (1);
|
||||
}
|
||||
done (1);
|
||||
}
|
||||
|
||||
if (hist_num_bins)
|
||||
++nhist;
|
||||
@ -287,7 +387,7 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
{
|
||||
hist_sample =
|
||||
(int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
|
||||
|
||||
|
||||
memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
|
||||
}
|
||||
|
||||
@ -300,7 +400,7 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
whoami, --i, hist_num_bins);
|
||||
done (1);
|
||||
}
|
||||
|
||||
|
||||
hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
|
||||
}
|
||||
|
||||
@ -312,15 +412,15 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
from_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.from_pc);
|
||||
self_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.self_pc);
|
||||
count = bfd_get_32 (core_bfd, (bfd_byte *) raw_arc.count);
|
||||
|
||||
|
||||
DBG (SAMPLEDEBUG,
|
||||
printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n",
|
||||
(unsigned long) from_pc, (unsigned long) self_pc, count));
|
||||
|
||||
|
||||
/* Add this arc. */
|
||||
cg_tally (from_pc, self_pc, count);
|
||||
}
|
||||
|
||||
|
||||
fclose (ifp);
|
||||
|
||||
if (hz == HZ_WRONG)
|
||||
@ -328,7 +428,7 @@ DEFUN (gmon_out_read, (filename), const char *filename)
|
||||
/* How many ticks per second? If we can't tell, report
|
||||
time in ticks. */
|
||||
hz = hertz ();
|
||||
|
||||
|
||||
if (hz == HZ_WRONG)
|
||||
{
|
||||
hz = 1;
|
||||
@ -377,7 +477,7 @@ DEFUN (gmon_out_write, (filename), const char *filename)
|
||||
|
||||
memcpy (&ghdr.cookie[0], GMON_MAGIC, 4);
|
||||
bfd_put_32 (core_bfd, GMON_VERSION, (bfd_byte *) ghdr.version);
|
||||
|
||||
|
||||
if (fwrite (&ghdr, sizeof (ghdr), 1, ofp) != 1)
|
||||
{
|
||||
perror (filename);
|
||||
@ -413,8 +513,8 @@ DEFUN (gmon_out_write, (filename), const char *filename)
|
||||
(bfd_byte *) &h.ncnt);
|
||||
|
||||
/* Write header. Use new style BSD format is explicitly
|
||||
specified, or if the profiling rate is non-standard;
|
||||
otherwise, use the old BSD format. */
|
||||
specified, or if the profiling rate is non-standard;
|
||||
otherwise, use the old BSD format. */
|
||||
if (file_format == FF_BSD44
|
||||
|| hz != hertz ())
|
||||
{
|
||||
@ -467,7 +567,7 @@ DEFUN (gmon_out_write, (filename), const char *filename)
|
||||
(unsigned long) arc->child->addr, arc->count));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fclose (ofp);
|
||||
}
|
||||
else
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* gmon_io.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -49,8 +49,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
extern int gmon_input; /* What input did we see? */
|
||||
extern int gmon_file_version; /* File version are we dealing with. */
|
||||
|
||||
extern bfd_vma get_vma PARAMS ((bfd *, bfd_byte *));
|
||||
extern void put_vma PARAMS ((bfd *, bfd_vma, bfd_byte *));
|
||||
extern int gmon_io_read_vma PARAMS ((FILE *ifp, bfd_vma *valp));
|
||||
extern int gmon_io_read_32 PARAMS ((FILE *ifp, unsigned int *valp));
|
||||
extern int gmon_io_read PARAMS ((FILE *ifp, char *buf, size_t n));
|
||||
extern int gmon_io_write_vma PARAMS ((FILE *ifp, bfd_vma val));
|
||||
extern int gmon_io_write_32 PARAMS ((FILE *ifp, unsigned int val));
|
||||
extern int gmon_io_write_8 PARAMS ((FILE *ifp, unsigned char val));
|
||||
extern int gmon_io_write PARAMS ((FILE *ifp, char *buf, size_t n));
|
||||
|
||||
extern void gmon_out_read PARAMS ((const char *));
|
||||
extern void gmon_out_write PARAMS ((const char *));
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* gmon_out.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -18,17 +18,14 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This file specifies the format of gmon.out files. It should have
|
||||
as few external dependencies as possible as it is going to be
|
||||
included in many different programs. That is, minimize the
|
||||
number of #include's.
|
||||
|
||||
A gmon.out file consists of a header (defined by gmon_hdr) followed
|
||||
/* A gmon.out file consists of a header (defined by gmon_hdr) followed
|
||||
by a sequence of records. Each record starts with a one-byte tag
|
||||
identifying the type of records, followed by records specific data. */
|
||||
#ifndef gmon_out_h
|
||||
#define gmon_out_h
|
||||
|
||||
#include <gconfig.h>
|
||||
|
||||
#define GMON_MAGIC "gmon" /* magic cookie */
|
||||
#define GMON_VERSION 1 /* version number */
|
||||
|
||||
@ -47,21 +44,4 @@ typedef enum
|
||||
}
|
||||
GMON_Record_Tag;
|
||||
|
||||
struct gmon_hist_hdr
|
||||
{
|
||||
char low_pc[sizeof (char*)]; /* Base pc address of sample buffer. */
|
||||
char high_pc[sizeof (char*)]; /* Max pc address of sampled buffer. */
|
||||
char hist_size[4]; /* Size of sample buffer. */
|
||||
char prof_rate[4]; /* Profiling clock rate. */
|
||||
char dimen[15]; /* Phys. dim., usually "seconds". */
|
||||
char dimen_abbrev; /* Usually 's' for "seconds". */
|
||||
};
|
||||
|
||||
struct gmon_cg_arc_record
|
||||
{
|
||||
char from_pc[sizeof (char*)]; /* Address within caller's body. */
|
||||
char self_pc[sizeof (char*)]; /* Address within callee's body. */
|
||||
char count[4]; /* Number of arc traversals. */
|
||||
};
|
||||
|
||||
#endif /* gmon_out_h */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1998 Regents of the University of California.
|
||||
* Copyright (c) 1983, 1998, 2001 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
@ -429,18 +429,18 @@ This program is free software. This program has absolutely no warranty.\n"));
|
||||
if (optarg != NULL)
|
||||
{
|
||||
enum demangling_styles style;
|
||||
|
||||
|
||||
style = cplus_demangle_name_to_style (optarg);
|
||||
if (style == unknown_demangling)
|
||||
if (style == unknown_demangling)
|
||||
{
|
||||
fprintf (stderr,
|
||||
_("%s: unknown demangling style `%s'\n"),
|
||||
whoami, optarg);
|
||||
xexit (1);
|
||||
}
|
||||
|
||||
|
||||
cplus_demangle_set_style (style);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OPTION_NO_DEMANGLE:
|
||||
demangle = FALSE;
|
||||
|
204
gprof/hist.c
204
gprof/hist.c
@ -1,6 +1,6 @@
|
||||
/* hist.c - Histogram related operations.
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -43,11 +43,10 @@ bfd_vma lowpc, highpc; /* Same, but expressed in UNITs. */
|
||||
int hist_num_bins = 0; /* Number of histogram samples. */
|
||||
int *hist_sample = 0; /* Histogram samples (shorts in the file!). */
|
||||
double hist_scale;
|
||||
char hist_dimension[sizeof (((struct gmon_hist_hdr *) 0)->dimen) + 1] =
|
||||
"seconds";
|
||||
char hist_dimension[16] = "seconds";
|
||||
char hist_dimension_abbrev = 's';
|
||||
|
||||
static double accum_time; /* Accumulated time so far for print_line(). */
|
||||
static double accum_time; /* Accumulated time so far for print_line(). */
|
||||
static double total_time; /* Total time for all routines. */
|
||||
|
||||
/* Table of SI prefixes for powers of 10 (used to automatically
|
||||
@ -59,50 +58,17 @@ const struct
|
||||
}
|
||||
SItab[] =
|
||||
{
|
||||
{
|
||||
'T', 1e-12
|
||||
}
|
||||
, /* tera */
|
||||
{
|
||||
'G', 1e-09
|
||||
}
|
||||
, /* giga */
|
||||
{
|
||||
'M', 1e-06
|
||||
}
|
||||
, /* mega */
|
||||
{
|
||||
'K', 1e-03
|
||||
}
|
||||
, /* kilo */
|
||||
{
|
||||
' ', 1e-00
|
||||
}
|
||||
,
|
||||
{
|
||||
'm', 1e+03
|
||||
}
|
||||
, /* milli */
|
||||
{
|
||||
'u', 1e+06
|
||||
}
|
||||
, /* micro */
|
||||
{
|
||||
'n', 1e+09
|
||||
}
|
||||
, /* nano */
|
||||
{
|
||||
'p', 1e+12
|
||||
}
|
||||
, /* pico */
|
||||
{
|
||||
'f', 1e+15
|
||||
}
|
||||
, /* femto */
|
||||
{
|
||||
'a', 1e+18
|
||||
}
|
||||
, /* ato */
|
||||
{ 'T', 1e-12 }, /* tera */
|
||||
{ 'G', 1e-09 }, /* giga */
|
||||
{ 'M', 1e-06 }, /* mega */
|
||||
{ 'K', 1e-03 }, /* kilo */
|
||||
{ ' ', 1e-00 },
|
||||
{ 'm', 1e+03 }, /* milli */
|
||||
{ 'u', 1e+06 }, /* micro */
|
||||
{ 'n', 1e+09 }, /* nano */
|
||||
{ 'p', 1e+12 }, /* pico */
|
||||
{ 'f', 1e+15 }, /* femto */
|
||||
{ 'a', 1e+18 } /* ato */
|
||||
};
|
||||
|
||||
|
||||
@ -112,26 +78,23 @@ SItab[] =
|
||||
void
|
||||
DEFUN (hist_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
|
||||
{
|
||||
struct gmon_hist_hdr hdr;
|
||||
bfd_vma n_lowpc, n_highpc;
|
||||
int i, ncnt, profrate;
|
||||
UNIT count;
|
||||
|
||||
if (fread (&hdr, sizeof (hdr), 1, ifp) != 1)
|
||||
if (gmon_io_read_vma (ifp, &n_lowpc)
|
||||
|| gmon_io_read_vma (ifp, &n_highpc)
|
||||
|| gmon_io_read_32 (ifp, &ncnt)
|
||||
|| gmon_io_read_32 (ifp, &profrate)
|
||||
|| gmon_io_read (ifp, hist_dimension, 15)
|
||||
|| gmon_io_read (ifp, &hist_dimension_abbrev, 1))
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: unexpected end of file\n"),
|
||||
whoami, filename);
|
||||
|
||||
done (1);
|
||||
}
|
||||
|
||||
n_lowpc = (bfd_vma) get_vma (core_bfd, (bfd_byte *) hdr.low_pc);
|
||||
n_highpc = (bfd_vma) get_vma (core_bfd, (bfd_byte *) hdr.high_pc);
|
||||
ncnt = bfd_get_32 (core_bfd, (bfd_byte *) hdr.hist_size);
|
||||
profrate = bfd_get_32 (core_bfd, (bfd_byte *) hdr.prof_rate);
|
||||
strncpy (hist_dimension, hdr.dimen, sizeof (hdr.dimen));
|
||||
hist_dimension[sizeof (hdr.dimen)] = '\0';
|
||||
hist_dimension_abbrev = hdr.dimen_abbrev;
|
||||
|
||||
if (!s_highpc)
|
||||
{
|
||||
/* This is the first histogram record. */
|
||||
@ -171,11 +134,15 @@ DEFUN (hist_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
|
||||
if (fread (&count[0], sizeof (count), 1, ifp) != 1)
|
||||
{
|
||||
fprintf (stderr,
|
||||
_("%s: %s: unexpected EOF after reading %d of %d samples\n"),
|
||||
_("%s: %s: unexpected EOF after reading %d of %d samples\n"),
|
||||
whoami, filename, i, hist_num_bins);
|
||||
done (1);
|
||||
}
|
||||
hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]);
|
||||
DBG (SAMPLEDEBUG,
|
||||
printf ("[hist_read_rec] 0x%lx: %u\n",
|
||||
(unsigned long) (n_lowpc + i * (n_highpc - n_lowpc) / ncnt),
|
||||
hist_sample[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,23 +153,18 @@ DEFUN (hist_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
|
||||
void
|
||||
DEFUN (hist_write_hist, (ofp, filename), FILE * ofp AND const char *filename)
|
||||
{
|
||||
struct gmon_hist_hdr hdr;
|
||||
unsigned char tag;
|
||||
UNIT count;
|
||||
int i;
|
||||
|
||||
/* Write header. */
|
||||
|
||||
tag = GMON_TAG_TIME_HIST;
|
||||
put_vma (core_bfd, s_lowpc, (bfd_byte *) hdr.low_pc);
|
||||
put_vma (core_bfd, s_highpc, (bfd_byte *) hdr.high_pc);
|
||||
bfd_put_32 (core_bfd, hist_num_bins, (bfd_byte *) hdr.hist_size);
|
||||
bfd_put_32 (core_bfd, hz, (bfd_byte *) hdr.prof_rate);
|
||||
strncpy (hdr.dimen, hist_dimension, sizeof (hdr.dimen));
|
||||
hdr.dimen_abbrev = hist_dimension_abbrev;
|
||||
|
||||
if (fwrite (&tag, sizeof (tag), 1, ofp) != 1
|
||||
|| fwrite (&hdr, sizeof (hdr), 1, ofp) != 1)
|
||||
if (gmon_io_write_8 (ofp, GMON_TAG_TIME_HIST)
|
||||
|| gmon_io_write_vma (ofp, s_lowpc)
|
||||
|| gmon_io_write_vma (ofp, s_highpc)
|
||||
|| gmon_io_write_32 (ofp, hist_num_bins)
|
||||
|| gmon_io_write_32 (ofp, hz)
|
||||
|| gmon_io_write (ofp, hist_dimension, 15)
|
||||
|| gmon_io_write (ofp, &hist_dimension_abbrev, 1))
|
||||
{
|
||||
perror (filename);
|
||||
done (1);
|
||||
@ -211,7 +173,7 @@ DEFUN (hist_write_hist, (ofp, filename), FILE * ofp AND const char *filename)
|
||||
for (i = 0; i < hist_num_bins; ++i)
|
||||
{
|
||||
bfd_put_16 (core_bfd, hist_sample[i], (bfd_byte *) & count[0]);
|
||||
|
||||
|
||||
if (fwrite (&count[0], sizeof (count), 1, ofp) != 1)
|
||||
{
|
||||
perror (filename);
|
||||
@ -239,7 +201,8 @@ scale_and_align_entries ()
|
||||
{
|
||||
sym->hist.scaled_addr = sym->addr / sizeof (UNIT);
|
||||
bin_of_entry = (sym->hist.scaled_addr - lowpc) / hist_scale;
|
||||
bin_of_code = (sym->hist.scaled_addr + UNITS_TO_CODE - lowpc) / hist_scale;
|
||||
bin_of_code = ((sym->hist.scaled_addr + UNITS_TO_CODE - lowpc)
|
||||
/ hist_scale);
|
||||
if (bin_of_entry < bin_of_code)
|
||||
{
|
||||
DBG (SAMPLEDEBUG,
|
||||
@ -254,33 +217,33 @@ scale_and_align_entries ()
|
||||
|
||||
|
||||
/* Assign samples to the symbol to which they belong.
|
||||
|
||||
|
||||
Histogram bin I covers some address range [BIN_LOWPC,BIN_HIGH_PC)
|
||||
which may overlap one more symbol address ranges. If a symbol
|
||||
overlaps with the bin's address range by O percent, then O percent
|
||||
of the bin's count is credited to that symbol.
|
||||
|
||||
|
||||
There are three cases as to where BIN_LOW_PC and BIN_HIGH_PC can be
|
||||
with respect to the symbol's address range [SYM_LOW_PC,
|
||||
SYM_HIGH_PC) as shown in the following diagram. OVERLAP computes
|
||||
the distance (in UNITs) between the arrows, the fraction of the
|
||||
sample that is to be credited to the symbol which starts at
|
||||
SYM_LOW_PC.
|
||||
|
||||
sym_low_pc sym_high_pc
|
||||
| |
|
||||
v v
|
||||
|
||||
+-----------------------------------------------+
|
||||
| |
|
||||
| ->| |<- ->| |<- ->| |<- |
|
||||
| | | | | |
|
||||
+---------+ +---------+ +---------+
|
||||
|
||||
^ ^ ^ ^ ^ ^
|
||||
| | | | | |
|
||||
|
||||
sym_low_pc sym_high_pc
|
||||
| |
|
||||
v v
|
||||
|
||||
+-----------------------------------------------+
|
||||
| |
|
||||
| ->| |<- ->| |<- ->| |<- |
|
||||
| | | | | |
|
||||
+---------+ +---------+ +---------+
|
||||
|
||||
^ ^ ^ ^ ^ ^
|
||||
| | | | | |
|
||||
bin_low_pc bin_high_pc bin_low_pc bin_high_pc bin_low_pc bin_high_pc
|
||||
|
||||
|
||||
For the VAX we assert that samples will never fall in the first two
|
||||
bytes of any routine, since that is the entry mask, thus we call
|
||||
scale_and_align_entries() to adjust the entry points if the entry
|
||||
@ -315,7 +278,7 @@ DEFUN_VOID (hist_assign_samples)
|
||||
bin_low_pc = lowpc + (bfd_vma) (hist_scale * i);
|
||||
bin_high_pc = lowpc + (bfd_vma) (hist_scale * (i + 1));
|
||||
time = bin_count;
|
||||
|
||||
|
||||
DBG (SAMPLEDEBUG,
|
||||
printf (
|
||||
"[assign_samples] bin_low_pc=0x%lx, bin_high_pc=0x%lx, bin_count=%d\n",
|
||||
@ -329,7 +292,7 @@ DEFUN_VOID (hist_assign_samples)
|
||||
{
|
||||
sym_low_pc = symtab.base[j].hist.scaled_addr;
|
||||
sym_high_pc = symtab.base[j + 1].hist.scaled_addr;
|
||||
|
||||
|
||||
/* If high end of bin is below entry address,
|
||||
go for next bin. */
|
||||
if (bin_high_pc < sym_low_pc)
|
||||
@ -346,18 +309,18 @@ DEFUN_VOID (hist_assign_samples)
|
||||
{
|
||||
DBG (SAMPLEDEBUG,
|
||||
printf (
|
||||
"[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n",
|
||||
(unsigned long) symtab.base[j].addr,
|
||||
(unsigned long) (sizeof (UNIT) * sym_high_pc),
|
||||
symtab.base[j].name, overlap * time / hist_scale,
|
||||
(long) overlap));
|
||||
|
||||
"[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n",
|
||||
(unsigned long) symtab.base[j].addr,
|
||||
(unsigned long) (sizeof (UNIT) * sym_high_pc),
|
||||
symtab.base[j].name, overlap * time / hist_scale,
|
||||
(long) overlap));
|
||||
|
||||
addr = symtab.base[j].addr;
|
||||
credit = overlap * time / hist_scale;
|
||||
|
||||
|
||||
/* Credit symbol if it appears in INCL_FLAT or that
|
||||
table is empty and it does not appear it in
|
||||
EXCL_FLAT. */
|
||||
table is empty and it does not appear it in
|
||||
EXCL_FLAT. */
|
||||
if (sym_lookup (&syms[INCL_FLAT], addr)
|
||||
|| (syms[INCL_FLAT].len == 0
|
||||
&& !sym_lookup (&syms[EXCL_FLAT], addr)))
|
||||
@ -371,7 +334,7 @@ DEFUN_VOID (hist_assign_samples)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DBG (SAMPLEDEBUG, printf ("[assign_samples] total_time %f\n",
|
||||
total_time));
|
||||
}
|
||||
@ -404,13 +367,14 @@ DEFUN (print_header, (prefix), const char prefix)
|
||||
if (total_time <= 0.0)
|
||||
{
|
||||
printf (_(" no time accumulated\n\n"));
|
||||
|
||||
|
||||
/* This doesn't hurt since all the numerators will be zero. */
|
||||
total_time = 1.0;
|
||||
}
|
||||
|
||||
printf ("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
|
||||
"% ", _("cumulative"), _("self "), "", _("self "), _("total "), "");
|
||||
"% ", _("cumulative"), _("self "), "", _("self "), _("total "),
|
||||
"");
|
||||
printf ("%5.5s %9.9s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
|
||||
_("time"), hist_dimension, hist_dimension, _("calls"), unit, unit,
|
||||
_("name"));
|
||||
@ -424,7 +388,7 @@ DEFUN (print_line, (sym, scale), Sym * sym AND double scale)
|
||||
return;
|
||||
|
||||
accum_time += sym->hist.time;
|
||||
|
||||
|
||||
if (bsd_style_output)
|
||||
printf ("%5.1f %10.2f %8.2f",
|
||||
total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
|
||||
@ -433,14 +397,14 @@ DEFUN (print_line, (sym, scale), Sym * sym AND double scale)
|
||||
printf ("%6.2f %9.2f %8.2f",
|
||||
total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
|
||||
accum_time / hz, sym->hist.time / hz);
|
||||
|
||||
|
||||
if (sym->ncalls != 0)
|
||||
printf (" %8lu %8.2f %8.2f ",
|
||||
sym->ncalls, scale * sym->hist.time / hz / sym->ncalls,
|
||||
scale * (sym->hist.time + sym->cg.child_time) / hz / sym->ncalls);
|
||||
else
|
||||
printf (" %8.8s %8.8s %8.8s ", "", "", "");
|
||||
|
||||
|
||||
if (bsd_style_output)
|
||||
print_name (sym);
|
||||
else
|
||||
@ -462,10 +426,10 @@ DEFUN (cmp_time, (lp, rp), const PTR lp AND const PTR rp)
|
||||
double time_diff;
|
||||
|
||||
time_diff = right->hist.time - left->hist.time;
|
||||
|
||||
|
||||
if (time_diff > 0.0)
|
||||
return 1;
|
||||
|
||||
|
||||
if (time_diff < 0.0)
|
||||
return -1;
|
||||
|
||||
@ -496,7 +460,7 @@ DEFUN_VOID (hist_print)
|
||||
printf ("\f\n");
|
||||
|
||||
accum_time = 0.0;
|
||||
|
||||
|
||||
if (bsd_style_output)
|
||||
{
|
||||
if (print_descriptions)
|
||||
@ -509,11 +473,11 @@ DEFUN_VOID (hist_print)
|
||||
{
|
||||
printf (_("Flat profile:\n"));
|
||||
}
|
||||
|
||||
|
||||
/* Sort the symbol table by time (call-count and name as secondary
|
||||
and tertiary keys). */
|
||||
time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
|
||||
|
||||
|
||||
for (index = 0; index < symtab.len; ++index)
|
||||
time_sorted_syms[index] = &symtab.base[index];
|
||||
|
||||
@ -530,15 +494,15 @@ DEFUN_VOID (hist_print)
|
||||
log_scale = 0;
|
||||
top_dog = 0;
|
||||
top_time = 0.0;
|
||||
|
||||
|
||||
for (index = 0; index < symtab.len; ++index)
|
||||
{
|
||||
sym = time_sorted_syms[index];
|
||||
|
||||
|
||||
if (sym->ncalls != 0)
|
||||
{
|
||||
time = (sym->hist.time + sym->cg.child_time) / sym->ncalls;
|
||||
|
||||
|
||||
if (time > top_time)
|
||||
{
|
||||
top_dog = sym;
|
||||
@ -546,11 +510,11 @@ DEFUN_VOID (hist_print)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (top_dog && top_dog->ncalls != 0 && top_time > 0.0)
|
||||
{
|
||||
top_time /= hz;
|
||||
|
||||
|
||||
while (SItab[log_scale].scale * top_time < 1000.0
|
||||
&& ((size_t) log_scale
|
||||
< sizeof (SItab) / sizeof (SItab[0]) - 1))
|
||||
@ -564,19 +528,19 @@ DEFUN_VOID (hist_print)
|
||||
may also want to support other (pseudo-)dimensions (such as
|
||||
I-cache misses etc.). */
|
||||
print_header (SItab[log_scale].prefix);
|
||||
|
||||
|
||||
for (index = 0; index < symtab.len; ++index)
|
||||
{
|
||||
addr = time_sorted_syms[index]->addr;
|
||||
|
||||
|
||||
/* Print symbol if its in INCL_FLAT table or that table
|
||||
is empty and the symbol is not in EXCL_FLAT. */
|
||||
is empty and the symbol is not in EXCL_FLAT. */
|
||||
if (sym_lookup (&syms[INCL_FLAT], addr)
|
||||
|| (syms[INCL_FLAT].len == 0
|
||||
&& !sym_lookup (&syms[EXCL_FLAT], addr)))
|
||||
print_line (time_sorted_syms[index], SItab[log_scale].scale);
|
||||
}
|
||||
|
||||
|
||||
free (time_sorted_syms);
|
||||
|
||||
if (print_descriptions && !bsd_style_output)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* hist.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* Copyright (c) 1983, 2001 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
@ -71,7 +71,7 @@ i386_find_call (parent, p_lowpc, p_highpc)
|
||||
(unsigned long) (instructp - (unsigned char *) delta)));
|
||||
/*
|
||||
* regular pc relative addressing
|
||||
* check that this is the address of
|
||||
* check that this is the address of
|
||||
* a function.
|
||||
*/
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* search-list.c
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -37,7 +37,7 @@ DEFUN (search_list_append, (list, paths),
|
||||
{
|
||||
beg = colon + 1;
|
||||
colon = strchr (beg, PATH_SEP_CHAR);
|
||||
|
||||
|
||||
if (colon)
|
||||
len = colon - beg;
|
||||
else
|
||||
@ -49,7 +49,7 @@ DEFUN (search_list_append, (list, paths),
|
||||
|
||||
/* Append new path at end of list. */
|
||||
new_el->next = 0;
|
||||
|
||||
|
||||
if (list->tail)
|
||||
list->tail->next = new_el;
|
||||
else
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* search-list.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* source.c - Keep track of source files.
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -44,19 +44,19 @@ DEFUN (source_file_lookup_path, (path), const char *path)
|
||||
if (FILENAME_CMP (path, sf->name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!sf)
|
||||
{
|
||||
/* Create a new source file descriptor. */
|
||||
sf = (Source_File *) xmalloc (sizeof (*sf));
|
||||
|
||||
|
||||
memset (sf, 0, sizeof (*sf));
|
||||
|
||||
|
||||
sf->name = xstrdup (path);
|
||||
sf->next = first_src_file;
|
||||
first_src_file = sf;
|
||||
}
|
||||
|
||||
|
||||
return sf;
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ DEFUN (source_file_lookup_name, (filename), const char *filename)
|
||||
{
|
||||
const char *fname;
|
||||
Source_File *sf;
|
||||
|
||||
|
||||
/* The user cannot know exactly how a filename will be stored in
|
||||
the debugging info (e.g., ../include/foo.h
|
||||
vs. /usr/include/foo.h). So we simply compare the filename
|
||||
@ -74,7 +74,7 @@ DEFUN (source_file_lookup_name, (filename), const char *filename)
|
||||
for (sf = first_src_file; sf; sf = sf->next)
|
||||
{
|
||||
fname = strrchr (sf->name, '/');
|
||||
|
||||
|
||||
if (fname)
|
||||
++fname;
|
||||
else
|
||||
@ -83,7 +83,7 @@ DEFUN (source_file_lookup_name, (filename), const char *filename)
|
||||
if (FILENAME_CMP (filename, fname) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return sf;
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ DEFUN (annotate_source, (sf, max_width, annote, arg),
|
||||
/* Open input file. If open fails, walk along search-list until
|
||||
open succeeds or reaching end of list. */
|
||||
strcpy (fname, sf->name);
|
||||
|
||||
|
||||
if (IS_ABSOLUTE_PATH (sf->name))
|
||||
sle = 0; /* Don't use search list for absolute paths. */
|
||||
|
||||
@ -115,7 +115,7 @@ DEFUN (annotate_source, (sf, max_width, annote, arg),
|
||||
{
|
||||
DBG (SRCDEBUG, printf ("[annotate_source]: looking for %s, trying %s\n",
|
||||
sf->name, fname));
|
||||
|
||||
|
||||
ifp = fopen (fname, FOPEN_RB);
|
||||
if (ifp)
|
||||
break;
|
||||
@ -139,7 +139,7 @@ DEFUN (annotate_source, (sf, max_width, annote, arg),
|
||||
sle = src_search_list.head;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (sle)
|
||||
{
|
||||
strcpy (fname, sle->path);
|
||||
@ -149,7 +149,7 @@ DEFUN (annotate_source, (sf, max_width, annote, arg),
|
||||
strcat (fname, ".");
|
||||
#endif
|
||||
strcat (fname, "/");
|
||||
|
||||
|
||||
if (name_only)
|
||||
strcat (fname, name_only);
|
||||
else
|
||||
@ -170,7 +170,7 @@ DEFUN (annotate_source, (sf, max_width, annote, arg),
|
||||
}
|
||||
|
||||
ofp = stdout;
|
||||
|
||||
|
||||
if (create_annotation_files)
|
||||
{
|
||||
/* Try to create annotated source file. */
|
||||
@ -213,7 +213,7 @@ DEFUN (annotate_source, (sf, max_width, annote, arg),
|
||||
}
|
||||
#endif
|
||||
ofp = fopen (fname, "w");
|
||||
|
||||
|
||||
if (!ofp)
|
||||
{
|
||||
perror (fname);
|
||||
@ -241,7 +241,7 @@ DEFUN (annotate_source, (sf, max_width, annote, arg),
|
||||
annotation = xmalloc (max_width + 1);
|
||||
line_num = 1;
|
||||
new_line = TRUE;
|
||||
|
||||
|
||||
while ((nread = fread (buf, 1, sizeof (buf), ifp)) > 0)
|
||||
{
|
||||
for (i = 0; i < nread; ++i)
|
||||
@ -253,12 +253,12 @@ DEFUN (annotate_source, (sf, max_width, annote, arg),
|
||||
++line_num;
|
||||
new_line = FALSE;
|
||||
}
|
||||
|
||||
|
||||
new_line = (buf[i] == '\n');
|
||||
fputc (buf[i], ofp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free (annotation);
|
||||
return ofp;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* source.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -53,7 +53,7 @@ extern Source_File *source_file_lookup_name PARAMS ((const char *));
|
||||
MAX_WIDTH characters wide and for each source-line an annotation is
|
||||
obtained by invoking function ANNOTE. ARG is an argument passed to
|
||||
ANNOTE that is left uninterpreted by annotate_source().
|
||||
|
||||
|
||||
Returns a pointer to the output file (which maybe stdout) such
|
||||
that summary statistics can be printed. If the returned file
|
||||
is not stdout, it should be closed when done with it. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* sym_ids.c
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -31,7 +31,7 @@ struct sym_id
|
||||
char *spec; /* Parsing modifies this. */
|
||||
Table_Id which_table;
|
||||
bool has_right;
|
||||
|
||||
|
||||
struct match
|
||||
{
|
||||
int prev_index; /* Index of prev match. */
|
||||
@ -91,11 +91,11 @@ DEFUN (sym_id_add, (spec, which_table),
|
||||
|
||||
/* A spec has the syntax FILENAME:(FUNCNAME|LINENUM). As a convenience
|
||||
to the user, a spec without a colon is interpreted as:
|
||||
|
||||
(i) a FILENAME if it contains a dot
|
||||
(ii) a FUNCNAME if it starts with a non-digit character
|
||||
(iii) a LINENUM if it starts with a digit
|
||||
|
||||
|
||||
(i) a FILENAME if it contains a dot
|
||||
(ii) a FUNCNAME if it starts with a non-digit character
|
||||
(iii) a LINENUM if it starts with a digit
|
||||
|
||||
A FUNCNAME containing a dot can be specified by :FUNCNAME, a
|
||||
FILENAME not containing a dot can be specified by FILENAME. */
|
||||
|
||||
@ -106,21 +106,21 @@ DEFUN (parse_spec, (spec, sym), char *spec AND Sym * sym)
|
||||
|
||||
sym_init (sym);
|
||||
colon = strrchr (spec, ':');
|
||||
|
||||
|
||||
if (colon)
|
||||
{
|
||||
*colon = '\0';
|
||||
|
||||
|
||||
if (colon > spec)
|
||||
{
|
||||
sym->file = source_file_lookup_name (spec);
|
||||
|
||||
|
||||
if (!sym->file)
|
||||
sym->file = &non_existent_file;
|
||||
}
|
||||
|
||||
|
||||
spec = colon + 1;
|
||||
|
||||
|
||||
if (strlen (spec))
|
||||
{
|
||||
if (isdigit ((unsigned char) spec[0]))
|
||||
@ -135,7 +135,7 @@ DEFUN (parse_spec, (spec, sym), char *spec AND Sym * sym)
|
||||
if (strchr (spec, '.'))
|
||||
{
|
||||
sym->file = source_file_lookup_name (spec);
|
||||
|
||||
|
||||
if (!sym->file)
|
||||
sym->file = &non_existent_file;
|
||||
}
|
||||
@ -174,19 +174,19 @@ DEFUN (parse_id, (id), struct sym_id *id)
|
||||
if (debug_level & IDDEBUG)
|
||||
{
|
||||
printf ("%s:", id->left.sym.file ? id->left.sym.file->name : "*");
|
||||
|
||||
|
||||
if (id->left.sym.name)
|
||||
printf ("%s", id->left.sym.name);
|
||||
else if (id->left.sym.line_num)
|
||||
printf ("%d", id->left.sym.line_num);
|
||||
else
|
||||
printf ("*");
|
||||
|
||||
|
||||
if (id->has_right)
|
||||
{
|
||||
printf ("/%s:",
|
||||
id->right.sym.file ? id->right.sym.file->name : "*");
|
||||
|
||||
|
||||
if (id->right.sym.name)
|
||||
printf ("%s", id->right.sym.name);
|
||||
else if (id->right.sym.line_num)
|
||||
@ -194,7 +194,7 @@ DEFUN (parse_id, (id), struct sym_id *id)
|
||||
else
|
||||
printf ("*");
|
||||
}
|
||||
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
#endif
|
||||
@ -231,7 +231,7 @@ DEFUN (extend_match, (m, sym, tab, second_pass),
|
||||
tab->base[tab->len].next = m->first_match;
|
||||
m->first_match = &tab->base[tab->len];
|
||||
}
|
||||
|
||||
|
||||
++tab->len;
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ DEFUN (extend_match, (m, sym, tab, second_pass),
|
||||
/* Go through sym_id list produced by option processing and fill
|
||||
in the various symbol tables indicating what symbols should
|
||||
be displayed or suppressed for the various kinds of outputs.
|
||||
|
||||
|
||||
This can potentially produce huge tables and in particulars
|
||||
tons of arcs, but this happens only if the user makes silly
|
||||
requests---you get what you ask for! */
|
||||
@ -285,7 +285,7 @@ DEFUN_VOID (sym_id_parse)
|
||||
tab->len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (right_ids.len)
|
||||
{
|
||||
right_ids.base = (Sym *) xmalloc (right_ids.len * sizeof (Sym));
|
||||
@ -327,7 +327,7 @@ DEFUN_VOID (sym_id_parse)
|
||||
(unsigned long) right->addr,
|
||||
(unsigned long) right->end_addr,
|
||||
table_name[id->which_table]));
|
||||
|
||||
|
||||
arc_add (left, right, (unsigned long) 0);
|
||||
}
|
||||
}
|
||||
@ -362,6 +362,6 @@ DEFUN (sym_id_arc_is_present, (symtab, from, to),
|
||||
&& arc_lookup (sym, to))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* sym_ids.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* symtab.c
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -33,7 +33,7 @@ void
|
||||
DEFUN (sym_init, (sym), Sym * sym)
|
||||
{
|
||||
memset (sym, 0, sizeof (*sym));
|
||||
|
||||
|
||||
/* It is not safe to assume that a binary zero corresponds
|
||||
to a floating-point 0.0, so initialize floats explicitly. */
|
||||
sym->hist.time = 0.0;
|
||||
@ -86,7 +86,7 @@ DEFUN (symtab_finalize, (tab), Sym_Table * tab)
|
||||
/* Remove duplicate entries to speed-up later processing and
|
||||
set end_addr if its not set yet. */
|
||||
prev_addr = tab->base[0].addr + 1;
|
||||
|
||||
|
||||
for (src = dst = tab->base; src < tab->limit; ++src)
|
||||
{
|
||||
if (src->addr == prev_addr)
|
||||
@ -114,7 +114,7 @@ DEFUN (symtab_finalize, (tab), Sym_Table * tab)
|
||||
dst[-1].name, dst[-1].is_static ? 't' : 'T',
|
||||
dst[-1].is_func ? 'F' : 'f');
|
||||
printf (" (addr=%lx)\n", (unsigned long) src->addr));
|
||||
|
||||
|
||||
dst[-1] = *src;
|
||||
}
|
||||
else
|
||||
@ -142,7 +142,7 @@ DEFUN (symtab_finalize, (tab), Sym_Table * tab)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tab->len > 0 && dst[-1].end_addr == 0)
|
||||
dst[-1].end_addr = core_text_sect->vma + core_text_sect->_raw_size - 1;
|
||||
|
||||
@ -157,11 +157,11 @@ DEFUN (symtab_finalize, (tab), Sym_Table * tab)
|
||||
unsigned int j;
|
||||
|
||||
for (j = 0; j < tab->len; ++j)
|
||||
{
|
||||
{
|
||||
printf ("[symtab_finalize] 0x%lx-0x%lx\t%s\n",
|
||||
(long) tab->base[j].addr, (long) tab->base[j].end_addr,
|
||||
tab->base[j].name);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -181,13 +181,13 @@ DEFUN (dbg_sym_lookup, (symtab, address), Sym_Table * symtab AND bfd_vma address
|
||||
for (low = 0, high = symtab->len - 1; low != high;)
|
||||
{
|
||||
mid = (high + low) >> 1;
|
||||
|
||||
|
||||
fprintf (stderr, "[dbg_sym_lookup] low=0x%lx, mid=0x%lx, high=0x%lx\n",
|
||||
low, mid, high);
|
||||
fprintf (stderr, "[dbg_sym_lookup] sym[m]=0x%lx sym[m + 1]=0x%lx\n",
|
||||
(unsigned long) sym[mid].addr,
|
||||
(unsigned long) sym[mid + 1].addr);
|
||||
|
||||
|
||||
if (sym[mid].addr <= address && sym[mid + 1].addr > address)
|
||||
return &sym[mid];
|
||||
|
||||
@ -196,9 +196,9 @@ DEFUN (dbg_sym_lookup, (symtab, address), Sym_Table * symtab AND bfd_vma address
|
||||
else
|
||||
low = mid + 1;
|
||||
}
|
||||
|
||||
|
||||
fprintf (stderr, "[dbg_sym_lookup] binary search fails???\n");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -225,7 +225,7 @@ DEFUN (sym_lookup, (symtab, address), Sym_Table * symtab AND bfd_vma address)
|
||||
{
|
||||
DBG (LOOKUPDEBUG, ++probes);
|
||||
mid = (high + low) / 2;
|
||||
|
||||
|
||||
if (sym[mid].addr <= address && sym[mid + 1].addr > address)
|
||||
{
|
||||
if (address > sym[mid].end_addr)
|
||||
@ -242,13 +242,13 @@ DEFUN (sym_lookup, (symtab, address), Sym_Table * symtab AND bfd_vma address)
|
||||
return &sym[mid];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (sym[mid].addr > address)
|
||||
high = mid;
|
||||
else
|
||||
low = mid + 1;
|
||||
}
|
||||
|
||||
|
||||
if (sym[mid + 1].addr <= address)
|
||||
{
|
||||
if (address > sym[mid + 1].end_addr)
|
||||
@ -263,6 +263,6 @@ DEFUN (sym_lookup, (symtab, address), Sym_Table * symtab AND bfd_vma address)
|
||||
return &sym[mid + 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* symtab.h
|
||||
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
to map code-addresses into source-code information. Source-code
|
||||
information can be any combination of: (i) function-name, (ii)
|
||||
source file-name, and (iii) source line number.
|
||||
|
||||
|
||||
The symbol table is used to map addresses into source-code
|
||||
information. */
|
||||
|
||||
@ -41,11 +41,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
typedef struct sym
|
||||
{
|
||||
/* Common information:
|
||||
|
||||
|
||||
In the symbol-table, fields ADDR and FUNC_NAME are guaranteed
|
||||
to contain valid information. FILE may be 0, if unknown and
|
||||
LINE_NUM maybe 0 if unknown. */
|
||||
|
||||
|
||||
bfd_vma addr; /* Address of entry point. */
|
||||
bfd_vma end_addr; /* End-address. */
|
||||
const char *name; /* Name of function this sym is from. */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* Copyright (c) 1983, 2001 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
@ -304,7 +304,7 @@ tahoe_find_call (parent, p_lowpc, p_highpc)
|
||||
case longrel:
|
||||
/*
|
||||
* regular pc relative addressing
|
||||
* check that this is the address of
|
||||
* check that this is the address of
|
||||
* a function.
|
||||
*/
|
||||
destpc = tahoe_reladdr (instructp + length)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1998 Regents of the University of California.
|
||||
* Copyright (c) 1983, 1998, 2001 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
@ -68,7 +68,8 @@ DEFUN (print_name_only, (self), Sym * self)
|
||||
filename = self->file->name;
|
||||
}
|
||||
}
|
||||
sprintf (buf, " (%s:%d)", filename, self->line_num);
|
||||
sprintf (buf, " (%s:%d @ %lx)", filename, self->line_num,
|
||||
(unsigned long) self->addr);
|
||||
printf ("%s", buf);
|
||||
size += strlen (buf);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* Copyright (c) 1983, 2001 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
@ -307,7 +307,7 @@ vax_find_call (parent, p_lowpc, p_highpc)
|
||||
case longrel:
|
||||
/*
|
||||
* regular pc relative addressing
|
||||
* check that this is the address of
|
||||
* check that this is the address of
|
||||
* a function.
|
||||
*/
|
||||
destpc = vax_reladdr ((struct modebyte *) (instructp + length))
|
||||
|
Loading…
Reference in New Issue
Block a user