blob: 9d0fef2cf260116267678c0d47ab7ba099e11c47 [file] [log] [blame]
Brian Silverman86497922018-02-10 19:28:39 -05001/* Standard libdwfl callbacks for debugging the running Linux kernel.
2 Copyright (C) 2005-2011, 2013, 2014, 2015 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
7
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
11
12 or
13
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
28
29/* In case we have a bad fts we include this before config.h because it
30 can't handle _FILE_OFFSET_BITS.
31 Everything we need here is fine if its declarations just come first.
32 Also, include sys/types.h before fts. On some systems fts.h is not self
33 contained. */
34#ifdef BAD_FTS
35 #include <sys/types.h>
36 #include <fts.h>
37#endif
38
39#include <config.h>
40#include <system.h>
41
42#include "libdwflP.h"
43#include <inttypes.h>
44#include <errno.h>
45#include <stdio.h>
46#include <stdio_ext.h>
47#include <string.h>
48#include <stdlib.h>
49#include <sys/utsname.h>
50#include <fcntl.h>
51#include <unistd.h>
52
53/* If fts.h is included before config.h, its indirect inclusions may not
54 give us the right LFS aliases of these functions, so map them manually. */
55#ifdef BAD_FTS
56 #ifdef _FILE_OFFSET_BITS
57 #define open open64
58 #define fopen fopen64
59 #endif
60#else
61 #include <sys/types.h>
62 #include <fts.h>
63#endif
64
65
66#define KERNEL_MODNAME "kernel"
67
68#define MODULEDIRFMT "/lib/modules/%s"
69
70#define KNOTESFILE "/sys/kernel/notes"
71#define MODNOTESFMT "/sys/module/%s/notes"
72#define KSYMSFILE "/proc/kallsyms"
73#define MODULELIST "/proc/modules"
74#define SECADDRDIRFMT "/sys/module/%s/sections/"
75#define MODULE_SECT_NAME_LEN 32 /* Minimum any linux/module.h has had. */
76
77
78static const char *vmlinux_suffixes[] =
79 {
80 ".gz",
81#ifdef USE_BZLIB
82 ".bz2",
83#endif
84#ifdef USE_LZMA
85 ".xz",
86#endif
87 };
88
89/* Try to open the given file as it is or under the debuginfo directory. */
90static int
91try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug)
92{
93 if (*fname == NULL)
94 return -1;
95
96 /* Don't bother trying *FNAME itself here if the path will cause it to be
97 tried because we give its own basename as DEBUGLINK_FILE. */
98 int fd = ((((dwfl->callbacks->debuginfo_path
99 ? *dwfl->callbacks->debuginfo_path : NULL)
100 ?: DEFAULT_DEBUGINFO_PATH)[0] == ':') ? -1
101 : TEMP_FAILURE_RETRY (open (*fname, O_RDONLY)));
102
103 if (fd < 0)
104 {
105 Dwfl_Module fakemod = { .dwfl = dwfl };
106
107 if (try_debug)
108 /* Passing NULL for DEBUGLINK_FILE searches for both the basenamer
109 "vmlinux" and the default of basename + ".debug", to look for
110 "vmlinux.debug" files. */
111 fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
112 *fname, NULL, 0,
113 &fakemod.debug.name);
114 else
115 /* Try the file's unadorned basename as DEBUGLINK_FILE,
116 to look only for "vmlinux" files. */
117 fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
118 *fname, basename (*fname),
119 0, &fakemod.debug.name);
120
121 if (fakemod.debug.name != NULL)
122 {
123 free (*fname);
124 *fname = fakemod.debug.name;
125 }
126 }
127
128 if (fd < 0)
129 for (size_t i = 0;
130 i < sizeof vmlinux_suffixes / sizeof vmlinux_suffixes[0];
131 ++i)
132 {
133 char *zname;
134 if (asprintf (&zname, "%s%s", *fname, vmlinux_suffixes[i]) > 0)
135 {
136 fd = TEMP_FAILURE_RETRY (open (zname, O_RDONLY));
137 if (fd < 0)
138 free (zname);
139 else
140 {
141 free (*fname);
142 *fname = zname;
143 }
144 }
145 }
146
147 if (fd < 0)
148 {
149 free (*fname);
150 *fname = NULL;
151 }
152
153 return fd;
154}
155
156static inline const char *
157kernel_release (void)
158{
159#ifdef __linux__
160 /* Cache the `uname -r` string we'll use. */
161 static struct utsname utsname;
162 if (utsname.release[0] == '\0' && uname (&utsname) != 0)
163 return NULL;
164 return utsname.release;
165#else
166 /* Used for finding the running linux kernel, which isn't supported
167 on non-linux kernel systems. */
168 errno = ENOTSUP;
169 return NULL;
170#endif
171}
172
173static int
174find_kernel_elf (Dwfl *dwfl, const char *release, char **fname)
175{
176 if ((release[0] == '/'
177 ? asprintf (fname, "%s/vmlinux", release)
178 : asprintf (fname, "/boot/vmlinux-%s", release)) < 0)
179 return -1;
180
181 int fd = try_kernel_name (dwfl, fname, true);
182 if (fd < 0 && release[0] != '/')
183 {
184 free (*fname);
185 if (asprintf (fname, MODULEDIRFMT "/vmlinux", release) < 0)
186 return -1;
187 fd = try_kernel_name (dwfl, fname, true);
188 }
189
190 return fd;
191}
192
193static int
194get_release (Dwfl *dwfl, const char **release)
195{
196 if (dwfl == NULL)
197 return -1;
198
199 const char *release_string = release == NULL ? NULL : *release;
200 if (release_string == NULL)
201 {
202 release_string = kernel_release ();
203 if (release_string == NULL)
204 return errno;
205 if (release != NULL)
206 *release = release_string;
207 }
208
209 return 0;
210}
211
212static int
213report_kernel (Dwfl *dwfl, const char **release,
214 int (*predicate) (const char *module, const char *file))
215{
216 int result = get_release (dwfl, release);
217 if (unlikely (result != 0))
218 return result;
219
220 char *fname;
221 int fd = find_kernel_elf (dwfl, *release, &fname);
222
223 if (fd < 0)
224 result = ((predicate != NULL && !(*predicate) (KERNEL_MODNAME, NULL))
225 ? 0 : errno ?: ENOENT);
226 else
227 {
228 bool report = true;
229
230 if (predicate != NULL)
231 {
232 /* Let the predicate decide whether to use this one. */
233 int want = (*predicate) (KERNEL_MODNAME, fname);
234 if (want < 0)
235 result = errno;
236 report = want > 0;
237 }
238
239 if (report)
240 {
241 /* Note that on some architectures (e.g. x86_64) the vmlinux
242 is ET_EXEC, while on others (e.g. ppc64) it is ET_DYN.
243 In both cases the phdr p_vaddr load address will be non-zero.
244 We want the image to be placed as if it was ET_DYN, so
245 pass true for add_p_vaddr which will do the right thing
246 (in combination with a zero base) in either case. */
247 Dwfl_Module *mod = INTUSE(dwfl_report_elf) (dwfl, KERNEL_MODNAME,
248 fname, fd, 0, true);
249 if (mod == NULL)
250 result = -1;
251 else
252 /* The kernel is ET_EXEC, but always treat it as relocatable. */
253 mod->e_type = ET_DYN;
254 }
255
256 free (fname);
257
258 if (!report || result < 0)
259 close (fd);
260 }
261
262 return result;
263}
264
265/* Look for a kernel debug archive. If we find one, report all its modules.
266 If not, return ENOENT. */
267static int
268report_kernel_archive (Dwfl *dwfl, const char **release,
269 int (*predicate) (const char *module, const char *file))
270{
271 int result = get_release (dwfl, release);
272 if (unlikely (result != 0))
273 return result;
274
275 char *archive;
276 int res = (((*release)[0] == '/')
277 ? asprintf (&archive, "%s/debug.a", *release)
278 : asprintf (&archive, MODULEDIRFMT "/debug.a", *release));
279 if (unlikely (res < 0))
280 return ENOMEM;
281
282 int fd = try_kernel_name (dwfl, &archive, false);
283 if (fd < 0)
284 result = errno ?: ENOENT;
285 else
286 {
287 /* We have the archive file open! */
288 Dwfl_Module *last = __libdwfl_report_offline (dwfl, NULL, archive, fd,
289 true, predicate);
290 if (unlikely (last == NULL))
291 result = -1;
292 else
293 {
294 /* Find the kernel and move it to the head of the list. */
295 Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp;
296 for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next))
297 if (!m->gc && m->e_type != ET_REL && !strcmp (m->name, "kernel"))
298 {
299 *prevp = m->next;
300 m->next = *tailp;
301 *tailp = m;
302 break;
303 }
304 }
305 }
306
307 free (archive);
308 return result;
309}
310
311static size_t
312check_suffix (const FTSENT *f, size_t namelen)
313{
314#define TRY(sfx) \
315 if ((namelen ? f->fts_namelen == namelen + sizeof sfx - 1 \
316 : f->fts_namelen >= sizeof sfx) \
317 && !memcmp (f->fts_name + f->fts_namelen - (sizeof sfx - 1), \
318 sfx, sizeof sfx)) \
319 return sizeof sfx - 1
320
321 TRY (".ko");
322 TRY (".ko.gz");
323#if USE_BZLIB
324 TRY (".ko.bz2");
325#endif
326#if USE_LZMA
327 TRY (".ko.xz");
328#endif
329
330 return 0;
331
332#undef TRY
333}
334
335/* Report a kernel and all its modules found on disk, for offline use.
336 If RELEASE starts with '/', it names a directory to look in;
337 if not, it names a directory to find under /lib/modules/;
338 if null, /lib/modules/`uname -r` is used.
339 Returns zero on success, -1 if dwfl_report_module failed,
340 or an errno code if finding the files on disk failed. */
341int
342dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release,
343 int (*predicate) (const char *module,
344 const char *file))
345{
346 int result = report_kernel_archive (dwfl, &release, predicate);
347 if (result != ENOENT)
348 return result;
349
350 /* First report the kernel. */
351 result = report_kernel (dwfl, &release, predicate);
352 if (result == 0)
353 {
354 /* Do "find /lib/modules/RELEASE -name *.ko". */
355
356 char *modulesdir[] = { NULL, NULL };
357 if (release[0] == '/')
358 modulesdir[0] = (char *) release;
359 else
360 {
361 if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0)
362 return errno;
363 }
364
365 FTS *fts = fts_open (modulesdir, FTS_NOSTAT | FTS_LOGICAL, NULL);
366 if (modulesdir[0] == (char *) release)
367 modulesdir[0] = NULL;
368 if (fts == NULL)
369 {
370 free (modulesdir[0]);
371 return errno;
372 }
373
374 FTSENT *f;
375 while ((f = fts_read (fts)) != NULL)
376 {
377 /* Skip a "source" subtree, which tends to be large.
378 This insane hard-coding of names is what depmod does too. */
379 if (f->fts_namelen == sizeof "source" - 1
380 && !strcmp (f->fts_name, "source"))
381 {
382 fts_set (fts, f, FTS_SKIP);
383 continue;
384 }
385
386 switch (f->fts_info)
387 {
388 case FTS_F:
389 case FTS_SL:
390 case FTS_NSOK:;
391 /* See if this file name matches "*.ko". */
392 const size_t suffix = check_suffix (f, 0);
393 if (suffix)
394 {
395 /* We have a .ko file to report. Following the algorithm
396 by which the kernel makefiles set KBUILD_MODNAME, we
397 replace all ',' or '-' with '_' in the file name and
398 call that the module name. Modules could well be
399 built using different embedded names than their file
400 names. To handle that, we would have to look at the
401 __this_module.name contents in the module's text. */
402
403 char *name = strndup (f->fts_name, f->fts_namelen - suffix);
404 if (unlikely (name == NULL))
405 {
406 __libdwfl_seterrno (DWFL_E_NOMEM);
407 result = -1;
408 break;
409 }
410 for (size_t i = 0; i < f->fts_namelen - suffix; ++i)
411 if (name[i] == '-' || name[i] == ',')
412 name[i] = '_';
413
414 if (predicate != NULL)
415 {
416 /* Let the predicate decide whether to use this one. */
417 int want = (*predicate) (name, f->fts_path);
418 if (want < 0)
419 {
420 result = -1;
421 free (name);
422 break;
423 }
424 if (!want)
425 {
426 free (name);
427 continue;
428 }
429 }
430
431 if (dwfl_report_offline (dwfl, name, f->fts_path, -1) == NULL)
432 {
433 free (name);
434 result = -1;
435 break;
436 }
437 free (name);
438 }
439 continue;
440
441 case FTS_ERR:
442 case FTS_DNR:
443 case FTS_NS:
444 result = f->fts_errno;
445 break;
446
447 case FTS_SLNONE:
448 default:
449 continue;
450 }
451
452 /* We only get here in error cases. */
453 break;
454 }
455 fts_close (fts);
456 free (modulesdir[0]);
457 }
458
459 return result;
460}
461INTDEF (dwfl_linux_kernel_report_offline)
462
463
464/* State of read_address used by intuit_kernel_bounds. */
465struct read_address_state {
466 FILE *f;
467 char *line;
468 size_t linesz;
469 size_t n;
470 char *p;
471 const char *type;
472};
473
474static inline bool
475read_address (struct read_address_state *state, Dwarf_Addr *addr)
476{
477 if ((state->n = getline (&state->line, &state->linesz, state->f)) < 1 ||
478 state->line[state->n - 2] == ']')
479 return false;
480 *addr = strtoull (state->line, &state->p, 16);
481 state->p += strspn (state->p, " \t");
482 state->type = strsep (&state->p, " \t\n");
483 if (state->type == NULL)
484 return false;
485 return state->p != NULL && state->p != state->line;
486}
487
488
489/* Grovel around to guess the bounds of the runtime kernel image. */
490static int
491intuit_kernel_bounds (Dwarf_Addr *start, Dwarf_Addr *end, Dwarf_Addr *notes)
492{
493 struct read_address_state state = { NULL, NULL, 0, 0, NULL, NULL };
494
495 state.f = fopen (KSYMSFILE, "r");
496 if (state.f == NULL)
497 return errno;
498
499 (void) __fsetlocking (state.f, FSETLOCKING_BYCALLER);
500
501 *notes = 0;
502
503 int result;
504 do
505 result = read_address (&state, start) ? 0 : -1;
506 while (result == 0 && strchr ("TtRr", *state.type) == NULL);
507
508 if (result == 0)
509 {
510 *end = *start;
511 while (read_address (&state, end))
512 if (*notes == 0 && !strcmp (state.p, "__start_notes\n"))
513 *notes = *end;
514
515 Dwarf_Addr round_kernel = sysconf (_SC_PAGESIZE);
516 *start &= -(Dwarf_Addr) round_kernel;
517 *end += round_kernel - 1;
518 *end &= -(Dwarf_Addr) round_kernel;
519 if (*start >= *end || *end - *start < round_kernel)
520 result = -1;
521 }
522 free (state.line);
523
524 if (result == -1)
525 result = ferror_unlocked (state.f) ? errno : ENOEXEC;
526
527 fclose (state.f);
528
529 return result;
530}
531
532
533/* Look for a build ID note in NOTESFILE and associate the ID with MOD. */
534static int
535check_notes (Dwfl_Module *mod, const char *notesfile,
536 Dwarf_Addr vaddr, const char *secname)
537{
538 int fd = open (notesfile, O_RDONLY);
539 if (fd < 0)
540 return 1;
541
542 assert (sizeof (Elf32_Nhdr) == sizeof (GElf_Nhdr));
543 assert (sizeof (Elf64_Nhdr) == sizeof (GElf_Nhdr));
544 union
545 {
546 GElf_Nhdr nhdr;
547 unsigned char data[8192];
548 } buf;
549
550 ssize_t n = read (fd, buf.data, sizeof buf);
551 close (fd);
552
553 if (n <= 0)
554 return 1;
555
556 unsigned char *p = buf.data;
557 while (p < &buf.data[n])
558 {
559 /* No translation required since we are reading the native kernel. */
560 GElf_Nhdr *nhdr = (void *) p;
561 p += sizeof *nhdr;
562 unsigned char *name = p;
563 p += (nhdr->n_namesz + 3) & -4U;
564 unsigned char *bits = p;
565 p += (nhdr->n_descsz + 3) & -4U;
566
567 if (p <= &buf.data[n]
568 && nhdr->n_type == NT_GNU_BUILD_ID
569 && nhdr->n_namesz == sizeof "GNU"
570 && !memcmp (name, "GNU", sizeof "GNU"))
571 {
572 /* Found it. For a module we must figure out its VADDR now. */
573
574 if (secname != NULL
575 && (INTUSE(dwfl_linux_kernel_module_section_address)
576 (mod, NULL, mod->name, 0, secname, 0, NULL, &vaddr) != 0
577 || vaddr == (GElf_Addr) -1l))
578 vaddr = 0;
579
580 if (vaddr != 0)
581 vaddr += bits - buf.data;
582 return INTUSE(dwfl_module_report_build_id) (mod, bits,
583 nhdr->n_descsz, vaddr);
584 }
585 }
586
587 return 0;
588}
589
590/* Look for a build ID for the kernel. */
591static int
592check_kernel_notes (Dwfl_Module *kernelmod, GElf_Addr vaddr)
593{
594 return check_notes (kernelmod, KNOTESFILE, vaddr, NULL) < 0 ? -1 : 0;
595}
596
597/* Look for a build ID for a loaded kernel module. */
598static int
599check_module_notes (Dwfl_Module *mod)
600{
601 char *dirs[2] = { NULL, NULL };
602 if (asprintf (&dirs[0], MODNOTESFMT, mod->name) < 0)
603 return ENOMEM;
604
605 FTS *fts = fts_open (dirs, FTS_NOSTAT | FTS_LOGICAL, NULL);
606 if (fts == NULL)
607 {
608 free (dirs[0]);
609 return 0;
610 }
611
612 int result = 0;
613 FTSENT *f;
614 while ((f = fts_read (fts)) != NULL)
615 {
616 switch (f->fts_info)
617 {
618 case FTS_F:
619 case FTS_SL:
620 case FTS_NSOK:
621 result = check_notes (mod, f->fts_accpath, 0, f->fts_name);
622 if (result > 0) /* Nothing found. */
623 {
624 result = 0;
625 continue;
626 }
627 break;
628
629 case FTS_ERR:
630 case FTS_DNR:
631 result = f->fts_errno;
632 break;
633
634 case FTS_NS:
635 case FTS_SLNONE:
636 default:
637 continue;
638 }
639
640 /* We only get here when finished or in error cases. */
641 break;
642 }
643 fts_close (fts);
644 free (dirs[0]);
645
646 return result;
647}
648
649int
650dwfl_linux_kernel_report_kernel (Dwfl *dwfl)
651{
652 Dwarf_Addr start = 0;
653 Dwarf_Addr end = 0;
654
655 #define report() \
656 (INTUSE(dwfl_report_module) (dwfl, KERNEL_MODNAME, start, end))
657
658 /* This is a bit of a kludge. If we already reported the kernel,
659 don't bother figuring it out again--it never changes. */
660 for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
661 if (!strcmp (m->name, KERNEL_MODNAME))
662 {
663 start = m->low_addr;
664 end = m->high_addr;
665 return report () == NULL ? -1 : 0;
666 }
667
668 /* Try to figure out the bounds of the kernel image without
669 looking for any vmlinux file. */
670 Dwarf_Addr notes;
671 /* The compiler cannot deduce that if intuit_kernel_bounds returns
672 zero NOTES will be initialized. Fake the initialization. */
673 asm ("" : "=m" (notes));
674 int result = intuit_kernel_bounds (&start, &end, &notes);
675 if (result == 0)
676 {
677 Dwfl_Module *mod = report ();
678 return unlikely (mod == NULL) ? -1 : check_kernel_notes (mod, notes);
679 }
680 if (result != ENOENT)
681 return result;
682
683 /* Find the ELF file for the running kernel and dwfl_report_elf it. */
684 return report_kernel (dwfl, NULL, NULL);
685}
686INTDEF (dwfl_linux_kernel_report_kernel)
687
688
689static inline bool
690subst_name (char from, char to,
691 const char * const module_name,
692 char * const alternate_name,
693 const size_t namelen)
694{
695 const char *n = memchr (module_name, from, namelen);
696 if (n == NULL)
697 return false;
698 char *a = mempcpy (alternate_name, module_name, n - module_name);
699 *a++ = to;
700 ++n;
701 const char *p;
702 while ((p = memchr (n, from, namelen - (n - module_name))) != NULL)
703 {
704 a = mempcpy (a, n, p - n);
705 *a++ = to;
706 n = p + 1;
707 }
708 memcpy (a, n, namelen - (n - module_name) + 1);
709 return true;
710}
711
712/* Dwfl_Callbacks.find_elf for the running Linux kernel and its modules. */
713
714int
715dwfl_linux_kernel_find_elf (Dwfl_Module *mod,
716 void **userdata __attribute__ ((unused)),
717 const char *module_name,
718 Dwarf_Addr base __attribute__ ((unused)),
719 char **file_name, Elf **elfp)
720{
721 if (mod->build_id_len > 0)
722 {
723 int fd = INTUSE(dwfl_build_id_find_elf) (mod, NULL, NULL, 0,
724 file_name, elfp);
725 if (fd >= 0 || mod->main.elf != NULL || errno != 0)
726 return fd;
727 }
728
729 const char *release = kernel_release ();
730 if (release == NULL)
731 return errno;
732
733 if (!strcmp (module_name, KERNEL_MODNAME))
734 return find_kernel_elf (mod->dwfl, release, file_name);
735
736 /* Do "find /lib/modules/`uname -r` -name MODULE_NAME.ko". */
737
738 char *modulesdir[] = { NULL, NULL };
739 if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0)
740 return -1;
741
742 FTS *fts = fts_open (modulesdir, FTS_NOSTAT | FTS_LOGICAL, NULL);
743 if (fts == NULL)
744 {
745 free (modulesdir[0]);
746 return -1;
747 }
748
749 size_t namelen = strlen (module_name);
750
751 /* This is a kludge. There is no actual necessary relationship between
752 the name of the .ko file installed and the module name the kernel
753 knows it by when it's loaded. The kernel's only idea of the module
754 name comes from the name embedded in the object's magic
755 .gnu.linkonce.this_module section.
756
757 In practice, these module names match the .ko file names except for
758 some using '_' and some using '-'. So our cheap kludge is to look for
759 two files when either a '_' or '-' appears in a module name, one using
760 only '_' and one only using '-'. */
761
762 char *alternate_name = malloc (namelen + 1);
763 if (unlikely (alternate_name == NULL))
764 {
765 free (modulesdir[0]);
766 return ENOMEM;
767 }
768 if (!subst_name ('-', '_', module_name, alternate_name, namelen) &&
769 !subst_name ('_', '-', module_name, alternate_name, namelen))
770 alternate_name[0] = '\0';
771
772 FTSENT *f;
773 int error = ENOENT;
774 while ((f = fts_read (fts)) != NULL)
775 {
776 /* Skip a "source" subtree, which tends to be large.
777 This insane hard-coding of names is what depmod does too. */
778 if (f->fts_namelen == sizeof "source" - 1
779 && !strcmp (f->fts_name, "source"))
780 {
781 fts_set (fts, f, FTS_SKIP);
782 continue;
783 }
784
785 error = ENOENT;
786 switch (f->fts_info)
787 {
788 case FTS_F:
789 case FTS_SL:
790 case FTS_NSOK:
791 /* See if this file name is "MODULE_NAME.ko". */
792 if (check_suffix (f, namelen)
793 && (!memcmp (f->fts_name, module_name, namelen)
794 || !memcmp (f->fts_name, alternate_name, namelen)))
795 {
796 int fd = open (f->fts_accpath, O_RDONLY);
797 *file_name = strdup (f->fts_path);
798 fts_close (fts);
799 free (modulesdir[0]);
800 free (alternate_name);
801 if (fd < 0)
802 free (*file_name);
803 else if (*file_name == NULL)
804 {
805 close (fd);
806 fd = -1;
807 }
808 return fd;
809 }
810 break;
811
812 case FTS_ERR:
813 case FTS_DNR:
814 case FTS_NS:
815 error = f->fts_errno;
816 break;
817
818 case FTS_SLNONE:
819 default:
820 break;
821 }
822 }
823
824 fts_close (fts);
825 free (modulesdir[0]);
826 free (alternate_name);
827 errno = error;
828 return -1;
829}
830INTDEF (dwfl_linux_kernel_find_elf)
831
832
833/* Dwfl_Callbacks.section_address for kernel modules in the running Linux.
834 We read the information from /sys/module directly. */
835
836int
837dwfl_linux_kernel_module_section_address
838(Dwfl_Module *mod __attribute__ ((unused)),
839 void **userdata __attribute__ ((unused)),
840 const char *modname, Dwarf_Addr base __attribute__ ((unused)),
841 const char *secname, Elf32_Word shndx __attribute__ ((unused)),
842 const GElf_Shdr *shdr __attribute__ ((unused)),
843 Dwarf_Addr *addr)
844{
845 char *sysfile;
846 if (asprintf (&sysfile, SECADDRDIRFMT "%s", modname, secname) < 0)
847 return DWARF_CB_ABORT;
848
849 FILE *f = fopen (sysfile, "r");
850 free (sysfile);
851
852 if (f == NULL)
853 {
854 if (errno == ENOENT)
855 {
856 /* The .modinfo and .data.percpu sections are never kept
857 loaded in the kernel. If the kernel was compiled without
858 CONFIG_MODULE_UNLOAD, the .exit.* sections are not
859 actually loaded at all.
860
861 Setting *ADDR to -1 tells the caller this section is
862 actually absent from memory. */
863
864 if (!strcmp (secname, ".modinfo")
865 || !strcmp (secname, ".data.percpu")
866 || !strncmp (secname, ".exit", 5))
867 {
868 *addr = (Dwarf_Addr) -1l;
869 return DWARF_CB_OK;
870 }
871
872 /* The goofy PPC64 module_frob_arch_sections function tweaks
873 the section names as a way to control other kernel code's
874 behavior, and this cruft leaks out into the /sys information.
875 The file name for ".init*" may actually look like "_init*". */
876
877 const bool is_init = !strncmp (secname, ".init", 5);
878 if (is_init)
879 {
880 if (asprintf (&sysfile, SECADDRDIRFMT "_%s",
881 modname, &secname[1]) < 0)
882 return ENOMEM;
883 f = fopen (sysfile, "r");
884 free (sysfile);
885 if (f != NULL)
886 goto ok;
887 }
888
889 /* The kernel truncates section names to MODULE_SECT_NAME_LEN - 1.
890 In case that size increases in the future, look for longer
891 truncated names first. */
892 size_t namelen = strlen (secname);
893 if (namelen >= MODULE_SECT_NAME_LEN)
894 {
895 int len = asprintf (&sysfile, SECADDRDIRFMT "%s",
896 modname, secname);
897 if (len < 0)
898 return DWARF_CB_ABORT;
899 char *end = sysfile + len;
900 do
901 {
902 *--end = '\0';
903 f = fopen (sysfile, "r");
904 if (is_init && f == NULL && errno == ENOENT)
905 {
906 sysfile[len - namelen] = '_';
907 f = fopen (sysfile, "r");
908 sysfile[len - namelen] = '.';
909 }
910 }
911 while (f == NULL && errno == ENOENT
912 && end - &sysfile[len - namelen] >= MODULE_SECT_NAME_LEN);
913 free (sysfile);
914
915 if (f != NULL)
916 goto ok;
917 }
918 }
919
920 return DWARF_CB_ABORT;
921 }
922
923 ok:
924 (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
925
926 int result = (fscanf (f, "%" PRIx64 "\n", addr) == 1 ? 0
927 : ferror_unlocked (f) ? errno : ENOEXEC);
928 fclose (f);
929
930 if (result == 0)
931 return DWARF_CB_OK;
932
933 errno = result;
934 return DWARF_CB_ABORT;
935}
936INTDEF (dwfl_linux_kernel_module_section_address)
937
938int
939dwfl_linux_kernel_report_modules (Dwfl *dwfl)
940{
941 FILE *f = fopen (MODULELIST, "r");
942 if (f == NULL)
943 return errno;
944
945 (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
946
947 int result = 0;
948 Dwarf_Addr modaddr;
949 unsigned long int modsz;
950 char modname[128];
951 char *line = NULL;
952 size_t linesz = 0;
953 /* We can't just use fscanf here because it's not easy to distinguish \n
954 from other whitespace so as to take the optional word following the
955 address but always stop at the end of the line. */
956 while (getline (&line, &linesz, f) > 0
957 && sscanf (line, "%128s %lu %*s %*s %*s %" PRIx64 " %*s\n",
958 modname, &modsz, &modaddr) == 3)
959 {
960 Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, modname,
961 modaddr, modaddr + modsz);
962 if (mod == NULL)
963 {
964 result = -1;
965 break;
966 }
967
968 result = check_module_notes (mod);
969 }
970 free (line);
971
972 if (result == 0)
973 result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC;
974
975 fclose (f);
976
977 return result;
978}
979INTDEF (dwfl_linux_kernel_report_modules)