gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gprof / gmon_io.c
CommitLineData
ef368dac
NC
1/* gmon_io.c - Input and output from/to gmon.out files.
2
b3adc24a 3 Copyright (C) 1999-2020 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
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 63static enum gmon_ptr_size
e6c7cdec 64gmon_get_ptr_size (void)
9844bab2
CD
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
e6c7cdec 90gmon_get_ptr_signedness (void)
9844bab2
CD
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 303 SET_BINARY (fileno (stdin));
252b5132
RH
304 }
305 else
306 {
307 ifp = fopen (filename, FOPEN_RB);
0eee5820 308
252b5132
RH
309 if (!ifp)
310 {
311 perror (filename);
312 done (1);
313 }
314 }
0eee5820 315
252b5132
RH
316 if (fread (&ghdr, sizeof (struct gmon_hdr), 1, ifp) != 1)
317 {
318 fprintf (stderr, _("%s: file too short to be a gmon file\n"),
319 filename);
320 done (1);
321 }
322
0eee5820
AM
323 if ((file_format == FF_MAGIC)
324 || (file_format == FF_AUTO && !strncmp (&ghdr.cookie[0], GMON_MAGIC, 4)))
252b5132
RH
325 {
326 if (file_format == FF_MAGIC && strncmp (&ghdr.cookie[0], GMON_MAGIC, 4))
327 {
328 fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"),
329 whoami, filename);
330 done (1);
331 }
332
ef368dac 333 /* Right magic, so it's probably really a new gmon.out file. */
252b5132 334 gmon_file_version = bfd_get_32 (core_bfd, (bfd_byte *) ghdr.version);
0eee5820 335
252b5132
RH
336 if (gmon_file_version != GMON_VERSION && gmon_file_version != 0)
337 {
338 fprintf (stderr,
339 _("%s: file `%s' has unsupported version %d\n"),
340 whoami, filename, gmon_file_version);
341 done (1);
342 }
343
ef368dac 344 /* Read in all the records. */
252b5132
RH
345 while (fread (&tag, sizeof (tag), 1, ifp) == 1)
346 {
347 switch (tag)
348 {
349 case GMON_TAG_TIME_HIST:
350 ++nhist;
351 gmon_input |= INPUT_HISTOGRAM;
352 hist_read_rec (ifp, filename);
353 break;
354
355 case GMON_TAG_CG_ARC:
356 ++narcs;
357 gmon_input |= INPUT_CALL_GRAPH;
358 cg_read_rec (ifp, filename);
359 break;
360
361 case GMON_TAG_BB_COUNT:
362 ++nbbs;
363 gmon_input |= INPUT_BB_COUNTS;
364 bb_read_rec (ifp, filename);
365 break;
366
367 default:
368 fprintf (stderr,
369 _("%s: %s: found bad tag %d (file corrupted?)\n"),
370 whoami, filename, tag);
371 done (1);
372 }
373 }
374 }
375 else if (file_format == FF_AUTO
376 || file_format == FF_BSD
377 || file_format == FF_BSD44)
378 {
379 struct hdr
380 {
381 bfd_vma low_pc;
382 bfd_vma high_pc;
8c62e9e1 383 unsigned int ncnt;
252b5132 384 };
8c62e9e1
AM
385 unsigned int i;
386 int samp_bytes, header_size = 0;
252b5132
RH
387 unsigned long count;
388 bfd_vma from_pc, self_pc;
252b5132
RH
389 UNIT raw_bin_count;
390 struct hdr tmp;
8c62e9e1 391 unsigned int version;
b3296dc5 392 unsigned int hist_num_bins;
252b5132 393
ef368dac 394 /* Information from a gmon.out file is in two parts: an array of
0eee5820 395 sampling hits within pc ranges, and the arcs. */
252b5132
RH
396 gmon_input = INPUT_HISTOGRAM | INPUT_CALL_GRAPH;
397
ef368dac 398 /* This fseek() ought to work even on stdin as long as it's
0eee5820
AM
399 not an interactive device (heck, is there anybody who would
400 want to type in a gmon.out at the terminal?). */
252b5132
RH
401 if (fseek (ifp, 0, SEEK_SET) < 0)
402 {
403 perror (filename);
404 done (1);
405 }
0eee5820 406
e7e2dd92
NC
407 /* The beginning of the old BSD header and the 4.4BSD header
408 are the same: lowpc, highpc, ncnt */
409 if (gmon_io_read_vma (ifp, &tmp.low_pc)
410 || gmon_io_read_vma (ifp, &tmp.high_pc)
411 || gmon_io_read_32 (ifp, &tmp.ncnt))
252b5132 412 {
e7e2dd92
NC
413 bad_gmon_file:
414 fprintf (stderr, _("%s: file too short to be a gmon file\n"),
252b5132
RH
415 filename);
416 done (1);
417 }
0eee5820 418
e7e2dd92
NC
419 /* Check to see if this a 4.4BSD-style header. */
420 if (gmon_io_read_32 (ifp, &version))
421 goto bad_gmon_file;
252b5132 422
e7e2dd92 423 if (version == GMONVERSION)
252b5132 424 {
8c62e9e1 425 unsigned int profrate;
252b5132
RH
426
427 /* 4.4BSD format header. */
e7e2dd92
NC
428 if (gmon_io_read_32 (ifp, &profrate))
429 goto bad_gmon_file;
0eee5820 430
b3296dc5 431 if (!histograms)
252b5132 432 hz = profrate;
8c62e9e1 433 else if (hz != (int) profrate)
252b5132
RH
434 {
435 fprintf (stderr,
436 _("%s: profiling rate incompatible with first gmon file\n"),
437 filename);
438 done (1);
439 }
440
9844bab2 441 switch (gmon_get_ptr_size ())
e7e2dd92 442 {
9844bab2 443 case ptr_32bit:
e7e2dd92
NC
444 header_size = GMON_HDRSIZE_BSD44_32;
445 break;
446
9844bab2 447 case ptr_64bit:
e7e2dd92
NC
448 header_size = GMON_HDRSIZE_BSD44_64;
449 break;
e7e2dd92 450 }
252b5132
RH
451 }
452 else
453 {
ef368dac 454 /* Old style BSD format. */
252b5132
RH
455 if (file_format == FF_BSD44)
456 {
457 fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"),
458 whoami, filename);
459 done (1);
460 }
461
9844bab2 462 switch (gmon_get_ptr_size ())
252b5132 463 {
9844bab2 464 case ptr_32bit:
e7e2dd92
NC
465 header_size = GMON_HDRSIZE_OLDBSD_32;
466 break;
467
9844bab2 468 case ptr_64bit:
e7e2dd92
NC
469 header_size = GMON_HDRSIZE_OLDBSD_64;
470 break;
252b5132 471 }
e7e2dd92 472 }
252b5132 473
e7e2dd92
NC
474 /* Position the file to after the header. */
475 if (fseek (ifp, header_size, SEEK_SET) < 0)
476 {
477 perror (filename);
478 done (1);
252b5132
RH
479 }
480
b3296dc5
VP
481 samp_bytes = tmp.ncnt - header_size;
482 hist_num_bins = samp_bytes / sizeof (UNIT);
483 if (histograms && (tmp.low_pc != histograms->lowpc
484 || tmp.high_pc != histograms->highpc
485 || (hist_num_bins != histograms->num_bins)))
252b5132
RH
486 {
487 fprintf (stderr, _("%s: incompatible with first gmon file\n"),
488 filename);
489 done (1);
490 }
0eee5820 491
b3296dc5
VP
492 if (!histograms)
493 {
4094fdc2 494 num_histograms = 1;
1e9cc1c2 495 histograms = (struct histogram *) xmalloc (sizeof (struct histogram));
b3296dc5
VP
496 histograms->lowpc = tmp.low_pc;
497 histograms->highpc = tmp.high_pc;
498 histograms->num_bins = hist_num_bins;
4094fdc2
BD
499 hist_scale = (double)((tmp.high_pc - tmp.low_pc) / sizeof (UNIT))
500 / hist_num_bins;
1e9cc1c2 501 histograms->sample = (int *) xmalloc (hist_num_bins * sizeof (int));
f3445b37 502 memset (histograms->sample, 0,
b3296dc5
VP
503 hist_num_bins * sizeof (int));
504 }
0eee5820 505
252b5132
RH
506 DBG (SAMPLEDEBUG,
507 printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n",
b3296dc5
VP
508 (unsigned long) tmp.low_pc, (unsigned long) tmp.high_pc,
509 tmp.ncnt);
252b5132
RH
510 printf ("[gmon_out_read] samp_bytes %d hist_num_bins %d\n",
511 samp_bytes, hist_num_bins));
512
2d35e9f6 513 /* Make sure that we have sensible values. */
b3296dc5 514 if (samp_bytes < 0 || histograms->lowpc > histograms->highpc)
0eee5820
AM
515 {
516 fprintf (stderr,
2d35e9f6
NC
517 _("%s: file '%s' does not appear to be in gmon.out format\n"),
518 whoami, filename);
0eee5820
AM
519 done (1);
520 }
2d35e9f6 521
252b5132 522 if (hist_num_bins)
ef368dac 523 ++nhist;
252b5132 524
252b5132
RH
525 for (i = 0; i < hist_num_bins; ++i)
526 {
527 if (fread (raw_bin_count, sizeof (raw_bin_count), 1, ifp) != 1)
528 {
529 fprintf (stderr,
530 _("%s: unexpected EOF after reading %d/%d bins\n"),
531 whoami, --i, hist_num_bins);
532 done (1);
533 }
0eee5820 534
f3445b37 535 histograms->sample[i]
b3296dc5 536 += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
252b5132
RH
537 }
538
ef368dac
NC
539 /* The rest of the file consists of a bunch of
540 <from,self,count> tuples. */
e7e2dd92 541 while (gmon_read_raw_arc (ifp, &from_pc, &self_pc, &count) == 0)
252b5132
RH
542 {
543 ++narcs;
0eee5820 544
252b5132
RH
545 DBG (SAMPLEDEBUG,
546 printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n",
fdcf7d43 547 (unsigned long) from_pc, (unsigned long) self_pc, count));
0eee5820 548
ef368dac 549 /* Add this arc. */
252b5132
RH
550 cg_tally (from_pc, self_pc, count);
551 }
0eee5820 552
252b5132
RH
553 if (hz == HZ_WRONG)
554 {
ef368dac
NC
555 /* How many ticks per second? If we can't tell, report
556 time in ticks. */
252b5132 557 hz = hertz ();
0eee5820 558
252b5132
RH
559 if (hz == HZ_WRONG)
560 {
561 hz = 1;
562 fprintf (stderr, _("time is in ticks, not seconds\n"));
563 }
564 }
565 }
566 else
567 {
568 fprintf (stderr, _("%s: don't know how to deal with file format %d\n"),
569 whoami, file_format);
570 done (1);
571 }
572
d9097b0b
SB
573 if (ifp != stdin)
574 fclose (ifp);
575
252b5132
RH
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
f3445b37 674 use a cross gprof alpha OSF. */
e7e2dd92
NC
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)
f3445b37 686 || gmon_io_write_32 (ofp, histograms->num_bins
b3296dc5 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.852204 seconds and 4 git commands to generate.