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