* po/bfd.pot: Updated by the Translation project.
[deliverable/binutils-gdb.git] / gprof / gmon_io.c
CommitLineData
ef368dac
NC
1/* gmon_io.c - Input and output from/to gmon.out files.
2
81e80dda 3 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
d6a39701 4 Free Software Foundation, Inc.
ef368dac
NC
5
6 This file is part of GNU Binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
651dbc76 10 the Free Software Foundation; either version 3 of the License, or
ef368dac
NC
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
44eb1801
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
ef368dac 22\f
6d9c411a 23#include "gprof.h"
81e80dda 24#include "binary-io.h"
6d9c411a
AM
25#include "search_list.h"
26#include "source.h"
27#include "symtab.h"
252b5132
RH
28#include "cg_arcs.h"
29#include "basic_blocks.h"
252b5132
RH
30#include "corefile.h"
31#include "call_graph.h"
32#include "gmon_io.h"
33#include "gmon_out.h"
ef368dac 34#include "gmon.h" /* Fetch header for old format. */
252b5132
RH
35#include "hertz.h"
36#include "hist.h"
37#include "libiberty.h"
38
9844bab2
CD
39enum gmon_ptr_size {
40 ptr_32bit,
41 ptr_64bit
42};
43
44enum gmon_ptr_signedness {
45 ptr_signed,
46 ptr_unsigned
47};
48
3e8f6abf
BE
49static enum gmon_ptr_size gmon_get_ptr_size (void);
50static enum gmon_ptr_signedness gmon_get_ptr_signedness (void);
9844bab2 51
e4c79bb2 52#ifdef BFD_HOST_U_64_BIT
3e8f6abf
BE
53static int gmon_io_read_64 (FILE *, BFD_HOST_U_64_BIT *);
54static int gmon_io_write_64 (FILE *, BFD_HOST_U_64_BIT);
e4c79bb2 55#endif
1355568a 56static int gmon_read_raw_arc
3e8f6abf 57 (FILE *, bfd_vma *, bfd_vma *, unsigned long *);
1355568a 58static int gmon_write_raw_arc
3e8f6abf 59 (FILE *, bfd_vma, bfd_vma, unsigned long);
1355568a 60
252b5132 61int gmon_input = 0;
ef368dac
NC
62int gmon_file_version = 0; /* 0 == old (non-versioned) file format. */
63
9844bab2
CD
64static enum gmon_ptr_size
65gmon_get_ptr_size ()
66{
67 int size;
68
69 /* Pick best size for pointers. Start with the ELF size, and if not
70 elf go with the architecture's address size. */
71 size = bfd_get_arch_size (core_bfd);
72 if (size == -1)
73 size = bfd_arch_bits_per_address (core_bfd);
74
75 switch (size)
76 {
77 case 32:
78 return ptr_32bit;
79
80 case 64:
81 return ptr_64bit;
82
83 default:
84 fprintf (stderr, _("%s: address size has unexpected value of %u\n"),
85 whoami, size);
86 done (1);
87 }
88}
89
90static enum gmon_ptr_signedness
91gmon_get_ptr_signedness ()
92{
93 int sext;
94
95 /* Figure out whether to sign extend. If BFD doesn't know, assume no. */
96 sext = bfd_get_sign_extend_vma (core_bfd);
97 if (sext == -1)
98 return ptr_unsigned;
99 return (sext ? ptr_signed : ptr_unsigned);
100}
101
0eee5820 102int
3e8f6abf 103gmon_io_read_32 (FILE *ifp, unsigned int *valp)
e7e2dd92
NC
104{
105 char buf[4];
106
107 if (fread (buf, 1, 4, ifp) != 4)
108 return 1;
109 *valp = bfd_get_32 (core_bfd, buf);
110 return 0;
111}
112
e4c79bb2 113#ifdef BFD_HOST_U_64_BIT
1355568a 114static int
3e8f6abf 115gmon_io_read_64 (FILE *ifp, BFD_HOST_U_64_BIT *valp)
0eee5820
AM
116{
117 char buf[8];
0eee5820 118
e7e2dd92
NC
119 if (fread (buf, 1, 8, ifp) != 8)
120 return 1;
121 *valp = bfd_get_64 (core_bfd, buf);
122 return 0;
123}
e4c79bb2 124#endif
e7e2dd92
NC
125
126int
3e8f6abf 127gmon_io_read_vma (FILE *ifp, bfd_vma *valp)
e7e2dd92
NC
128{
129 unsigned int val32;
e4c79bb2 130#ifdef BFD_HOST_U_64_BIT
e7e2dd92 131 BFD_HOST_U_64_BIT val64;
e4c79bb2 132#endif
e7e2dd92 133
9844bab2 134 switch (gmon_get_ptr_size ())
0eee5820 135 {
9844bab2 136 case ptr_32bit:
e7e2dd92 137 if (gmon_io_read_32 (ifp, &val32))
0eee5820 138 return 1;
9844bab2
CD
139 if (gmon_get_ptr_signedness () == ptr_signed)
140 *valp = (int) val32;
141 else
142 *valp = val32;
0eee5820
AM
143 break;
144
e4c79bb2 145#ifdef BFD_HOST_U_64_BIT
9844bab2 146 case ptr_64bit:
e7e2dd92 147 if (gmon_io_read_64 (ifp, &val64))
0eee5820 148 return 1;
9844bab2
CD
149#ifdef BFD_HOST_64_BIT
150 if (gmon_get_ptr_signedness () == ptr_signed)
151 *valp = (BFD_HOST_64_BIT) val64;
152 else
153#endif
154 *valp = val64;
0eee5820 155 break;
e4c79bb2 156#endif
0eee5820 157 }
0eee5820
AM
158 return 0;
159}
252b5132 160
0eee5820 161int
3e8f6abf 162gmon_io_read (FILE *ifp, char *buf, size_t n)
e7e2dd92
NC
163{
164 if (fread (buf, 1, n, ifp) != n)
165 return 1;
166 return 0;
167}
168
169int
3e8f6abf 170gmon_io_write_32 (FILE *ofp, unsigned int val)
0eee5820
AM
171{
172 char buf[4];
173
1355568a 174 bfd_put_32 (core_bfd, (bfd_vma) val, buf);
e7e2dd92 175 if (fwrite (buf, 1, 4, ofp) != 4)
0eee5820 176 return 1;
0eee5820
AM
177 return 0;
178}
179
e4c79bb2 180#ifdef BFD_HOST_U_64_BIT
1355568a 181static int
3e8f6abf 182gmon_io_write_64 (FILE *ofp, BFD_HOST_U_64_BIT val)
0eee5820 183{
e7e2dd92
NC
184 char buf[8];
185
1355568a 186 bfd_put_64 (core_bfd, (bfd_vma) val, buf);
e7e2dd92 187 if (fwrite (buf, 1, 8, ofp) != 8)
0eee5820
AM
188 return 1;
189 return 0;
190}
e4c79bb2 191#endif
0eee5820
AM
192
193int
3e8f6abf 194gmon_io_write_vma (FILE *ofp, bfd_vma val)
0eee5820 195{
0eee5820 196
9844bab2 197 switch (gmon_get_ptr_size ())
0eee5820 198 {
9844bab2 199 case ptr_32bit:
e7e2dd92 200 if (gmon_io_write_32 (ofp, (unsigned int) val))
0eee5820
AM
201 return 1;
202 break;
203
e4c79bb2 204#ifdef BFD_HOST_U_64_BIT
9844bab2 205 case ptr_64bit:
e7e2dd92 206 if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) val))
0eee5820
AM
207 return 1;
208 break;
e4c79bb2 209#endif
0eee5820
AM
210 }
211 return 0;
212}
213
0eee5820 214int
3e8f6abf 215gmon_io_write_8 (FILE *ofp, unsigned int val)
0eee5820
AM
216{
217 char buf[1];
218
219 bfd_put_8 (core_bfd, val, buf);
220 if (fwrite (buf, 1, 1, ofp) != 1)
221 return 1;
222 return 0;
223}
224
225int
3e8f6abf 226gmon_io_write (FILE *ofp, char *buf, size_t n)
0eee5820
AM
227{
228 if (fwrite (buf, 1, n, ofp) != n)
229 return 1;
230 return 0;
231}
232
1355568a 233static int
3e8f6abf 234gmon_read_raw_arc (FILE *ifp, bfd_vma *fpc, bfd_vma *spc, unsigned long *cnt)
252b5132 235{
e4c79bb2 236#ifdef BFD_HOST_U_64_BIT
e7e2dd92 237 BFD_HOST_U_64_BIT cnt64;
e4c79bb2 238#endif
e7e2dd92
NC
239 unsigned int cnt32;
240
241 if (gmon_io_read_vma (ifp, fpc)
242 || gmon_io_read_vma (ifp, spc))
243 return 1;
244
9844bab2 245 switch (gmon_get_ptr_size ())
252b5132 246 {
9844bab2 247 case ptr_32bit:
e7e2dd92
NC
248 if (gmon_io_read_32 (ifp, &cnt32))
249 return 1;
250 *cnt = cnt32;
251 break;
252
e4c79bb2 253#ifdef BFD_HOST_U_64_BIT
9844bab2 254 case ptr_64bit:
e7e2dd92
NC
255 if (gmon_io_read_64 (ifp, &cnt64))
256 return 1;
257 *cnt = cnt64;
258 break;
e4c79bb2 259#endif
5ef6bac7
AM
260
261 default:
262 return 1;
252b5132 263 }
e7e2dd92 264 return 0;
252b5132
RH
265}
266
1355568a 267static int
3e8f6abf 268gmon_write_raw_arc (FILE *ofp, bfd_vma fpc, bfd_vma spc, unsigned long cnt)
252b5132 269{
e7e2dd92
NC
270
271 if (gmon_io_write_vma (ofp, fpc)
272 || gmon_io_write_vma (ofp, spc))
273 return 1;
274
9844bab2 275 switch (gmon_get_ptr_size ())
252b5132 276 {
9844bab2 277 case ptr_32bit:
e7e2dd92
NC
278 if (gmon_io_write_32 (ofp, (unsigned int) cnt))
279 return 1;
252b5132 280 break;
e7e2dd92 281
e4c79bb2 282#ifdef BFD_HOST_U_64_BIT
9844bab2 283 case ptr_64bit:
e7e2dd92
NC
284 if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) cnt))
285 return 1;
252b5132 286 break;
e4c79bb2 287#endif
252b5132 288 }
e7e2dd92 289 return 0;
252b5132
RH
290}
291
252b5132 292void
3e8f6abf 293gmon_out_read (const char *filename)
252b5132
RH
294{
295 FILE *ifp;
296 struct gmon_hdr ghdr;
297 unsigned char tag;
298 int nhist = 0, narcs = 0, nbbs = 0;
299
ef368dac 300 /* Open gmon.out file. */
252b5132
RH
301 if (strcmp (filename, "-") == 0)
302 {
303 ifp = stdin;
5af11cab 304 SET_BINARY (fileno (stdin));
252b5132
RH
305 }
306 else
307 {
308 ifp = fopen (filename, FOPEN_RB);
0eee5820 309
252b5132
RH
310 if (!ifp)
311 {
312 perror (filename);
313 done (1);
314 }
315 }
0eee5820 316
252b5132
RH
317 if (fread (&ghdr, sizeof (struct gmon_hdr), 1, ifp) != 1)
318 {
319 fprintf (stderr, _("%s: file too short to be a gmon file\n"),
320 filename);
321 done (1);
322 }
323
0eee5820
AM
324 if ((file_format == FF_MAGIC)
325 || (file_format == FF_AUTO && !strncmp (&ghdr.cookie[0], GMON_MAGIC, 4)))
252b5132
RH
326 {
327 if (file_format == FF_MAGIC && strncmp (&ghdr.cookie[0], GMON_MAGIC, 4))
328 {
329 fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"),
330 whoami, filename);
331 done (1);
332 }
333
ef368dac 334 /* Right magic, so it's probably really a new gmon.out file. */
252b5132 335 gmon_file_version = bfd_get_32 (core_bfd, (bfd_byte *) ghdr.version);
0eee5820 336
252b5132
RH
337 if (gmon_file_version != GMON_VERSION && gmon_file_version != 0)
338 {
339 fprintf (stderr,
340 _("%s: file `%s' has unsupported version %d\n"),
341 whoami, filename, gmon_file_version);
342 done (1);
343 }
344
ef368dac 345 /* Read in all the records. */
252b5132
RH
346 while (fread (&tag, sizeof (tag), 1, ifp) == 1)
347 {
348 switch (tag)
349 {
350 case GMON_TAG_TIME_HIST:
351 ++nhist;
352 gmon_input |= INPUT_HISTOGRAM;
353 hist_read_rec (ifp, filename);
354 break;
355
356 case GMON_TAG_CG_ARC:
357 ++narcs;
358 gmon_input |= INPUT_CALL_GRAPH;
359 cg_read_rec (ifp, filename);
360 break;
361
362 case GMON_TAG_BB_COUNT:
363 ++nbbs;
364 gmon_input |= INPUT_BB_COUNTS;
365 bb_read_rec (ifp, filename);
366 break;
367
368 default:
369 fprintf (stderr,
370 _("%s: %s: found bad tag %d (file corrupted?)\n"),
371 whoami, filename, tag);
372 done (1);
373 }
374 }
375 }
376 else if (file_format == FF_AUTO
377 || file_format == FF_BSD
378 || file_format == FF_BSD44)
379 {
380 struct hdr
381 {
382 bfd_vma low_pc;
383 bfd_vma high_pc;
8c62e9e1 384 unsigned int ncnt;
252b5132 385 };
8c62e9e1
AM
386 unsigned int i;
387 int samp_bytes, header_size = 0;
252b5132
RH
388 unsigned long count;
389 bfd_vma from_pc, self_pc;
252b5132
RH
390 UNIT raw_bin_count;
391 struct hdr tmp;
8c62e9e1 392 unsigned int version;
b3296dc5 393 unsigned int hist_num_bins;
252b5132 394
ef368dac 395 /* Information from a gmon.out file is in two parts: an array of
0eee5820 396 sampling hits within pc ranges, and the arcs. */
252b5132
RH
397 gmon_input = INPUT_HISTOGRAM | INPUT_CALL_GRAPH;
398
ef368dac 399 /* This fseek() ought to work even on stdin as long as it's
0eee5820
AM
400 not an interactive device (heck, is there anybody who would
401 want to type in a gmon.out at the terminal?). */
252b5132
RH
402 if (fseek (ifp, 0, SEEK_SET) < 0)
403 {
404 perror (filename);
405 done (1);
406 }
0eee5820 407
e7e2dd92
NC
408 /* The beginning of the old BSD header and the 4.4BSD header
409 are the same: lowpc, highpc, ncnt */
410 if (gmon_io_read_vma (ifp, &tmp.low_pc)
411 || gmon_io_read_vma (ifp, &tmp.high_pc)
412 || gmon_io_read_32 (ifp, &tmp.ncnt))
252b5132 413 {
e7e2dd92
NC
414 bad_gmon_file:
415 fprintf (stderr, _("%s: file too short to be a gmon file\n"),
252b5132
RH
416 filename);
417 done (1);
418 }
0eee5820 419
e7e2dd92
NC
420 /* Check to see if this a 4.4BSD-style header. */
421 if (gmon_io_read_32 (ifp, &version))
422 goto bad_gmon_file;
252b5132 423
e7e2dd92 424 if (version == GMONVERSION)
252b5132 425 {
8c62e9e1 426 unsigned int profrate;
252b5132
RH
427
428 /* 4.4BSD format header. */
e7e2dd92
NC
429 if (gmon_io_read_32 (ifp, &profrate))
430 goto bad_gmon_file;
0eee5820 431
b3296dc5 432 if (!histograms)
252b5132 433 hz = profrate;
8c62e9e1 434 else if (hz != (int) profrate)
252b5132
RH
435 {
436 fprintf (stderr,
437 _("%s: profiling rate incompatible with first gmon file\n"),
438 filename);
439 done (1);
440 }
441
9844bab2 442 switch (gmon_get_ptr_size ())
e7e2dd92 443 {
9844bab2 444 case ptr_32bit:
e7e2dd92
NC
445 header_size = GMON_HDRSIZE_BSD44_32;
446 break;
447
9844bab2 448 case ptr_64bit:
e7e2dd92
NC
449 header_size = GMON_HDRSIZE_BSD44_64;
450 break;
e7e2dd92 451 }
252b5132
RH
452 }
453 else
454 {
ef368dac 455 /* Old style BSD format. */
252b5132
RH
456 if (file_format == FF_BSD44)
457 {
458 fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"),
459 whoami, filename);
460 done (1);
461 }
462
9844bab2 463 switch (gmon_get_ptr_size ())
252b5132 464 {
9844bab2 465 case ptr_32bit:
e7e2dd92
NC
466 header_size = GMON_HDRSIZE_OLDBSD_32;
467 break;
468
9844bab2 469 case ptr_64bit:
e7e2dd92
NC
470 header_size = GMON_HDRSIZE_OLDBSD_64;
471 break;
252b5132 472 }
e7e2dd92 473 }
252b5132 474
e7e2dd92
NC
475 /* Position the file to after the header. */
476 if (fseek (ifp, header_size, SEEK_SET) < 0)
477 {
478 perror (filename);
479 done (1);
252b5132
RH
480 }
481
b3296dc5
VP
482 samp_bytes = tmp.ncnt - header_size;
483 hist_num_bins = samp_bytes / sizeof (UNIT);
484 if (histograms && (tmp.low_pc != histograms->lowpc
485 || tmp.high_pc != histograms->highpc
486 || (hist_num_bins != histograms->num_bins)))
252b5132
RH
487 {
488 fprintf (stderr, _("%s: incompatible with first gmon file\n"),
489 filename);
490 done (1);
491 }
0eee5820 492
b3296dc5
VP
493 if (!histograms)
494 {
4094fdc2 495 num_histograms = 1;
1e9cc1c2 496 histograms = (struct histogram *) xmalloc (sizeof (struct histogram));
b3296dc5
VP
497 histograms->lowpc = tmp.low_pc;
498 histograms->highpc = tmp.high_pc;
499 histograms->num_bins = hist_num_bins;
4094fdc2
BD
500 hist_scale = (double)((tmp.high_pc - tmp.low_pc) / sizeof (UNIT))
501 / hist_num_bins;
1e9cc1c2 502 histograms->sample = (int *) xmalloc (hist_num_bins * sizeof (int));
b3296dc5
VP
503 memset (histograms->sample, 0,
504 hist_num_bins * sizeof (int));
505 }
0eee5820 506
252b5132
RH
507 DBG (SAMPLEDEBUG,
508 printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n",
b3296dc5
VP
509 (unsigned long) tmp.low_pc, (unsigned long) tmp.high_pc,
510 tmp.ncnt);
252b5132
RH
511 printf ("[gmon_out_read] samp_bytes %d hist_num_bins %d\n",
512 samp_bytes, hist_num_bins));
513
2d35e9f6 514 /* Make sure that we have sensible values. */
b3296dc5 515 if (samp_bytes < 0 || histograms->lowpc > histograms->highpc)
0eee5820
AM
516 {
517 fprintf (stderr,
2d35e9f6
NC
518 _("%s: file '%s' does not appear to be in gmon.out format\n"),
519 whoami, filename);
0eee5820
AM
520 done (1);
521 }
2d35e9f6 522
252b5132 523 if (hist_num_bins)
ef368dac 524 ++nhist;
252b5132 525
252b5132
RH
526 for (i = 0; i < hist_num_bins; ++i)
527 {
528 if (fread (raw_bin_count, sizeof (raw_bin_count), 1, ifp) != 1)
529 {
530 fprintf (stderr,
531 _("%s: unexpected EOF after reading %d/%d bins\n"),
532 whoami, --i, hist_num_bins);
533 done (1);
534 }
0eee5820 535
b3296dc5
VP
536 histograms->sample[i]
537 += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
252b5132
RH
538 }
539
ef368dac
NC
540 /* The rest of the file consists of a bunch of
541 <from,self,count> tuples. */
e7e2dd92 542 while (gmon_read_raw_arc (ifp, &from_pc, &self_pc, &count) == 0)
252b5132
RH
543 {
544 ++narcs;
0eee5820 545
252b5132
RH
546 DBG (SAMPLEDEBUG,
547 printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n",
fdcf7d43 548 (unsigned long) from_pc, (unsigned long) self_pc, count));
0eee5820 549
ef368dac 550 /* Add this arc. */
252b5132
RH
551 cg_tally (from_pc, self_pc, count);
552 }
0eee5820 553
252b5132
RH
554 fclose (ifp);
555
556 if (hz == HZ_WRONG)
557 {
ef368dac
NC
558 /* How many ticks per second? If we can't tell, report
559 time in ticks. */
252b5132 560 hz = hertz ();
0eee5820 561
252b5132
RH
562 if (hz == HZ_WRONG)
563 {
564 hz = 1;
565 fprintf (stderr, _("time is in ticks, not seconds\n"));
566 }
567 }
568 }
569 else
570 {
571 fprintf (stderr, _("%s: don't know how to deal with file format %d\n"),
572 whoami, file_format);
573 done (1);
574 }
575
576 if (output_style & STYLE_GMON_INFO)
577 {
578 printf (_("File `%s' (version %d) contains:\n"),
579 filename, gmon_file_version);
741247bf
NC
580 printf (nhist == 1 ?
581 _("\t%d histogram record\n") :
582 _("\t%d histogram records\n"), nhist);
583 printf (narcs == 1 ?
584 _("\t%d call-graph record\n") :
585 _("\t%d call-graph records\n"), narcs);
586 printf (nbbs == 1 ?
587 _("\t%d basic-block count record\n") :
588 _("\t%d basic-block count records\n"), nbbs);
b34976b6 589 first_output = FALSE;
252b5132
RH
590 }
591}
592
593
594void
3e8f6abf 595gmon_out_write (const char *filename)
252b5132
RH
596{
597 FILE *ofp;
598 struct gmon_hdr ghdr;
599
600 ofp = fopen (filename, FOPEN_WB);
601 if (!ofp)
602 {
603 perror (filename);
604 done (1);
605 }
606
607 if (file_format == FF_AUTO || file_format == FF_MAGIC)
608 {
ef368dac 609 /* Write gmon header. */
252b5132
RH
610
611 memcpy (&ghdr.cookie[0], GMON_MAGIC, 4);
1355568a 612 bfd_put_32 (core_bfd, (bfd_vma) GMON_VERSION, (bfd_byte *) ghdr.version);
0eee5820 613
252b5132
RH
614 if (fwrite (&ghdr, sizeof (ghdr), 1, ofp) != 1)
615 {
616 perror (filename);
617 done (1);
618 }
619
ef368dac 620 /* Write execution time histogram if we have one. */
252b5132 621 if (gmon_input & INPUT_HISTOGRAM)
ef368dac 622 hist_write_hist (ofp, filename);
252b5132 623
ef368dac 624 /* Write call graph arcs if we have any. */
252b5132 625 if (gmon_input & INPUT_CALL_GRAPH)
ef368dac 626 cg_write_arcs (ofp, filename);
252b5132 627
ef368dac 628 /* Write basic-block info if we have it. */
252b5132 629 if (gmon_input & INPUT_BB_COUNTS)
ef368dac 630 bb_write_blocks (ofp, filename);
252b5132
RH
631 }
632 else if (file_format == FF_BSD || file_format == FF_BSD44)
633 {
252b5132 634 UNIT raw_bin_count;
8c62e9e1 635 unsigned int i, hdrsize;
e7e2dd92
NC
636 unsigned padsize;
637 char pad[3*4];
252b5132
RH
638 Arc *arc;
639 Sym *sym;
640
e7e2dd92 641 memset (pad, 0, sizeof (pad));
252b5132 642
e7e2dd92
NC
643 hdrsize = 0;
644 /* Decide how large the header will be. Use the 4.4BSD format
645 header if explicitly specified, or if the profiling rate is
646 non-standard. Otherwise, use the old BSD format. */
252b5132 647 if (file_format == FF_BSD44
e7e2dd92 648 || hz != hertz())
252b5132 649 {
e7e2dd92 650 padsize = 3*4;
9844bab2 651 switch (gmon_get_ptr_size ())
252b5132 652 {
9844bab2 653 case ptr_32bit:
e7e2dd92
NC
654 hdrsize = GMON_HDRSIZE_BSD44_32;
655 break;
656
9844bab2 657 case ptr_64bit:
e7e2dd92
NC
658 hdrsize = GMON_HDRSIZE_BSD44_64;
659 break;
252b5132
RH
660 }
661 }
662 else
663 {
e7e2dd92 664 padsize = 0;
9844bab2 665 switch (gmon_get_ptr_size ())
e7e2dd92 666 {
9844bab2 667 case ptr_32bit:
e7e2dd92
NC
668 hdrsize = GMON_HDRSIZE_OLDBSD_32;
669 break;
670
9844bab2 671 case ptr_64bit:
e7e2dd92
NC
672 hdrsize = GMON_HDRSIZE_OLDBSD_64;
673 /* FIXME: Checking host compiler defines here means that we can't
674 use a cross gprof alpha OSF. */
675#if defined(__alpha__) && defined (__osf__)
676 padsize = 4;
677#endif
678 break;
e7e2dd92
NC
679 }
680 }
681
682 /* Write the parts of the headers that are common to both the
683 old BSD and 4.4BSD formats. */
b3296dc5
VP
684 if (gmon_io_write_vma (ofp, histograms->lowpc)
685 || gmon_io_write_vma (ofp, histograms->highpc)
686 || gmon_io_write_32 (ofp, histograms->num_bins
687 * sizeof (UNIT) + hdrsize))
e7e2dd92
NC
688 {
689 perror (filename);
690 done (1);
691 }
692
693 /* Write out the 4.4BSD header bits, if that's what we're using. */
694 if (file_format == FF_BSD44
695 || hz != hertz())
696 {
697 if (gmon_io_write_32 (ofp, GMONVERSION)
1355568a 698 || gmon_io_write_32 (ofp, (unsigned int) hz))
252b5132
RH
699 {
700 perror (filename);
701 done (1);
702 }
703 }
704
e7e2dd92
NC
705 /* Now write out any necessary padding after the meaningful
706 header bits. */
707 if (padsize != 0
708 && fwrite (pad, 1, padsize, ofp) != padsize)
709 {
710 perror (filename);
711 done (1);
712 }
713
ef368dac 714 /* Dump the samples. */
b3296dc5 715 for (i = 0; i < histograms->num_bins; ++i)
252b5132 716 {
b3296dc5 717 bfd_put_16 (core_bfd, (bfd_vma) histograms->sample[i],
1355568a 718 (bfd_byte *) &raw_bin_count[0]);
252b5132
RH
719 if (fwrite (&raw_bin_count[0], sizeof (raw_bin_count), 1, ofp) != 1)
720 {
721 perror (filename);
722 done (1);
723 }
724 }
725
ef368dac 726 /* Dump the normalized raw arc information. */
252b5132
RH
727 for (sym = symtab.base; sym < symtab.limit; ++sym)
728 {
729 for (arc = sym->cg.children; arc; arc = arc->next_child)
730 {
e7e2dd92
NC
731 if (gmon_write_raw_arc (ofp, arc->parent->addr,
732 arc->child->addr, arc->count))
252b5132
RH
733 {
734 perror (filename);
735 done (1);
736 }
737 DBG (SAMPLEDEBUG,
738 printf ("[dumpsum] frompc 0x%lx selfpc 0x%lx count %lu\n",
fdcf7d43
ILT
739 (unsigned long) arc->parent->addr,
740 (unsigned long) arc->child->addr, arc->count));
252b5132
RH
741 }
742 }
0eee5820 743
252b5132
RH
744 fclose (ofp);
745 }
746 else
747 {
748 fprintf (stderr, _("%s: don't know how to deal with file format %d\n"),
749 whoami, file_format);
750 done (1);
751 }
752}
This page took 0.45668 seconds and 4 git commands to generate.