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