Bug Summary

File:src/usr.bin/pctr/pctr.c
Warning:line 135, column 2
Value stored to 'argv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pctr.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/pctr/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/pctr/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/pctr/pctr.c
1/* $OpenBSD: pctr.c,v 1.24 2019/06/28 13:35:02 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2007 Mike Belopuhov, Aleksey Lomovtsev
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * Pentium performance counter control program for OpenBSD.
21 * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
22 *
23 * Modification and redistribution in source and binary forms is
24 * permitted provided that due credit is given to the author and the
25 * OpenBSD project by leaving this copyright notice intact.
26 */
27
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <sys/sysctl.h>
31#include <sys/ioctl.h>
32
33#include <machine/cpu.h>
34#include <machine/pctr.h>
35#include <machine/specialreg.h>
36
37#include <errno(*__errno()).h>
38#include <err.h>
39#include <fcntl.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44
45#include "pctrvar.h"
46
47static int cpu_type;
48static int tsc_avail;
49
50static int ctr, func, masku, thold;
51static int cflag, eflag, iflag, kflag, uflag;
52static int Mflag, Eflag, Sflag, Iflag, Aflag;
53
54static void pctr_cpu_creds(void);
55static char *pctr_fn2str(u_int32_t);
56static void pctr_printvals(struct pctrst *);
57static int pctr_read(struct pctrst *);
58static int pctr_write(int, u_int32_t);
59static void pctr_list_fnct(void);
60static int pctr_set_cntr(void);
61static void usage(void);
62
63int
64main(int argc, char **argv)
65{
66 const char *errstr;
67 struct pctrst st;
68 int ch = -1;
69 int list_mode = 0, set_mode = 0;
70
71 pctr_cpu_creds();
72
73 while ((ch = getopt(argc, argv, "AcEef:IiklMm:Ss:t:u")) != -1)
74 switch (ch) {
75 case 'A':
76 Aflag = 1;
77 break;
78 case 'c':
79 cflag = 1;
80 break;
81 case 'E':
82 Eflag = 1;
83 break;
84 case 'e':
85 eflag = 1;
86 break;
87 case 'f':
88 if (sscanf(optarg, "%x", &func) <= 0 || func < 0 ||
89 func > PCTR_MAX_FUNCT0xff)
90 errx(1, "invalid function number");
91 break;
92 case 'I':
93 Iflag = 1;
94 break;
95 case 'i':
96 iflag = 1;
97 break;
98 case 'k':
99 kflag = 1;
100 break;
101 case 'l':
102 list_mode = 1;
103 break;
104 case 'M':
105 Mflag = 1;
106 break;
107 case 'm':
108 if (sscanf(optarg, "%x", &masku) <= 0 || masku < 0 ||
109 masku > PCTR_MAX_UMASK0xff)
110 errx(1, "invalid unit mask number");
111 break;
112 case 'S':
113 Sflag = 1;
114 break;
115 case 's':
116 set_mode = 1;
117 ctr = strtonum(optarg, 0, PCTR_NUM4-1, &errstr);
118 if (errstr)
119 errx(1, "counter number is %s: %s", errstr,
120 optarg);
121 break;
122 case 't':
123 thold = strtonum(optarg, 0, 0xff, &errstr);
124 if (errstr)
125 errx(1, "threshold is %s: %s", errstr, optarg);
126 break;
127 case 'u':
128 uflag = 1;
129 break;
130 default:
131 usage();
132 /* NOTREACHED */
133 }
134 argc -= optind;
135 argv += optind;
Value stored to 'argv' is never read
136
137 if (argc)
138 usage();
139
140 if (Aflag && (Mflag || Eflag || Sflag || Iflag))
141 usage();
142
143 if (list_mode)
144 pctr_list_fnct();
145 else if (set_mode) {
146 if (pctr_set_cntr() < 0)
147 err(1, "pctr_set_cntr");
148 } else {
149 bzero(&st, sizeof(st));
150 if (pctr_read(&st) < 0)
151 err(1, "pctr_read");
152 pctr_printvals(&st);
153 }
154 return (0);
155}
156
157static void
158pctr_cpu_creds(void)
159{
160 int atype;
161 char arch[16], vendor[64];
162 int mib[2], cpu_id, cpu_feature;
163 size_t len;
164
165 /* Get the architecture */
166 mib[0] = CTL_HW6;
167 mib[1] = HW_MACHINE1;
168 len = sizeof(arch);
169 if (sysctl(mib, 2, arch, &len, NULL((void *)0), 0) == -1)
170 err(1, "HW_MACHINE");
171
172 if (strcmp(arch, "i386") == 0)
173 atype = ARCH_I3861;
174 else if (strcmp(arch, "amd64") == 0)
175 atype = ARCH_AMD642;
176 else
177 errx(1, "architecture %s is not supported", arch);
178
179 /* Get the CPU id */
180 mib[0] = CTL_MACHDEP7;
181 mib[1] = CPU_CPUID7;
182 len = sizeof(cpu_id);
183 if (sysctl(mib, 2, &cpu_id, &len, NULL((void *)0), 0) == -1)
184 err(1, "CPU_CPUID");
185
186 /* Get the CPU features */
187 mib[1] = CPU_CPUFEATURE8;
188 len = sizeof(cpu_feature);
189 if (sysctl(mib, 2, &cpu_feature, &len, NULL((void *)0), 0) == -1)
190 err(1, "CPU_CPUFEATURE");
191
192 /* Get the processor vendor */
193 mib[0] = CTL_MACHDEP7;
194 mib[1] = CPU_CPUVENDOR6;
195 len = sizeof(vendor);
196 if (sysctl(mib, 2, vendor, &len, NULL((void *)0), 0) == -1)
197 err(1, "CPU_CPUVENDOR");
198
199 switch (atype) {
200 case ARCH_I3861:
201 if (strcmp(vendor, "AuthenticAMD") == 0) {
202 if (((cpu_id >> 8) & 15) >= 6)
203 cpu_type = CPU_AMD4;
204 else
205 cpu_type = CPU_UNDEF0; /* old AMD cpu */
206
207 } else if (strcmp(vendor, "GenuineIntel") == 0) {
208 if (((cpu_id >> 8) & 15) == 6 &&
209 ((cpu_id >> 4) & 15) > 14)
210 cpu_type = CPU_CORE3;
211 else if (((cpu_id >> 8) & 15) >= 6)
212 cpu_type = CPU_P62;
213 else if (((cpu_id >> 4) & 15) > 0)
214 cpu_type = CPU_P51;
215 else
216 cpu_type = CPU_UNDEF0; /* old Intel cpu */
217 }
218 if (cpu_feature & CPUID_TSC0x00000010)
219 tsc_avail = 1;
220 break;
221 case ARCH_AMD642:
222 if (strcmp(vendor, "AuthenticAMD") == 0)
223 cpu_type = CPU_AMD4;
224 else if (strcmp(vendor, "GenuineIntel") == 0)
225 cpu_type = CPU_CORE3;
226 if (cpu_feature & CPUID_TSC0x00000010)
227 tsc_avail = 1;
228 break;
229 }
230}
231
232static __inline int
233pctr_ctrfn_index(struct ctrfn *cfnp, u_int32_t func)
234{
235 int i;
236
237 for (i = 0; cfnp[i].name != NULL((void *)0); i++)
238 if (cfnp[i].fn == func)
239 return (i);
240 return (-1);
241}
242
243static char *
244pctr_fn2str(u_int32_t sel)
245{
246 static char buf[128];
247 struct ctrfn *cfnp = NULL((void *)0);
248 char th[6], um[5], *msg;
249 u_int32_t fn;
250 int ind;
251
252 bzero(buf, sizeof(buf));
253 bzero(th, sizeof(th));
254 bzero(um, sizeof(um));
255 switch (cpu_type) {
256 case CPU_P51:
257 fn = sel & 0x3f;
258 if ((ind = pctr_ctrfn_index(p5fn, fn)) < 0)
259 msg = "unknown function";
260 else
261 msg = p5fn[ind].name;
262 snprintf(buf, sizeof(buf), "%c%c%c %02x %s",
263 sel & P5CTR_C0x100 ? 'c' : '-',
264 sel & P5CTR_U0x080 ? 'u' : '-',
265 sel & P5CTR_K0x040 ? 'k' : '-',
266 fn, msg);
267 break;
268 case CPU_P62:
269 cfnp = p6fn;
270 case CPU_CORE3:
271 if (cpu_type == CPU_CORE3)
272 cfnp = corefn;
273 fn = sel & 0xff;
274 if ((ind = pctr_ctrfn_index(cfnp, fn)) < 0)
275 msg = "unknown function";
276 else
277 msg = cfnp[ind].name;
278 if (cfnp[ind].name && cfnp[ind].flags & CFL_MESI0x01)
279 snprintf(um, sizeof (um), "%c%c%c%c",
280 sel & PCTR_UM_M0x0800 ? 'M' : '-',
281 sel & PCTR_UM_E0x0400 ? 'E' : '-',
282 sel & PCTR_UM_S0x0200 ? 'S' : '-',
283 sel & PCTR_UM_I0x0100 ? 'I' : '-');
284 else if (cfnp[ind].name && cfnp[ind].flags & CFL_SA0x02)
285 snprintf(um, sizeof(um), "%c",
286 sel & PCTR_UM_A0x2000 ? 'A' : '-');
287 if (sel >> PCTR_CM_SHIFT24)
288 snprintf(th, sizeof(th), "+%d",
289 sel >> PCTR_CM_SHIFT24);
290 snprintf(buf, sizeof(buf), "%c%c%c%c %02x %02x %s %s %s",
291 sel & PCTR_I0x800000 ? 'i' : '-',
292 sel & PCTR_E0x040000 ? 'e' : '-',
293 sel & PCTR_K0x020000 ? 'k' : '-',
294 sel & PCTR_U0x010000 ? 'u' : '-',
295 fn, (sel >> PCTR_UM_SHIFT8) & 0xff, th, um, msg);
296 break;
297 case CPU_AMD4:
298 fn = sel & 0xff;
299 if (sel >> PCTR_CM_SHIFT24)
300 snprintf(th, sizeof(th), "+%d",
301 sel >> PCTR_CM_SHIFT24);
302 snprintf(buf, sizeof(buf), "%c%c%c%c %02x %02x %s",
303 sel & PCTR_I0x800000 ? 'i' : '-',
304 sel & PCTR_E0x040000 ? 'e' : '-',
305 sel & PCTR_K0x020000 ? 'k' : '-',
306 sel & PCTR_U0x010000 ? 'u' : '-',
307 fn, (sel >> PCTR_UM_SHIFT8) & 0xff, th);
308 break;
309 }
310 return (buf);
311}
312
313static void
314pctr_printvals(struct pctrst *st)
315{
316 int i, n;
317
318 switch (cpu_type) {
319 case CPU_P51:
320 case CPU_P62:
321 case CPU_CORE3:
322 n = PCTR_INTEL_NUM2;
323 case CPU_AMD4:
324 if (cpu_type == CPU_AMD4)
325 n = PCTR_AMD_NUM4;
326 for (i = 0; i < n; i++)
327 printf(" ctr%d = %16llu [%s]\n", i, st->pctr_hwc[i],
328 pctr_fn2str(st->pctr_fn[i]));
329 if (tsc_avail)
330 printf(" tsc = %16llu\n", st->pctr_tsc);
331 break;
332 }
333}
334
335static int
336pctr_read(struct pctrst *st)
337{
338 int fd, se;
339
340 fd = open(_PATH_PCTR"/dev/pctr", O_RDONLY0x0000);
341 if (fd == -1)
342 return (-1);
343 if (ioctl(fd, PCIOCRD((unsigned long)0x40000000 | ((sizeof(struct pctrst) & 0x1fff
) << 16) | ((('c')) << 8) | ((1)))
, st) == -1) {
344 se = errno(*__errno());
345 close(fd);
346 errno(*__errno()) = se;
347 return (-1);
348 }
349 return (close(fd));
350}
351
352static int
353pctr_write(int ctr, u_int32_t val)
354{
355 int fd, se;
356
357 fd = open(_PATH_PCTR"/dev/pctr", O_WRONLY0x0001);
358 if (fd == -1)
359 return (-1);
360 if (ioctl(fd, PCIOCS0((unsigned long)0x80000000 | ((sizeof(unsigned int) & 0x1fff
) << 16) | ((('c')) << 8) | ((8)))
+ ctr, &val) == -1) {
361 se = errno(*__errno());
362 close(fd);
363 errno(*__errno()) = se;
364 return (-1);
365 }
366 return (close(fd));
367}
368
369static __inline void
370pctr_printdesc(char *desc)
371{
372 char *p;
373
374 for (;;) {
375 while (*desc == ' ')
376 desc++;
377 if (strlen(desc) < 70) {
378 if (*desc)
379 printf(" %s\n", desc);
380 return;
381 }
382 p = desc + 72;
383 while (*--p != ' ')
384 ;
385 while (*--p == ' ')
386 ;
387 p++;
388 printf(" %.*s\n", (int)(p-desc), desc);
389 desc = p;
390 }
391}
392
393static void
394pctr_list_fnct(void)
395{
396 struct ctrfn *cfnp = NULL((void *)0);
397
398 if (cpu_type == CPU_P51)
399 cfnp = p5fn;
400 else if (cpu_type == CPU_P62)
401 cfnp = p6fn;
402 else if (cpu_type == CPU_CORE3)
403 cfnp = corefn;
404 else if (cpu_type == CPU_AMD4)
405 cfnp = amdfn;
406 else
407 return;
408
409 for (; cfnp->name; cfnp++) {
410 printf("%02x %s", cfnp->fn, cfnp->name);
411 if (cfnp->flags & CFL_MESI0x01)
412 printf(" (MESI)");
413 else if (cfnp->flags & CFL_SA0x02)
414 printf(" (A)");
415 if (cfnp->flags & CFL_C00x04)
416 printf(" (ctr0 only)");
417 else if (cfnp->flags & CFL_C10x08)
418 printf(" (ctr1 only)");
419 if (cfnp->flags & CFL_UM0x20)
420 printf(" (needs unit mask)");
421 printf("\n");
422 if (cfnp->desc)
423 pctr_printdesc(cfnp->desc);
424 }
425}
426
427static int
428pctr_set_cntr(void)
429{
430 struct ctrfn *cfnp = NULL((void *)0);
431 u_int32_t val = func;
432 int ind = 0;
433
434 switch (cpu_type) {
435 case CPU_P51:
436 if (ctr >= PCTR_INTEL_NUM2)
437 errx(1, "only %d counters are supported",
438 PCTR_INTEL_NUM2);
439 if (cflag)
440 val |= P5CTR_C0x100;
441 if (kflag)
442 val |= P5CTR_K0x040;
443 if (uflag)
444 val |= P5CTR_U0x080;
445 if (func && (!kflag && !uflag))
446 val |= P5CTR_K0x040 | P5CTR_U0x080;
447 break;
448 case CPU_P62:
449 cfnp = p6fn;
450 case CPU_CORE3:
451 if (cpu_type == CPU_CORE3)
452 cfnp = corefn;
453 if (ctr >= PCTR_INTEL_NUM2)
454 errx(1, "only %d counters are supported",
455 PCTR_INTEL_NUM2);
456 if (func && (ind = pctr_ctrfn_index(cfnp, func)) < 0)
457 errx(1, "function %02x is not supported", func);
458 if (func && (cfnp[ind].flags & CFL_SA0x02))
459 val |= PCTR_UM_A0x2000;
460 if (func && (cfnp[ind].flags & CFL_MESI0x01)) {
461 if (Mflag)
462 val |= PCTR_UM_M0x0800;
463 if (Eflag)
464 val |= PCTR_UM_E0x0400;
465 if (Sflag)
466 val |= PCTR_UM_S0x0200;
467 if (Iflag)
468 val |= PCTR_UM_I0x0100;
469 if (!Mflag || !Eflag || !Sflag || !Iflag)
470 val |= PCTR_UM_MESI(0x0800|0x0400|0x0200|0x0100);
471 }
472 if (func && (cfnp[ind].flags & CFL_ED0x10))
473 val |= PCTR_E0x040000;
474 if (func && (cfnp[ind].flags & CFL_UM0x20) && !masku)
475 errx(1, "function %02x needs unit mask specification",
476 func);
477 case CPU_AMD4:
478 if (cpu_type == CPU_AMD4 && func &&
479 ((ind = pctr_ctrfn_index(amdfn, func)) < 0))
480 errx(1, "function %02x is not supported", func);
481 if (ctr >= PCTR_AMD_NUM4)
482 errx(1, "only %d counters are supported",
483 PCTR_AMD_NUM4);
484 if (eflag)
485 val |= PCTR_E0x040000;
486 if (iflag)
487 val |= PCTR_I0x800000;
488 if (kflag)
489 val |= PCTR_K0x020000;
490 if (uflag)
491 val |= PCTR_U0x010000;
492 if (func && (!kflag && !uflag))
493 val |= PCTR_K0x020000 | PCTR_U0x010000;
494 val |= masku << PCTR_UM_SHIFT8;
495 val |= thold << PCTR_CM_SHIFT24;
496 if (func)
497 val |= PCTR_EN0x400000;
498 break;
499 }
500
501 return (pctr_write(ctr, val));
502}
503
504static void
505usage(void)
506{
507 extern char *__progname;
508 char *usg = NULL((void *)0);
509
510 switch (cpu_type) {
511 case CPU_P51:
512 usg = "[-cklu] [-f funct] [-s ctr]";
513 break;
514 case CPU_P62:
515 case CPU_CORE3:
516 usg = "[-AEeIiklMSu] [-f funct] [-m umask] [-s ctr] "
517 "[-t thold]";
518 break;
519 case CPU_AMD4:
520 usg = "[-eilku] [-f funct] [-m umask] [-s ctr] "
521 "[-t thold]";
522 break;
523 }
524
525 fprintf(stderr(&__sF[2]), "usage: %s %s\n", __progname, usg);
526 exit(1);
527}