summaryrefslogtreecommitdiff
path: root/gprof/gmon_io.c
diff options
context:
space:
mode:
authorVladimir Prus <vladimir@codesourcery.com>2007-04-10 07:57:31 +0000
committerVladimir Prus <vladimir@codesourcery.com>2007-04-10 07:57:31 +0000
commitb3296dc54c51d28ada4c97aca7f55a4abfe09d9a (patch)
tree574e097a5069021c4cb996d8012d8830e4ca1c0b /gprof/gmon_io.c
parent8e77c9de92cec383d9fa3b1f8cf10e4840174396 (diff)
downloadbinutils-gdb-b3296dc54c51d28ada4c97aca7f55a4abfe09d9a.tar.gz
* hist.h (struct histogram)
(histograms, num_histograms): New. * hist.c (find_histogram, find_histogram_for_pc) (read_histogram_header): New. (s_lowpc, s_highpc, lowpc, highpc, hist_num_bins) (hist_sample): Remove. (hist_read_rec): Use the above, and handle multiple histogram records with disjoint address ranges. (hist_write_hist): Support several histogram records. (scale_and_align_entries): Adjust for multiple histograms. (hist_assign_samples_1): New. (hist_assign_samples): Use the above. (hist_clip_symbol_address): New. * hist.h (hist_check_address) (hist_clip_symbol_address): Declare. * gmon_io.c (gmon_out_read, gmon_out_write): Adjust handling of legacy format for multiple histogram changes. * corefile.c (find_call): Check for core_text_space and clip symbol address range here. * vax.c (vax_find_call): Don't check for core_text_space, or clip the symbol's address range here. Use hist_check_address to check call's target address. * sparc.c: Likewise. * tahoe.c: Likewise. * i386.c: Likewise. * mips.c: Likewise. Also use core_text_sect->vma as the base address for code accesses, just like other machine-specific routines do. * gprof.texi: Adjust for the new logic.
Diffstat (limited to 'gprof/gmon_io.c')
-rw-r--r--gprof/gmon_io.c60
1 files changed, 28 insertions, 32 deletions
diff --git a/gprof/gmon_io.c b/gprof/gmon_io.c
index e56ab7a3695..1abf427bafc 100644
--- a/gprof/gmon_io.c
+++ b/gprof/gmon_io.c
@@ -388,10 +388,10 @@ gmon_out_read (const char *filename)
int samp_bytes, header_size = 0;
unsigned long count;
bfd_vma from_pc, self_pc;
- static struct hdr h;
UNIT raw_bin_count;
struct hdr tmp;
unsigned int version;
+ unsigned int hist_num_bins;
/* Information from a gmon.out file is in two parts: an array of
sampling hits within pc ranges, and the arcs. */
@@ -430,7 +430,7 @@ gmon_out_read (const char *filename)
if (gmon_io_read_32 (ifp, &profrate))
goto bad_gmon_file;
- if (!s_highpc)
+ if (!histograms)
hz = profrate;
else if (hz != (int) profrate)
{
@@ -480,35 +480,37 @@ gmon_out_read (const char *filename)
done (1);
}
- if (s_highpc && (tmp.low_pc != h.low_pc
- || tmp.high_pc != h.high_pc || tmp.ncnt != h.ncnt))
+ samp_bytes = tmp.ncnt - header_size;
+ hist_num_bins = samp_bytes / sizeof (UNIT);
+ if (histograms && (tmp.low_pc != histograms->lowpc
+ || tmp.high_pc != histograms->highpc
+ || (hist_num_bins != histograms->num_bins)))
{
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;
- lowpc = (bfd_vma) h.low_pc / sizeof (UNIT);
- highpc = (bfd_vma) h.high_pc / sizeof (UNIT);
- samp_bytes = h.ncnt - header_size;
- hist_num_bins = samp_bytes / sizeof (UNIT);
+ if (!histograms)
+ {
+ histograms = xmalloc (sizeof (struct histogram));
+ histograms->lowpc = tmp.low_pc;
+ histograms->highpc = tmp.high_pc;
+ histograms->num_bins = hist_num_bins;
+ histograms->sample = xmalloc (hist_num_bins * sizeof (int));
+ memset (histograms->sample, 0,
+ hist_num_bins * sizeof (int));
+ }
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,
- h.ncnt);
- printf ("[gmon_out_read] s_lowpc 0x%lx s_highpc 0x%lx\n",
- (unsigned long) s_lowpc, (unsigned long) s_highpc);
- printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx\n",
- (unsigned long) lowpc, (unsigned long) highpc);
+ (unsigned long) tmp.low_pc, (unsigned long) tmp.high_pc,
+ tmp.ncnt);
printf ("[gmon_out_read] samp_bytes %d hist_num_bins %d\n",
samp_bytes, hist_num_bins));
/* Make sure that we have sensible values. */
- if (samp_bytes < 0 || lowpc > highpc)
+ if (samp_bytes < 0 || histograms->lowpc > histograms->highpc)
{
fprintf (stderr,
_("%s: file '%s' does not appear to be in gmon.out format\n"),
@@ -519,14 +521,6 @@ gmon_out_read (const char *filename)
if (hist_num_bins)
++nhist;
- if (!hist_sample)
- {
- hist_sample =
- (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
-
- memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
- }
-
for (i = 0; i < hist_num_bins; ++i)
{
if (fread (raw_bin_count, sizeof (raw_bin_count), 1, ifp) != 1)
@@ -537,7 +531,8 @@ gmon_out_read (const char *filename)
done (1);
}
- hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
+ histograms->sample[i]
+ += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
}
/* The rest of the file consists of a bunch of
@@ -684,9 +679,10 @@ gmon_out_write (const char *filename)
/* Write the parts of the headers that are common to both the
old BSD and 4.4BSD formats. */
- if (gmon_io_write_vma (ofp, s_lowpc)
- || gmon_io_write_vma (ofp, s_highpc)
- || gmon_io_write_32 (ofp, hist_num_bins * sizeof (UNIT) + hdrsize))
+ if (gmon_io_write_vma (ofp, histograms->lowpc)
+ || gmon_io_write_vma (ofp, histograms->highpc)
+ || gmon_io_write_32 (ofp, histograms->num_bins
+ * sizeof (UNIT) + hdrsize))
{
perror (filename);
done (1);
@@ -714,9 +710,9 @@ gmon_out_write (const char *filename)
}
/* Dump the samples. */
- for (i = 0; i < hist_num_bins; ++i)
+ for (i = 0; i < histograms->num_bins; ++i)
{
- bfd_put_16 (core_bfd, (bfd_vma) hist_sample[i],
+ bfd_put_16 (core_bfd, (bfd_vma) histograms->sample[i],
(bfd_byte *) &raw_bin_count[0]);
if (fwrite (&raw_bin_count[0], sizeof (raw_bin_count), 1, ofp) != 1)
{