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