Bug Summary

File:ddb/db_elf.c
Warning:line 67, column 8
Value stored to 'errstr' during its initialization 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 db_elf.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 static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -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 -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/ddb/db_elf.c
1/* $OpenBSD: db_elf.c,v 1.32 2021/03/12 10:22:46 jsg Exp $ */
2/* $NetBSD: db_elf.c,v 1.13 2000/07/07 21:55:18 jhawk Exp $ */
3
4/*-
5 * Copyright (c) 1997 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10 * NASA Ames Research Center.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <sys/param.h>
35#include <sys/stdint.h>
36#include <sys/systm.h>
37#include <sys/exec.h>
38
39#include <machine/db_machdep.h>
40
41#include <ddb/db_elf.h>
42#include <ddb/db_sym.h>
43#include <ddb/db_output.h>
44
45#include <sys/exec_elf.h>
46
47db_symtab_t db_symtab;
48
49Elf_SymElf64_Sym *db_elf_sym_lookup(char *);
50
51/*
52 * Find the symbol table and strings; tell ddb about them.
53 *
54 * symsize: size of symbol table
55 * symtab: pointer to start of symbol table
56 * esymtab: pointer to end of string table, for checking - rounded up to
57 * integer boundary
58 */
59int
60db_elf_sym_init(int symsize, void *symtab, void *esymtab, const char *name)
61{
62 Elf_EhdrElf64_Ehdr *elf;
63 Elf_ShdrElf64_Shdr *shp;
64 Elf_SymElf64_Sym *symp, *symtab_start, *symtab_end;
65 char *shstrtab, *strtab_start, *strtab_end;
66 int i;
67 char *errstr = "";
Value stored to 'errstr' during its initialization is never read
68
69 if (ALIGNED_POINTER(symtab, long)1 == 0) {
70 db_printf("[ %s symbol table has bad start address %p ]\n",
71 name, symtab);
72 return (0);
73 }
74
75 symtab_start = symtab_end = NULL((void *)0);
76 strtab_start = strtab_end = NULL((void *)0);
77
78 /*
79 * The format of the symbols loaded by the boot program is:
80 *
81 * Elf exec header
82 * first section header
83 * . . .
84 * . . .
85 * last section header
86 * first symbol, string, or line table section
87 * . . .
88 * . . .
89 * last symbol, string, or line table section
90 */
91
92 /*
93 * Validate the Elf header.
94 */
95 elf = (Elf_EhdrElf64_Ehdr *)symtab;
96 if (memcmp(elf->e_ident, ELFMAG, SELFMAG)__builtin_memcmp((elf->e_ident), ("\177ELF"), (4)) != 0 ||
97 elf->e_ident[EI_CLASS4] != ELFCLASS2) {
98 errstr = "bad magic";
99 goto badheader;
100 }
101
102 if (elf->e_machine != ELF_TARG_MACH62) {
103 errstr = "bad e_machine";
104 goto badheader;
105 }
106
107 /*
108 * Find the section header string table (.shstrtab), and look up
109 * the symbol table (.symtab) and string table (.strtab) via their
110 * names in shstrtab, rather than by table type.
111 * This works in the presence of multiple string tables, such as
112 * stabs data found when booting bsd.gdb.
113 */
114 shp = (Elf_ShdrElf64_Shdr *)((char *)symtab + elf->e_shoff);
115 shstrtab = (char *)symtab + shp[elf->e_shstrndx].sh_offset;
116 for (i = 0; i < elf->e_shnum; i++) {
117 if (shp[i].sh_type == SHT_SYMTAB2) {
118 int j;
119
120 if (shp[i].sh_offset == 0)
121 continue;
122 symtab_start = (Elf_SymElf64_Sym *)((char *)symtab +
123 shp[i].sh_offset);
124 symtab_end = (Elf_SymElf64_Sym *)((char *)symtab +
125 shp[i].sh_offset + shp[i].sh_size);
126 j = shp[i].sh_link;
127 if (shp[j].sh_offset == 0)
128 continue;
129 strtab_start = (char *)symtab + shp[j].sh_offset;
130 strtab_end = (char *)symtab + shp[j].sh_offset +
131 shp[j].sh_size;
132 break;
133 }
134
135 /*
136 * This is the old way of doing things.
137 * XXX - verify that it's not needed.
138 */
139 if (strcmp(".strtab", shstrtab+shp[i].sh_name) == 0) {
140 strtab_start = (char *)symtab + shp[i].sh_offset;
141 strtab_end = (char *)symtab + shp[i].sh_offset +
142 shp[i].sh_size;
143 } else if (strcmp(".symtab", shstrtab+shp[i].sh_name) == 0) {
144 symtab_start = (Elf_SymElf64_Sym *)((char *)symtab +
145 shp[i].sh_offset);
146 symtab_end = (Elf_SymElf64_Sym *)((char *)symtab +
147 shp[i].sh_offset + shp[i].sh_size);
148 }
149 }
150
151 /*
152 * Now, sanity check the symbols against the string table.
153 */
154 if (symtab_start == NULL((void *)0) || strtab_start == NULL((void *)0) ||
155 ALIGNED_POINTER(symtab_start, long)1 == 0) {
156 errstr = "symtab unaligned";
157 goto badheader;
158 }
159 for (symp = symtab_start; symp < symtab_end; symp++)
160 if (symp->st_name + strtab_start > strtab_end) {
161 errstr = "symtab corrupted";
162 goto badheader;
163 }
164
165 /*
166 * Link the symbol table into the debugger.
167 */
168 db_symtab.start = (char *)symtab_start;
169 db_symtab.end = (char *)symtab_end;
170 db_symtab.name = name;
171 db_symtab.private = (char *)symtab;
172
173 db_printf("[ using %lu bytes of %s ELF symbol table ]\n",
174 (u_long)roundup(((char *)esymtab - (char *)symtab), sizeof(u_long))((((((char *)esymtab - (char *)symtab))+((sizeof(u_long))-1))
/(sizeof(u_long)))*(sizeof(u_long)))
,
175 name);
176
177 return (1);
178
179 badheader:
180 db_printf("[ %s ELF symbol table not valid: %s ]\n", name, errstr);
181 return (0);
182}
183
184/*
185 * Internal helper function - return a pointer to the string table
186 * for the current symbol table.
187 */
188char *
189db_elf_find_strtab(db_symtab_t *stab)
190{
191 Elf_EhdrElf64_Ehdr *elf = STAB_TO_EHDR(stab)((Elf64_Ehdr *)((stab)->private));
192 Elf_ShdrElf64_Shdr *shp = STAB_TO_SHDR(stab, elf)((Elf64_Shdr *)((stab)->private + (elf)->e_shoff));
193 char *shstrtab;
194 int i;
195
196 shstrtab = (char *)elf + shp[elf->e_shstrndx].sh_offset;
197 for (i = 0; i < elf->e_shnum; i++) {
198 if (shp[i].sh_type == SHT_SYMTAB2)
199 return ((char *)elf + shp[shp[i].sh_link].sh_offset);
200 if (strcmp(".strtab", shstrtab+shp[i].sh_name) == 0)
201 return ((char *)elf + shp[i].sh_offset);
202 }
203
204 return (NULL((void *)0));
205}
206
207/*
208 * Internal helper function - return a pointer to the section
209 * named ``sname''.
210 */
211const char *
212db_elf_find_section(db_symtab_t *stab, size_t *size, const char *sname)
213{
214 Elf_EhdrElf64_Ehdr *elf = STAB_TO_EHDR(stab)((Elf64_Ehdr *)((stab)->private));
215 Elf_ShdrElf64_Shdr *shp = STAB_TO_SHDR(stab, elf)((Elf64_Shdr *)((stab)->private + (elf)->e_shoff));
216 char *shstrtab;
217 int i;
218
219 shstrtab = (char *)elf + shp[elf->e_shstrndx].sh_offset;
220 for (i = 0; i < elf->e_shnum; i++) {
221 if ((shp[i].sh_flags & SHF_ALLOC0x2) != 0 &&
222 strcmp(sname, shstrtab+shp[i].sh_name) == 0) {
223 *size = shp[i].sh_size;
224 return ((char *)elf + shp[i].sh_offset);
225 }
226 }
227
228 return (NULL((void *)0));
229}
230
231/*
232 * Lookup the symbol with the given name.
233 */
234Elf_SymElf64_Sym *
235db_elf_sym_lookup(char *symstr)
236{
237 db_symtab_t *stab = &db_symtab;
238 Elf_SymElf64_Sym *symp, *symtab_start, *symtab_end;
239 char *strtab;
240
241 if (stab->private == NULL((void *)0))
242 return (NULL((void *)0));
243
244 symtab_start = STAB_TO_SYMSTART(stab)((Elf64_Sym *)((stab)->start));
245 symtab_end = STAB_TO_SYMEND(stab)((Elf64_Sym *)((stab)->end));
246
247 strtab = db_elf_find_strtab(stab);
248 if (strtab == NULL((void *)0))
249 return (NULL((void *)0));
250
251 for (symp = symtab_start; symp < symtab_end; symp++) {
252 if (symp->st_name != 0 &&
253 db_eqname(strtab + symp->st_name, symstr, 0))
254 return (symp);
255 }
256
257 return (NULL((void *)0));
258}
259
260/*
261 * Search for the symbol with the given address (matching within the
262 * provided threshold).
263 */
264Elf_SymElf64_Sym *
265db_elf_sym_search(vaddr_t off, db_strategy_t strategy, db_expr_t *diffp)
266{
267 db_symtab_t *stab = &db_symtab;
268 Elf_SymElf64_Sym *rsymp, *symp, *symtab_start, *symtab_end;
269 db_expr_t diff = *diffp;
270
271 if (stab->private == NULL((void *)0))
272 return (NULL((void *)0));
273
274 symtab_start = STAB_TO_SYMSTART(stab)((Elf64_Sym *)((stab)->start));
275 symtab_end = STAB_TO_SYMEND(stab)((Elf64_Sym *)((stab)->end));
276
277 rsymp = NULL((void *)0);
278
279 for (symp = symtab_start; symp < symtab_end; symp++) {
280 if (symp->st_name == 0)
281 continue;
282#if 0
283 /* This prevents me from seeing anythin in locore.s -- eeh */
284 if (ELF_SYM_TYPE(symp->st_info) != Elf_estt_object &&
285 ELF_SYM_TYPE(symp->st_info) != Elf_estt_func)
286 continue;
287#endif
288
289 if (off >= symp->st_value) {
290 if ((off - symp->st_value) < diff) {
291 diff = off - symp->st_value;
292 rsymp = symp;
293 if (diff == 0) {
294 if (strategy == DB_STGY_PROC2 &&
295 ELF_ST_TYPE(symp->st_info)(((unsigned int) symp->st_info) & 0xf)
296 == STT_FUNC2 &&
297 ELF_ST_BIND(symp->st_info)((symp->st_info) >> 4)
298 != STB_LOCAL0)
299 break;
300 if (strategy == DB_STGY_ANY0 &&
301 ELF_ST_BIND(symp->st_info)((symp->st_info) >> 4)
302 != STB_LOCAL0)
303 break;
304 }
305 } else if ((off - symp->st_value) == diff) {
306 if (rsymp == NULL((void *)0))
307 rsymp = symp;
308 else if (ELF_ST_BIND(rsymp->st_info)((rsymp->st_info) >> 4)
309 == STB_LOCAL0 &&
310 ELF_ST_BIND(symp->st_info)((symp->st_info) >> 4)
311 != STB_LOCAL0) {
312 /* pick the external symbol */
313 rsymp = symp;
314 }
315 }
316 }
317 }
318
319 if (rsymp == NULL((void *)0))
320 *diffp = off;
321 else
322 *diffp = diff;
323
324 return (rsymp);
325}
326
327/*
328 * Return the name and value for a symbol.
329 */
330void
331db_symbol_values(Elf_SymElf64_Sym *sym, char **namep, db_expr_t *valuep)
332{
333 db_symtab_t *stab = &db_symtab;
334 Elf_SymElf64_Sym *symp = (Elf_SymElf64_Sym *)sym;
335 char *strtab;
336
337 if (sym == NULL((void *)0)) {
338 *namep = NULL((void *)0);
339 return;
340 }
341
342 if (stab->private == NULL((void *)0))
343 return;
344
345 if (namep) {
346 strtab = db_elf_find_strtab(stab);
347 if (strtab == NULL((void *)0))
348 *namep = NULL((void *)0);
349 else
350 *namep = strtab + symp->st_name;
351 }
352
353 if (valuep)
354 *valuep = symp->st_value;
355}
356
357/*
358 * Return the file and line number of the current program counter
359 * if we can find the appropriate debugging symbol.
360 */
361int
362db_elf_line_at_pc(Elf_SymElf64_Sym *cursym, char **filename,
363 int *linenum, db_expr_t off)
364{
365 db_symtab_t *stab = &db_symtab;
366 static char path[PATH_MAX1024];
367 const char *linetab, *dirname, *basename;
368 size_t linetab_size;
369
370 if (stab->private == NULL((void *)0))
371 return (0);
372
373 linetab = db_elf_find_section(stab, &linetab_size, ".debug_line");
374 if (linetab == NULL((void *)0))
375 return (0);
376
377 if (!db_dwarf_line_at_pc(linetab, linetab_size, off,
378 &dirname, &basename, linenum))
379 return (0);
380
381 if (dirname == NULL((void *)0))
382 strlcpy(path, basename, sizeof(path));
383 else
384 snprintf(path, sizeof(path), "%s/%s", dirname, basename);
385 *filename = path;
386 return (1);
387}
388
389void
390db_elf_sym_forall(db_forall_func_t db_forall_func, void *arg)
391{
392 db_symtab_t *stab = &db_symtab;
393 char *strtab;
394 static char suffix[2];
395 Elf_SymElf64_Sym *symp, *symtab_start, *symtab_end;
396
397 if (stab->private == NULL((void *)0))
398 return;
399
400 symtab_start = STAB_TO_SYMSTART(stab)((Elf64_Sym *)((stab)->start));
401 symtab_end = STAB_TO_SYMEND(stab)((Elf64_Sym *)((stab)->end));
402
403 strtab = db_elf_find_strtab(stab);
404 if (strtab == NULL((void *)0))
405 return;
406
407 for (symp = symtab_start; symp < symtab_end; symp++)
408 if (symp->st_name != 0) {
409 suffix[1] = '\0';
410 switch (ELF_ST_TYPE(symp->st_info)(((unsigned int) symp->st_info) & 0xf)) {
411 case STT_OBJECT1:
412 suffix[0] = '+';
413 break;
414 case STT_FUNC2:
415 suffix[0] = '*';
416 break;
417 case STT_SECTION3:
418 suffix[0] = '&';
419 break;
420 case STT_FILE4:
421 suffix[0] = '/';
422 break;
423 default:
424 suffix[0] = '\0';
425 }
426 (*db_forall_func)(symp,
427 strtab + symp->st_name, suffix, 0, arg);
428 }
429}
430
431Elf_SymElf64_Sym *
432db_symbol_by_name(char *name, db_expr_t *valuep)
433{
434 Elf_SymElf64_Sym *sym;
435
436 sym = db_elf_sym_lookup(name);
437 if (sym == NULL((void *)0))
438 return (NULL((void *)0));
439 db_symbol_values(sym, &name, valuep);
440 return (sym);
441}