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