1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #ifdef HAVE_CONFIG_H
24: # include <config.h>
25: #endif
26:
27: #include <argp.h>
28: #include <byteswap.h>
29: #include <errno.h>
30: #include <error.h>
31: #include <fcntl.h>
32: #include <inttypes.h>
33: #include <libintl.h>
34: #include <stdlib.h>
35: #include <string.h>
36: #include <unistd.h>
37:
38: #include "../version.h"
39:
40: #define PACKAGE _libc_intl_domainname
41:
42: #ifndef _
43: # define _(Str) gettext (Str)
44: #endif
45:
46: #ifndef N_
47: # define N_(Str) Str
48: #endif
49:
50:
51: static const struct argp_option options[] =
52: {
53: { "unbuffered", 'u', NULL, 0, N_("Don't buffer output") },
54: { NULL, 0, NULL, 0, NULL }
55: };
56:
57:
58: static const char doc[] = N_("Dump information generated by PC profiling.");
59:
60:
61: static const char args_doc[] = N_("[FILE]");
62:
63:
64: static char *more_help (int key, const char *text, void *input);
65:
66:
67: static error_t parse_opt (int key, char *arg, struct argp_state *state);
68:
69:
70: static struct argp argp =
71: {
72: options, parse_opt, args_doc, doc, NULL, more_help
73: };
74:
75:
76: int
77: main (int argc, char *argv[])
78: {
79:
80: setlocale (LC_ALL, "");
81:
82:
83: textdomain (PACKAGE);
84:
85:
86: int remaining;
87: argp_parse (&argp, argc, argv, 0, &remaining, NULL);
88:
89: int fd;
90: if (remaining == argc)
91: fd = STDIN_FILENO;
92: else if (remaining + 1 != argc)
93: {
94: argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
95: program_invocation_short_name);
96: exit (1);
97: }
98: else
99: {
100:
101: fd = open (argv[remaining], O_RDONLY);
102:
103: if (fd == -1)
104: error (EXIT_FAILURE, errno, _("cannot open input file"));
105: }
106:
107:
108:
109: uint32_t word;
110: if (TEMP_FAILURE_RETRY (read (fd, &word, 4)) != 4)
111: error (EXIT_FAILURE, errno, _("cannot read header"));
112:
113:
114: int must_swap = (word & 0xfffffff0) == bswap_32 (0xdeb00000);
115: if (must_swap)
116: word = bswap_32 (word);
117:
118:
119: if (word == 0xdeb00004)
120: {
121: union
122: {
123: uint32_t ptrs[2];
124: char bytes[8];
125: } pair;
126:
127: while (1)
128: {
129: size_t len = sizeof (pair);
130: size_t n;
131:
132: while (len > 0
133: && (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len],
134: len))) != 0)
135: len -= n;
136:
137: if (len != 0)
138:
139: break;
140:
141: printf ("this = %#010" PRIx32 ", caller = %#010" PRIx32 "\n",
142: must_swap ? bswap_32 (pair.ptrs[0]) : pair.ptrs[0],
143: must_swap ? bswap_32 (pair.ptrs[1]) : pair.ptrs[1]);
144: }
145: }
146: else if (word == 0xdeb00008)
147: {
148: union
149: {
150: uint64_t ptrs[2];
151: char bytes[16];
152: } pair;
153:
154: while (1)
155: {
156: size_t len = sizeof (pair);
157: size_t n;
158:
159: while (len > 0
160: && (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len],
161: len))) != 0)
162: len -= n;
163:
164: if (len != 0)
165:
166: break;
167:
168: printf ("this = %#018" PRIx64 ", caller = %#018" PRIx64 "\n",
169: must_swap ? bswap_64 (pair.ptrs[0]) : pair.ptrs[0],
170: must_swap ? bswap_64 (pair.ptrs[1]) : pair.ptrs[1]);
171: }
172: }
173: else
174:
175: error (EXIT_FAILURE, 0, _("invalid pointer size"));
176:
177:
178: close (fd);
179:
180: return 0;
181: }
182:
183: static error_t
184: parse_opt (int key, char *arg, struct argp_state *state)
185: {
186: switch (key)
187: {
188: case 'u':
189: setbuf (stdout, NULL);
190: break;
191: default:
192: return ARGP_ERR_UNKNOWN;
193: }
194: return 0;
195: }
196:
197: static char *
198: more_help (int key, const char *text, void *input)
199: {
200: switch (key)
201: {
202: case ARGP_KEY_HELP_EXTRA:
203:
204: return strdup (gettext ("\
205: For bug reporting instructions, please see:\n\
206: <http://www.gnu.org/software/libc/bugs.html>.\n"));
207: default:
208: break;
209: }
210: return (char *) text;
211: }