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