manual: Add links to POSIX Semaphores man-pages documentation
[glibc.git] / debug / pcprofiledump.c
blob26c55af4d88bf83150fc6bb9f5406d084f1c21e9
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. */
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
25 #include <argp.h>
26 #include <byteswap.h>
27 #include <errno.h>
28 #include <error.h>
29 #include <fcntl.h>
30 #include <inttypes.h>
31 #include <libintl.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <stdint.h>
37 #include "../version.h"
39 #define PACKAGE _libc_intl_domainname
41 #ifndef _
42 # define _(Str) gettext (Str)
43 #endif
45 #ifndef N_
46 # define N_(Str) Str
47 #endif
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. */
86 static bool
87 read_exactly (int fd, void *buffer, size_t size, bool in_header)
89 char *p = buffer;
90 char *end = p + size;
91 while (p < end)
93 ssize_t ret = TEMP_FAILURE_RETRY (read (fd, p, end - p));
94 if (ret < 0)
96 if (in_header)
97 error (EXIT_FAILURE, errno, _("cannot read header"));
98 else
99 error (EXIT_FAILURE, errno, _("cannot read pointer pair"));
101 if (ret == 0)
103 if (p == buffer && !in_header)
104 /* Nothing has been read. */
105 return false;
106 if (in_header)
107 error (EXIT_FAILURE, 0, _("unexpected end of file in header"));
108 else
109 error (EXIT_FAILURE, 0,
110 _("unexpected end of file in pointer pair"));
112 p += ret;
114 return true;
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. */
127 int remaining;
128 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
130 int fd;
131 if (remaining == argc)
132 fd = STDIN_FILENO;
133 else if (remaining + 1 != argc)
135 argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
136 program_invocation_short_name);
137 exit (1);
139 else
141 /* Open the given file. */
142 fd = open (argv[remaining], O_RDONLY);
144 if (fd == -1)
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. */
150 uint32_t word;
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);
155 if (must_swap)
156 word = bswap_32 (word);
158 /* We have two loops, one for 32 bit pointers, one for 64 bit pointers. */
159 if (word == 0xdeb00004)
161 uint32_t ptrs[2];
163 while (1)
165 if (!read_exactly (fd, ptrs, sizeof (ptrs), false))
166 break;
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)
175 uint64_t ptrs[2];
177 while (1)
179 if (!read_exactly (fd, ptrs, sizeof (ptrs), false))
180 break;
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]);
187 else
188 /* This should not happen. */
189 error (EXIT_FAILURE, 0, _("invalid pointer size"));
191 /* Clean up. */
192 close (fd);
194 return 0;
197 static error_t
198 parse_opt (int key, char *arg, struct argp_state *state)
200 switch (key)
202 case 'u':
203 setbuf (stdout, NULL);
204 break;
205 default:
206 return ARGP_ERR_UNKNOWN;
208 return 0;
211 static char *
212 more_help (int key, const char *text, void *input)
214 char *tp = NULL;
215 switch (key)
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)
222 return NULL;
223 return tp;
224 default:
225 break;
227 return (char *) text;
230 /* Print the version information. */
231 static void
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\
239 "), "2024");
240 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");