1 /* Dump information generated by PC profiling.
2 Copyright (C) 1999-2025 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* This is mainly an example. It shows how programs which want to use
20 the information should read the file. */
37 #include "../version.h"
39 #define PACKAGE _libc_intl_domainname
42 # define _(Str) gettext (Str)
49 /* Definitions of arguments for argp functions. */
50 static const struct argp_option options
[] =
52 { "unbuffered", 'u', NULL
, 0, N_("Don't buffer output") },
53 { NULL
, 0, NULL
, 0, NULL
}
56 /* Short description of program. */
57 static const char doc
[] = N_("Dump information generated by PC profiling.");
59 /* Strings for arguments in help texts. */
60 static const char args_doc
[] = N_("[FILE]");
62 /* Function to print some extra text in the help message. */
63 static char *more_help (int key
, const char *text
, void *input
);
65 /* Prototype for option handler. */
66 static error_t
parse_opt (int key
, char *arg
, struct argp_state
*state
);
68 /* Name and version of program. */
69 static void print_version (FILE *stream
, struct argp_state
*state
);
70 void (*argp_program_version_hook
) (FILE *, struct argp_state
*) = print_version
;
72 /* Data structure to communicate with argp functions. */
73 static struct argp argp
=
75 options
, parse_opt
, args_doc
, doc
, NULL
, more_help
78 /* Try to read SIZE bytes from FD and store them on BUF. Terminate
79 the process upon read error. Also terminate the process if less
80 than SIZE bytes are remaining in the file. If !IN_HEADER, do not
81 terminate the process if the end of the file is encountered
82 immediately, before any bytes are read.
84 Returns true if SIZE bytes have been read, and false if no bytes
85 have been read due to an end-of-file condition. */
87 read_exactly (int fd
, void *buffer
, size_t size
, bool in_header
)
93 ssize_t ret
= TEMP_FAILURE_RETRY (read (fd
, p
, end
- p
));
97 error (EXIT_FAILURE
, errno
, _("cannot read header"));
99 error (EXIT_FAILURE
, errno
, _("cannot read pointer pair"));
103 if (p
== buffer
&& !in_header
)
104 /* Nothing has been read. */
107 error (EXIT_FAILURE
, 0, _("unexpected end of file in header"));
109 error (EXIT_FAILURE
, 0,
110 _("unexpected end of file in pointer pair"));
118 main (int argc
, char *argv
[])
120 /* Set locale via LC_ALL. */
121 setlocale (LC_ALL
, "");
123 /* Set the text message domain. */
124 textdomain (PACKAGE
);
126 /* Parse and process arguments. */
128 argp_parse (&argp
, argc
, argv
, 0, &remaining
, NULL
);
131 if (remaining
== argc
)
133 else if (remaining
+ 1 != argc
)
135 argp_help (&argp
, stdout
, ARGP_HELP_SEE
| ARGP_HELP_EXIT_ERR
,
136 program_invocation_short_name
);
141 /* Open the given file. */
142 fd
= open (argv
[remaining
], O_RDONLY
);
145 error (EXIT_FAILURE
, errno
, _("cannot open input file"));
148 /* Read the first 4-byte word. It contains the information about
149 the word size and the endianness. */
151 read_exactly (fd
, &word
, sizeof (word
), true);
153 /* Check whether we have to swap the byte order. */
154 int must_swap
= (word
& 0x0fffffff) == bswap_32 (0xdeb00000);
156 word
= bswap_32 (word
);
158 /* We have two loops, one for 32 bit pointers, one for 64 bit pointers. */
159 if (word
== 0xdeb00004)
165 if (!read_exactly (fd
, ptrs
, sizeof (ptrs
), false))
168 printf ("this = %#010" PRIx32
", caller = %#010" PRIx32
"\n",
169 must_swap
? bswap_32 (ptrs
[0]) : ptrs
[0],
170 must_swap
? bswap_32 (ptrs
[1]) : ptrs
[1]);
173 else if (word
== 0xdeb00008)
179 if (!read_exactly (fd
, ptrs
, sizeof (ptrs
), false))
182 printf ("this = %#018" PRIx64
", caller = %#018" PRIx64
"\n",
183 must_swap
? bswap_64 (ptrs
[0]) : ptrs
[0],
184 must_swap
? bswap_64 (ptrs
[1]) : ptrs
[1]);
188 /* This should not happen. */
189 error (EXIT_FAILURE
, 0, _("invalid pointer size"));
198 parse_opt (int key
, char *arg
, struct argp_state
*state
)
203 setbuf (stdout
, NULL
);
206 return ARGP_ERR_UNKNOWN
;
212 more_help (int key
, const char *text
, void *input
)
217 case ARGP_KEY_HELP_EXTRA
:
218 /* We print some extra information. */
219 if (asprintf (&tp
, gettext ("\
220 For bug reporting instructions, please see:\n\
221 %s.\n"), REPORT_BUGS_TO
) < 0)
227 return (char *) text
;
230 /* Print the version information. */
232 print_version (FILE *stream
, struct argp_state
*state
)
234 fprintf (stream
, "pcprofiledump %s%s\n", PKGVERSION
, VERSION
);
235 fprintf (stream
, gettext ("\
236 Copyright (C) %s Free Software Foundation, Inc.\n\
237 This is free software; see the source for copying conditions. There is NO\n\
238 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
240 fprintf (stream
, gettext ("Written by %s.\n"), "Ulrich Drepper");