Bug Summary

File:src/usr.bin/ctfdump/ctfdump.c
Warning:line 408, column 4
Value stored to 'l' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctfdump.c -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/ctfdump/obj -resource-dir /usr/local/llvm16/lib/clang/16 -D ZLIB -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -Wno-unused -fdebug-compilation-dir=/usr/src/usr.bin/ctfdump/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.bin/ctfdump/ctfdump.c
1/* $OpenBSD: ctfdump.c,v 1.27 2022/08/14 15:01:18 millert Exp $ */
2
3/*
4 * Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
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#include <sys/types.h>
20#include <sys/stat.h>
21#include <sys/mman.h>
22#include <sys/ctf.h>
23
24#include <err.h>
25#include <fcntl.h>
26#include <gelf.h>
27#include <libelf.h>
28#include <locale.h>
29#include <stdio.h>
30#include <stdint.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34
35#ifdef ZLIB1
36#include <zlib.h>
37#endif /* ZLIB */
38
39#ifndef nitems
40#define nitems(_a)(sizeof((_a)) / sizeof((_a)[0])) (sizeof((_a)) / sizeof((_a)[0]))
41#endif
42
43#define DUMP_OBJECT(1 << 0) (1 << 0)
44#define DUMP_FUNCTION(1 << 1) (1 << 1)
45#define DUMP_HEADER(1 << 2) (1 << 2)
46#define DUMP_LABEL(1 << 3) (1 << 3)
47#define DUMP_STRTAB(1 << 4) (1 << 4)
48#define DUMP_STATISTIC(1 << 5) (1 << 5)
49#define DUMP_TYPE(1 << 6) (1 << 6)
50
51int dump(const char *, uint8_t);
52int isctf(const char *, size_t);
53__dead__attribute__((__noreturn__)) void usage(void);
54
55int ctf_dump(const char *, size_t, uint8_t);
56void ctf_dump_type(struct ctf_header *, const char *, size_t,
57 uint32_t, uint32_t *, uint32_t);
58const char *ctf_kind2name(uint16_t);
59const char *ctf_enc2name(uint16_t);
60const char *ctf_fpenc2name(uint16_t);
61const char *ctf_off2name(struct ctf_header *, const char *, size_t,
62 uint32_t);
63
64char *decompress(const char *, size_t, size_t);
65int elf_dump(uint8_t);
66const char *elf_idx2sym(size_t *, uint8_t);
67
68int
69main(int argc, char *argv[])
70{
71 const char *filename;
72 uint8_t flags = 0;
73 int ch, error = 0;
74
75 setlocale(LC_ALL0, "");
76
77 if (pledge("stdio rpath", NULL((void *)0)) == -1)
78 err(1, "pledge");
79
80 while ((ch = getopt(argc, argv, "dfhlst")) != -1) {
81 switch (ch) {
82 case 'd':
83 flags |= DUMP_OBJECT(1 << 0);
84 break;
85 case 'f':
86 flags |= DUMP_FUNCTION(1 << 1);
87 break;
88 case 'h':
89 flags |= DUMP_HEADER(1 << 2);
90 break;
91 case 'l':
92 flags |= DUMP_LABEL(1 << 3);
93 break;
94 case 's':
95 flags |= DUMP_STRTAB(1 << 4);
96 break;
97 case 't':
98 flags |= DUMP_TYPE(1 << 6);
99 break;
100 default:
101 usage();
102 }
103 }
104
105 argc -= optind;
106 argv += optind;
107
108 if (argc <= 0)
109 usage();
110
111 /* Dump everything by default */
112 if (flags == 0)
113 flags = 0xff;
114
115 if (elf_version(EV_CURRENT1) == EV_NONE0)
116 errx(1, "elf_version: %s", elf_errmsg(-1));
117
118 while ((filename = *argv++) != NULL((void *)0))
119 error |= dump(filename, flags);
120
121 return error;
122}
123
124Elf *e;
125Elf_Scn *scnsymtab;
126size_t strtabndx, strtabsz, nsymb;
127
128int
129dump(const char *path, uint8_t flags)
130{
131 struct stat st;
132 char *p;
133 int fd, error = 1;
134
135 fd = open(path, O_RDONLY0x0000);
136 if (fd == -1) {
137 warn("open");
138 return 1;
139 }
140
141 if ((e = elf_begin(fd, ELF_C_READ, NULL((void *)0))) == NULL((void *)0)) {
142 warnx("elf_begin: %s", elf_errmsg(-1));
143 goto done;
144 }
145
146 if (elf_kind(e) == ELF_K_ELF) {
147 error = elf_dump(flags);
148 elf_end(e);
149 goto done;
150 }
151 elf_end(e);
152
153 if (fstat(fd, &st) == -1) {
154 warn("fstat");
155 goto done;
156 }
157 if ((uintmax_t)st.st_size > SIZE_MAX0xffffffffffffffffUL) {
158 warnx("file too big to fit memory");
159 goto done;
160 }
161
162 p = mmap(NULL((void *)0), st.st_size, PROT_READ0x01, MAP_PRIVATE0x0002, fd, 0);
163 if (p == MAP_FAILED((void *)-1))
164 err(1, "mmap");
165
166 if (isctf(p, st.st_size))
167 error = ctf_dump(p, st.st_size, flags);
168
169 munmap(p, st.st_size);
170
171 done:
172 close(fd);
173 return error;
174}
175
176const char *
177elf_idx2sym(size_t *idx, uint8_t type)
178{
179 GElf_Sym sym;
180 Elf_Data *data;
181 char *name;
182 size_t i;
183
184 if (scnsymtab == NULL((void *)0) || strtabndx == 0)
185 return NULL((void *)0);
186
187 data = NULL((void *)0);
188 while ((data = elf_rawdata(scnsymtab, data)) != NULL((void *)0)) {
189 for (i = *idx + 1; i < nsymb; i++) {
190 if (gelf_getsym(data, i, &sym) != &sym)
191 continue;
192 if (GELF_ST_TYPE(sym.st_info)(((unsigned int) sym.st_info) & 0xf) != type)
193 continue;
194 if (sym.st_name >= strtabsz)
195 break;
196 if ((name = elf_strptr(e, strtabndx,
197 sym.st_name)) == NULL((void *)0))
198 continue;
199
200 *idx = i;
201 return name;
202 }
203 }
204
205 return NULL((void *)0);
206}
207
208int
209elf_dump(uint8_t flags)
210{
211 GElf_Shdr shdr;
212 Elf_Scn *scn, *scnctf;
213 Elf_Data *data;
214 char *name;
215 size_t shstrndx;
216 int error = 0;
217
218 if (elf_getshdrstrndx(e, &shstrndx) != 0) {
219 warnx("elf_getshdrstrndx: %s", elf_errmsg(-1));
220 return 1;
221 }
222
223 scn = scnctf = NULL((void *)0);
224 while ((scn = elf_nextscn(e, scn)) != NULL((void *)0)) {
225 if (gelf_getshdr(scn, &shdr) != &shdr) {
226 warnx("elf_getshdr: %s", elf_errmsg(-1));
227 return 1;
228 }
229
230 if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL((void *)0)) {
231 warnx("elf_strptr: %s", elf_errmsg(-1));
232 return 1;
233 }
234
235 if (strcmp(name, ELF_CTF".SUNW_ctf") == 0)
236 scnctf = scn;
237
238 if (strcmp(name, ELF_SYMTAB".symtab") == 0 &&
239 shdr.sh_type == SHT_SYMTAB2 && shdr.sh_entsize != 0) {
240 scnsymtab = scn;
241 nsymb = shdr.sh_size / shdr.sh_entsize;
242 }
243
244 if (strcmp(name, ELF_STRTAB".strtab") == 0 &&
245 shdr.sh_type == SHT_STRTAB3) {
246 strtabndx = elf_ndxscn(scn);
247 strtabsz = shdr.sh_size;
248 }
249 }
250
251 if (scnctf == NULL((void *)0)) {
252 warnx("%s section not found", ELF_CTF".SUNW_ctf");
253 return 1;
254 }
255
256 if (scnsymtab == NULL((void *)0))
257 warnx("symbol table not found");
258
259 data = NULL((void *)0);
260 while ((data = elf_rawdata(scnctf, data)) != NULL((void *)0)) {
261 if (data->d_buf == NULL((void *)0)) {
262 warnx("%s section size is zero", ELF_CTF".SUNW_ctf");
263 return 1;
264 }
265
266 if (isctf(data->d_buf, data->d_size))
267 error |= ctf_dump(data->d_buf, data->d_size, flags);
268 }
269
270 return error;
271}
272
273int
274isctf(const char *p, size_t filesize)
275{
276 struct ctf_header cth;
277 size_t dlen;
278
279 if (filesize < sizeof(struct ctf_header)) {
280 warnx("file too small to be CTF");
281 return 0;
282 }
283
284 memcpy(&cth, p, sizeof(struct ctf_header));
285 if (cth.cth_magic != CTF_MAGIC0xcff1 || cth.cth_version != CTF_VERSION2)
286 return 0;
287
288 dlen = cth.cth_stroff + cth.cth_strlen;
289 if (dlen > filesize && !(cth.cth_flags & CTF_F_COMPRESS(1 << 0))) {
290 warnx("bogus file size");
291 return 0;
292 }
293
294 if ((cth.cth_lbloff & 3) || (cth.cth_objtoff & 1) ||
295 (cth.cth_funcoff & 1) || (cth.cth_typeoff & 3)) {
296 warnx("wrongly aligned offset");
297 return 0;
298 }
299
300 if ((cth.cth_lbloff >= dlen) || (cth.cth_objtoff >= dlen) ||
301 (cth.cth_funcoff >= dlen) || (cth.cth_typeoff >= dlen)) {
302 warnx("truncated file");
303 return 0;
304 }
305
306 if ((cth.cth_lbloff > cth.cth_objtoff) ||
307 (cth.cth_objtoff > cth.cth_funcoff) ||
308 (cth.cth_funcoff > cth.cth_typeoff) ||
309 (cth.cth_typeoff > cth.cth_stroff)) {
310 warnx("corrupted file");
311 return 0;
312 }
313
314 return 1;
315}
316
317int
318ctf_dump(const char *p, size_t size, uint8_t flags)
319{
320 struct ctf_header cth;
321 size_t dlen;
322 char *data;
323
324 memcpy(&cth, p, sizeof(struct ctf_header));
325 dlen = cth.cth_stroff + cth.cth_strlen;
326 if (cth.cth_flags & CTF_F_COMPRESS(1 << 0)) {
327 data = decompress(p + sizeof(cth), size - sizeof(cth), dlen);
328 if (data == NULL((void *)0))
329 return 1;
330 } else {
331 data = (char *)p + sizeof(cth);
332 }
333
334 if (flags & DUMP_HEADER(1 << 2)) {
335 printf(" cth_magic = 0x%04x\n", cth.cth_magic);
336 printf(" cth_version = %u\n", cth.cth_version);
337 printf(" cth_flags = 0x%02x\n", cth.cth_flags);
338 printf(" cth_parlabel = %s\n",
339 ctf_off2name(&cth, data, dlen, cth.cth_parlabel));
340 printf(" cth_parname = %s\n",
341 ctf_off2name(&cth, data, dlen, cth.cth_parname));
342 printf(" cth_lbloff = %u\n", cth.cth_lbloff);
343 printf(" cth_objtoff = %u\n", cth.cth_objtoff);
344 printf(" cth_funcoff = %u\n", cth.cth_funcoff);
345 printf(" cth_typeoff = %u\n", cth.cth_typeoff);
346 printf(" cth_stroff = %u\n", cth.cth_stroff);
347 printf(" cth_strlen = %u\n", cth.cth_strlen);
348 printf("\n");
349 }
350
351 if (flags & DUMP_LABEL(1 << 3)) {
352 uint32_t lbloff = cth.cth_lbloff;
353 struct ctf_lblent *ctl;
354
355 while (lbloff < cth.cth_objtoff) {
356 ctl = (struct ctf_lblent *)(data + lbloff);
357
358 printf(" %5u %s\n", ctl->ctl_typeidx,
359 ctf_off2name(&cth, data, dlen, ctl->ctl_label));
360
361 lbloff += sizeof(*ctl);
362 }
363 printf("\n");
364 }
365
366 if (flags & DUMP_OBJECT(1 << 0)) {
367 uint32_t objtoff = cth.cth_objtoff;
368 size_t idx = 0, i = 0;
369 uint16_t *dsp;
370 const char *s;
371 int l;
372
373 while (objtoff < cth.cth_funcoff) {
374 dsp = (uint16_t *)(data + objtoff);
375
376 l = printf(" [%zu] %u", i++, *dsp);
377 if ((s = elf_idx2sym(&idx, STT_OBJECT1)) != NULL((void *)0))
378 printf("%*s %s (%zu)\n", (14 - l), "", s, idx);
379 else
380 printf("\n");
381
382 objtoff += sizeof(*dsp);
383 }
384 printf("\n");
385 }
386
387 if (flags & DUMP_FUNCTION(1 << 1)) {
388 uint16_t *fsp, kind, vlen;
389 uint16_t *fstart, *fend;
390 size_t idx = 0, i = -1;
391 const char *s;
392 int l;
393
394 fstart = (uint16_t *)(data + cth.cth_funcoff);
395 fend = (uint16_t *)(data + cth.cth_typeoff);
396
397 fsp = fstart;
398 while (fsp < fend) {
399 kind = CTF_INFO_KIND(*fsp)(((*fsp) & 0xf800) >> 11);
400 vlen = CTF_INFO_VLEN(*fsp)(((*fsp) & 0x03ff));
401 s = elf_idx2sym(&idx, STT_FUNC2);
402 fsp++;
403 i++;
404
405 if (kind == CTF_K_UNKNOWN0 && vlen == 0)
406 continue;
407
408 l = printf(" [%zu] FUNC ", i);
Value stored to 'l' is never read
409 if (s != NULL((void *)0))
410 printf("(%s) ", s);
411 printf("returns: %u args: (", *fsp++);
412 while (vlen-- > 0 && fsp < fend)
413 printf("%u%s", *fsp++, (vlen > 0) ? ", " : "");
414 printf(")\n");
415 }
416 printf("\n");
417 }
418
419 if (flags & DUMP_TYPE(1 << 6)) {
420 uint32_t idx = 1, offset = cth.cth_typeoff;
421 uint32_t stroff = cth.cth_stroff;
422
423 while (offset < stroff) {
424 ctf_dump_type(&cth, data, dlen, stroff, &offset, idx++);
425 }
426 printf("\n");
427 }
428
429 if (flags & DUMP_STRTAB(1 << 4)) {
430 uint32_t offset = 0;
431 const char *str;
432
433 while (offset < cth.cth_strlen) {
434 str = ctf_off2name(&cth, data, dlen, offset);
435
436 printf(" [%u] ", offset);
437 if (strcmp(str, "(anon)"))
438 offset += printf("%s\n", str);
439 else {
440 printf("\\0\n");
441 offset++;
442 }
443 }
444 printf("\n");
445 }
446
447 if (cth.cth_flags & CTF_F_COMPRESS(1 << 0))
448 free(data);
449
450 return 0;
451}
452
453void
454ctf_dump_type(struct ctf_header *cth, const char *data, size_t dlen,
455 uint32_t stroff, uint32_t *offset, uint32_t idx)
456{
457 const char *p = data + *offset;
458 const struct ctf_type *ctt = (struct ctf_type *)p;
459 const struct ctf_array *cta;
460 uint16_t *argp, i, kind, vlen, root;
461 uint32_t eob, toff;
462 uint64_t size;
463 const char *name, *kname;
464
465 kind = CTF_INFO_KIND(ctt->ctt_info)(((ctt->_ctt_stype.cts_info) & 0xf800) >> 11);
466 vlen = CTF_INFO_VLEN(ctt->ctt_info)(((ctt->_ctt_stype.cts_info) & 0x03ff));
467 root = CTF_INFO_ISROOT(ctt->ctt_info)(((ctt->_ctt_stype.cts_info) & 0x0400) >> 10);
468 name = ctf_off2name(cth, data, dlen, ctt->ctt_name_ctt_stype.cts_name);
469
470 if (root)
471 printf(" <%u> ", idx);
472 else
473 printf(" [%u] ", idx);
474
475 if ((kname = ctf_kind2name(kind)) != NULL((void *)0))
476 printf("%s %s", kname, name);
477
478 if (ctt->ctt_size_ctt_stype._ST._size <= CTF_MAX_SIZE0xfffe) {
479 size = ctt->ctt_size_ctt_stype._ST._size;
480 toff = sizeof(struct ctf_stype);
481 } else {
482 size = CTF_TYPE_LSIZE(ctt)(((uint64_t)(ctt)->ctt_lsizehi) << 32 | (ctt)->ctt_lsizelo
)
;
483 toff = sizeof(struct ctf_type);
484 }
485
486 switch (kind) {
487 case CTF_K_UNKNOWN0:
488 case CTF_K_FORWARD9:
489 break;
490 case CTF_K_INTEGER1:
491 eob = *((uint32_t *)(p + toff));
492 toff += sizeof(uint32_t);
493 printf(" encoding=%s offset=%u bits=%u",
494 ctf_enc2name(CTF_INT_ENCODING(eob)(((eob) & 0xff000000) >> 24)), CTF_INT_OFFSET(eob)(((eob) & 0x00ff0000) >> 16),
495 CTF_INT_BITS(eob)(((eob) & 0x0000ffff)));
496 break;
497 case CTF_K_FLOAT2:
498 eob = *((uint32_t *)(p + toff));
499 toff += sizeof(uint32_t);
500 printf(" encoding=%s offset=%u bits=%u",
501 ctf_fpenc2name(CTF_FP_ENCODING(eob)(((eob) & 0xff000000) >> 24)), CTF_FP_OFFSET(eob)(((eob) & 0x00ff0000) >> 16),
502 CTF_FP_BITS(eob)(((eob) & 0x0000ffff)));
503 break;
504 case CTF_K_ARRAY4:
505 cta = (struct ctf_array *)(p + toff);
506 printf(" content: %u index: %u nelems: %u\n", cta->cta_contents,
507 cta->cta_index, cta->cta_nelems);
508 toff += sizeof(struct ctf_array);
509 break;
510 case CTF_K_FUNCTION5:
511 argp = (uint16_t *)(p + toff);
512 printf(" returns: %u args: (%u", ctt->ctt_type_ctt_stype._ST._type, *argp);
513 for (i = 1; i < vlen; i++) {
514 argp++;
515 if ((const char *)argp > data + dlen)
516 errx(1, "offset exceeds CTF section");
517
518 printf(", %u", *argp);
519 }
520 printf(")");
521 toff += (vlen + (vlen & 1)) * sizeof(uint16_t);
522 break;
523 case CTF_K_STRUCT6:
524 case CTF_K_UNION7:
525 printf(" (%llu bytes)\n", size);
526
527 if (size < CTF_LSTRUCT_THRESH8192) {
528 for (i = 0; i < vlen; i++) {
529 struct ctf_member *ctm;
530
531 if (p + toff > data + dlen)
532 errx(1, "offset exceeds CTF section");
533
534 if (toff > (stroff - sizeof(*ctm)))
535 break;
536
537 ctm = (struct ctf_member *)(p + toff);
538 toff += sizeof(struct ctf_member);
539
540 printf("\t%s type=%u off=%u\n",
541 ctf_off2name(cth, data, dlen,
542 ctm->ctm_name),
543 ctm->ctm_type, ctm->ctm_offset);
544 }
545 } else {
546 for (i = 0; i < vlen; i++) {
547 struct ctf_lmember *ctlm;
548
549 if (p + toff > data + dlen)
550 errx(1, "offset exceeds CTF section");
551
552 if (toff > (stroff - sizeof(*ctlm)))
553 break;
554
555 ctlm = (struct ctf_lmember *)(p + toff);
556 toff += sizeof(struct ctf_lmember);
557
558 printf("\t%s type=%u off=%llu\n",
559 ctf_off2name(cth, data, dlen,
560 ctlm->ctlm_name_ctlm_member.ctm_name),
561 ctlm->ctlm_type_ctlm_member.ctm_type, CTF_LMEM_OFFSET(ctlm)(((uint64_t)(ctlm)->ctlm_offsethi) << 32 | (ctlm)->
ctlm_offsetlo)
);
562 }
563 }
564 break;
565 case CTF_K_ENUM8:
566 printf("\n");
567 for (i = 0; i < vlen; i++) {
568 struct ctf_enum *cte;
569
570 if (p + toff > data + dlen)
571 errx(1, "offset exceeds CTF section");
572
573 if (toff > (stroff - sizeof(*cte)))
574 break;
575
576 cte = (struct ctf_enum *)(p + toff);
577 toff += sizeof(struct ctf_enum);
578
579 printf("\t%s = %d\n",
580 ctf_off2name(cth, data, dlen, cte->cte_name),
581 cte->cte_value);
582 }
583 break;
584 case CTF_K_POINTER3:
585 case CTF_K_TYPEDEF10:
586 case CTF_K_VOLATILE11:
587 case CTF_K_CONST12:
588 case CTF_K_RESTRICT13:
589 printf(" refers to %u", ctt->ctt_type_ctt_stype._ST._type);
590 break;
591 default:
592 errx(1, "incorrect type %u at offset %u", kind, *offset);
593 }
594
595 printf("\n");
596
597 *offset += toff;
598}
599
600const char *
601ctf_kind2name(uint16_t kind)
602{
603 static const char *kind_name[] = { NULL((void *)0), "INTEGER", "FLOAT", "POINTER",
604 "ARRAY", "FUNCTION", "STRUCT", "UNION", "ENUM", "FORWARD",
605 "TYPEDEF", "VOLATILE", "CONST", "RESTRICT" };
606
607 if (kind >= nitems(kind_name)(sizeof((kind_name)) / sizeof((kind_name)[0])))
608 return NULL((void *)0);
609
610 return kind_name[kind];
611}
612
613const char *
614ctf_enc2name(uint16_t enc)
615{
616 static const char *enc_name[] = { "SIGNED", "CHAR", "SIGNED CHAR",
617 "BOOL", "SIGNED BOOL" };
618 static char invalid[7];
619
620 if (enc == CTF_INT_VARARGS(1 << 3))
621 return "VARARGS";
622
623 if (enc > 0 && enc <= nitems(enc_name)(sizeof((enc_name)) / sizeof((enc_name)[0])))
624 return enc_name[enc - 1];
625
626 snprintf(invalid, sizeof(invalid), "0x%x", enc);
627 return invalid;
628}
629
630const char *
631ctf_fpenc2name(uint16_t enc)
632{
633 static const char *enc_name[] = { "SINGLE", "DOUBLE", NULL((void *)0), NULL((void *)0),
634 NULL((void *)0), "LDOUBLE" };
635 static char invalid[7];
636
637 if (enc > 0 && enc <= nitems(enc_name)(sizeof((enc_name)) / sizeof((enc_name)[0])) && enc_name[enc - 1] != NULL((void *)0))
638 return enc_name[enc - 1];
639
640 snprintf(invalid, sizeof(invalid), "0x%x", enc);
641 return invalid;
642}
643
644const char *
645ctf_off2name(struct ctf_header *cth, const char *data, size_t dlen,
646 uint32_t offset)
647{
648 const char *name;
649
650 if (CTF_NAME_STID(offset)((offset) >> 31) != CTF_STRTAB_00)
651 return "external";
652
653 if (CTF_NAME_OFFSET(offset)((offset) & 0x7fffffff) >= cth->cth_strlen)
654 return "exceeds strlab";
655
656 if (cth->cth_stroff + CTF_NAME_OFFSET(offset)((offset) & 0x7fffffff) >= dlen)
657 return "invalid";
658
659 name = data + cth->cth_stroff + CTF_NAME_OFFSET(offset)((offset) & 0x7fffffff);
660 if (*name == '\0')
661 return "(anon)";
662
663 return name;
664}
665
666char *
667decompress(const char *buf, size_t size, size_t len)
668{
669#ifdef ZLIB1
670 z_stream stream;
671 char *data;
672 int error;
673
674 data = malloc(len);
675 if (data == NULL((void *)0)) {
676 warn(NULL((void *)0));
677 return NULL((void *)0);
678 }
679
680 memset(&stream, 0, sizeof(stream));
681 stream.next_in = (void *)buf;
682 stream.avail_in = size;
683 stream.next_out = (uint8_t *)data;
684 stream.avail_out = len;
685
686 if ((error = inflateInit(&stream)inflateInit_((&stream), "1.3.0.1-motley", (int)sizeof(z_stream
))
) != Z_OK0) {
687 warnx("zlib inflateInit failed: %s", zError(error));
688 goto exit;
689 }
690
691 if ((error = inflate(&stream, Z_FINISH4)) != Z_STREAM_END1) {
692 warnx("zlib inflate failed: %s", zError(error));
693 inflateEnd(&stream);
694 goto exit;
695 }
696
697 if ((error = inflateEnd(&stream)) != Z_OK0) {
698 warnx("zlib inflateEnd failed: %s", zError(error));
699 goto exit;
700 }
701
702 if (stream.total_out != len) {
703 warnx("decompression failed: %lu != %zu",
704 stream.total_out, len);
705 goto exit;
706 }
707
708 return data;
709
710exit:
711 free(data);
712#endif /* ZLIB */
713 return NULL((void *)0);
714}
715
716__dead__attribute__((__noreturn__)) void
717usage(void)
718{
719 fprintf(stderr(&__sF[2]), "usage: %s [-dfhlst] file ...\n",
720 getprogname());
721 exit(1);
722}