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 #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)
62 static 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.  */
77 static int
try_kernel_name(Dwfl * dwfl,char ** fname,bool try_debug)78 try_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 
141 static inline const char *
kernel_release(void)142 kernel_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 
151 static int
find_kernel_elf(Dwfl * dwfl,const char * release,char ** fname)152 find_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 
171 static int
get_release(Dwfl * dwfl,const char ** release)172 get_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 
190 static int
report_kernel(Dwfl * dwfl,const char ** release,int (* predicate)(const char * module,const char * file))191 report_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.  */
245 static int
report_kernel_archive(Dwfl * dwfl,const char ** release,int (* predicate)(const char * module,const char * file))246 report_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 
289 static size_t
check_suffix(const FTSENT * f,size_t namelen)290 check_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.  */
321 int
dwfl_linux_kernel_report_offline(Dwfl * dwfl,const char * release,int (* predicate)(const char * module,const char * file))322 dwfl_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[f->fts_namelen - suffix + 1];
384 		  for (size_t i = 0; i < f->fts_namelen - 3U; ++i)
385 		    if (f->fts_name[i] == '-' || f->fts_name[i] == ',')
386 		      name[i] = '_';
387 		    else
388 		      name[i] = f->fts_name[i];
389 		  name[f->fts_namelen - suffix] = '\0';
390 
391 		  if (predicate != NULL)
392 		    {
393 		      /* Let the predicate decide whether to use this one.  */
394 		      int want = (*predicate) (name, f->fts_path);
395 		      if (want < 0)
396 			{
397 			  result = -1;
398 			  break;
399 			}
400 		      if (!want)
401 			continue;
402 		    }
403 
404 		  if (dwfl_report_offline (dwfl, name, f->fts_path, -1) == NULL)
405 		    {
406 		      result = -1;
407 		      break;
408 		    }
409 		}
410 	      continue;
411 
412 	    case FTS_ERR:
413 	    case FTS_DNR:
414 	    case FTS_NS:
415 	      result = f->fts_errno;
416 	      break;
417 
418 	    case FTS_SLNONE:
419 	    default:
420 	      continue;
421 	    }
422 
423 	  /* We only get here in error cases.  */
424 	  break;
425 	}
426       fts_close (fts);
427       free (modulesdir[0]);
428     }
429 
430   return result;
431 }
INTDEF(dwfl_linux_kernel_report_offline)432 INTDEF (dwfl_linux_kernel_report_offline)
433 
434 
435 /* Grovel around to guess the bounds of the runtime kernel image.  */
436 static int
437 intuit_kernel_bounds (Dwarf_Addr *start, Dwarf_Addr *end, Dwarf_Addr *notes)
438 {
439   FILE *f = fopen (KSYMSFILE, "r");
440   if (f == NULL)
441     return errno;
442 
443   (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
444 
445   *notes = 0;
446 
447   char *line = NULL;
448   size_t linesz = 0;
449   size_t n;
450   char *p = NULL;
451   const char *type;
452 
453   inline bool read_address (Dwarf_Addr *addr)
454   {
455     if ((n = getline (&line, &linesz, f)) < 1 || line[n - 2] == ']')
456       return false;
457     *addr = strtoull (line, &p, 16);
458     p += strspn (p, " \t");
459     type = strsep (&p, " \t\n");
460     if (type == NULL)
461       return false;
462     return p != NULL && p != line;
463   }
464 
465   int result;
466   do
467     result = read_address (start) ? 0 : -1;
468   while (result == 0 && strchr ("TtRr", *type) == NULL);
469 
470   if (result == 0)
471     {
472       *end = *start;
473       while (read_address (end))
474 	if (*notes == 0 && !strcmp (p, "__start_notes\n"))
475 	  *notes = *end;
476 
477       Dwarf_Addr round_kernel = sysconf (_SC_PAGE_SIZE);
478       *start &= -(Dwarf_Addr) round_kernel;
479       *end += round_kernel - 1;
480       *end &= -(Dwarf_Addr) round_kernel;
481       if (*start >= *end || *end - *start < round_kernel)
482 	result = -1;
483     }
484   free (line);
485 
486   if (result == -1)
487     result = ferror_unlocked (f) ? errno : ENOEXEC;
488 
489   fclose (f);
490 
491   return result;
492 }
493 
494 
495 /* Look for a build ID note in NOTESFILE and associate the ID with MOD.  */
496 static int
check_notes(Dwfl_Module * mod,const char * notesfile,Dwarf_Addr vaddr,const char * secname)497 check_notes (Dwfl_Module *mod, const char *notesfile,
498 	     Dwarf_Addr vaddr, const char *secname)
499 {
500   int fd = open64 (notesfile, O_RDONLY);
501   if (fd < 0)
502     return 1;
503 
504   assert (sizeof (Elf32_Nhdr) == sizeof (GElf_Nhdr));
505   assert (sizeof (Elf64_Nhdr) == sizeof (GElf_Nhdr));
506   union
507   {
508     GElf_Nhdr nhdr;
509     unsigned char data[8192];
510   } buf;
511 
512   ssize_t n = read (fd, buf.data, sizeof buf);
513   close (fd);
514 
515   if (n <= 0)
516     return 1;
517 
518   unsigned char *p = buf.data;
519   while (p < &buf.data[n])
520     {
521       /* No translation required since we are reading the native kernel.  */
522       GElf_Nhdr *nhdr = (void *) p;
523       p += sizeof *nhdr;
524       unsigned char *name = p;
525       p += (nhdr->n_namesz + 3) & -4U;
526       unsigned char *bits = p;
527       p += (nhdr->n_descsz + 3) & -4U;
528 
529       if (p <= &buf.data[n]
530 	  && nhdr->n_type == NT_GNU_BUILD_ID
531 	  && nhdr->n_namesz == sizeof "GNU"
532 	  && !memcmp (name, "GNU", sizeof "GNU"))
533 	{
534 	  /* Found it.  For a module we must figure out its VADDR now.  */
535 
536 	  if (secname != NULL
537 	      && (INTUSE(dwfl_linux_kernel_module_section_address)
538 		  (mod, NULL, mod->name, 0, secname, 0, NULL, &vaddr) != 0
539 		  || vaddr == (GElf_Addr) -1l))
540 	    vaddr = 0;
541 
542 	  if (vaddr != 0)
543 	    vaddr += bits - buf.data;
544 	  return INTUSE(dwfl_module_report_build_id) (mod, bits,
545 						      nhdr->n_descsz, vaddr);
546 	}
547     }
548 
549   return 0;
550 }
551 
552 /* Look for a build ID for the kernel.  */
553 static int
check_kernel_notes(Dwfl_Module * kernelmod,GElf_Addr vaddr)554 check_kernel_notes (Dwfl_Module *kernelmod, GElf_Addr vaddr)
555 {
556   return check_notes (kernelmod, KNOTESFILE, vaddr, NULL) < 0 ? -1 : 0;
557 }
558 
559 /* Look for a build ID for a loaded kernel module.  */
560 static int
check_module_notes(Dwfl_Module * mod)561 check_module_notes (Dwfl_Module *mod)
562 {
563   char *dirs[2] = { NULL, NULL };
564   if (asprintf (&dirs[0], MODNOTESFMT, mod->name) < 0)
565     return ENOMEM;
566 
567   FTS *fts = fts_open (dirs, FTS_NOSTAT | FTS_LOGICAL, NULL);
568   if (fts == NULL)
569     {
570       free (dirs[0]);
571       return 0;
572     }
573 
574   int result = 0;
575   FTSENT *f;
576   while ((f = fts_read (fts)) != NULL)
577     {
578       switch (f->fts_info)
579 	{
580 	case FTS_F:
581 	case FTS_SL:
582 	case FTS_NSOK:
583 	  result = check_notes (mod, f->fts_accpath, 0, f->fts_name);
584 	  if (result > 0)	/* Nothing found.  */
585 	    {
586 	      result = 0;
587 	      continue;
588 	    }
589 	  break;
590 
591 	case FTS_ERR:
592 	case FTS_DNR:
593 	  result = f->fts_errno;
594 	  break;
595 
596 	case FTS_NS:
597 	case FTS_SLNONE:
598 	default:
599 	  continue;
600 	}
601 
602       /* We only get here when finished or in error cases.  */
603       break;
604     }
605   fts_close (fts);
606   free (dirs[0]);
607 
608   return result;
609 }
610 
611 int
dwfl_linux_kernel_report_kernel(Dwfl * dwfl)612 dwfl_linux_kernel_report_kernel (Dwfl *dwfl)
613 {
614   Dwarf_Addr start;
615   Dwarf_Addr end;
616   inline Dwfl_Module *report (void)
617     {
618       return INTUSE(dwfl_report_module) (dwfl, KERNEL_MODNAME, start, end);
619     }
620 
621   /* This is a bit of a kludge.  If we already reported the kernel,
622      don't bother figuring it out again--it never changes.  */
623   for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
624     if (!strcmp (m->name, KERNEL_MODNAME))
625       {
626 	start = m->low_addr;
627 	end = m->high_addr;
628 	return report () == NULL ? -1 : 0;
629       }
630 
631   /* Try to figure out the bounds of the kernel image without
632      looking for any vmlinux file.  */
633   Dwarf_Addr notes;
634   /* The compiler cannot deduce that if intuit_kernel_bounds returns
635      zero NOTES will be initialized.  Fake the initialization.  */
636   asm ("" : "=m" (notes));
637   int result = intuit_kernel_bounds (&start, &end, &notes);
638   if (result == 0)
639     {
640       Dwfl_Module *mod = report ();
641       return unlikely (mod == NULL) ? -1 : check_kernel_notes (mod, notes);
642     }
643   if (result != ENOENT)
644     return result;
645 
646   /* Find the ELF file for the running kernel and dwfl_report_elf it.  */
647   return report_kernel (dwfl, NULL, NULL);
648 }
INTDEF(dwfl_linux_kernel_report_kernel)649 INTDEF (dwfl_linux_kernel_report_kernel)
650 
651 
652 /* Dwfl_Callbacks.find_elf for the running Linux kernel and its modules.  */
653 
654 int
655 dwfl_linux_kernel_find_elf (Dwfl_Module *mod,
656 			    void **userdata __attribute__ ((unused)),
657 			    const char *module_name,
658 			    Dwarf_Addr base __attribute__ ((unused)),
659 			    char **file_name, Elf **elfp)
660 {
661   if (mod->build_id_len > 0)
662     {
663       int fd = INTUSE(dwfl_build_id_find_elf) (mod, NULL, NULL, 0,
664 					       file_name, elfp);
665       if (fd >= 0 || mod->main.elf != NULL || errno != 0)
666 	return fd;
667     }
668 
669   const char *release = kernel_release ();
670   if (release == NULL)
671     return errno;
672 
673   if (!strcmp (module_name, KERNEL_MODNAME))
674     return find_kernel_elf (mod->dwfl, release, file_name);
675 
676   /* Do "find /lib/modules/`uname -r` -name MODULE_NAME.ko".  */
677 
678   char *modulesdir[] = { NULL, NULL };
679   if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0)
680     return -1;
681 
682   FTS *fts = fts_open (modulesdir, FTS_NOSTAT | FTS_LOGICAL, NULL);
683   if (fts == NULL)
684     {
685       free (modulesdir[0]);
686       return -1;
687     }
688 
689   size_t namelen = strlen (module_name);
690 
691   /* This is a kludge.  There is no actual necessary relationship between
692      the name of the .ko file installed and the module name the kernel
693      knows it by when it's loaded.  The kernel's only idea of the module
694      name comes from the name embedded in the object's magic
695      .gnu.linkonce.this_module section.
696 
697      In practice, these module names match the .ko file names except for
698      some using '_' and some using '-'.  So our cheap kludge is to look for
699      two files when either a '_' or '-' appears in a module name, one using
700      only '_' and one only using '-'.  */
701 
702   char alternate_name[namelen + 1];
703   inline bool subst_name (char from, char to)
704     {
705       const char *n = memchr (module_name, from, namelen);
706       if (n == NULL)
707 	return false;
708       char *a = mempcpy (alternate_name, module_name, n - module_name);
709       *a++ = to;
710       ++n;
711       const char *p;
712       while ((p = memchr (n, from, namelen - (n - module_name))) != NULL)
713 	{
714 	  a = mempcpy (a, n, p - n);
715 	  *a++ = to;
716 	  n = p + 1;
717 	}
718       memcpy (a, n, namelen - (n - module_name) + 1);
719       return true;
720     }
721   if (!subst_name ('-', '_') && !subst_name ('_', '-'))
722     alternate_name[0] = '\0';
723 
724   FTSENT *f;
725   int error = ENOENT;
726   while ((f = fts_read (fts)) != NULL)
727     {
728       /* Skip a "source" subtree, which tends to be large.
729 	 This insane hard-coding of names is what depmod does too.  */
730       if (f->fts_namelen == sizeof "source" - 1
731 	  && !strcmp (f->fts_name, "source"))
732 	{
733 	  fts_set (fts, f, FTS_SKIP);
734 	  continue;
735 	}
736 
737       error = ENOENT;
738       switch (f->fts_info)
739 	{
740 	case FTS_F:
741 	case FTS_SL:
742 	case FTS_NSOK:
743 	  /* See if this file name is "MODULE_NAME.ko".  */
744 	  if (check_suffix (f, namelen)
745 	      && (!memcmp (f->fts_name, module_name, namelen)
746 		  || !memcmp (f->fts_name, alternate_name, namelen)))
747 	    {
748 	      int fd = open64 (f->fts_accpath, O_RDONLY);
749 	      *file_name = strdup (f->fts_path);
750 	      fts_close (fts);
751 	      free (modulesdir[0]);
752 	      if (fd < 0)
753 		free (*file_name);
754 	      else if (*file_name == NULL)
755 		{
756 		  close (fd);
757 		  fd = -1;
758 		}
759 	      return fd;
760 	    }
761 	  break;
762 
763 	case FTS_ERR:
764 	case FTS_DNR:
765 	case FTS_NS:
766 	  error = f->fts_errno;
767 	  break;
768 
769 	case FTS_SLNONE:
770 	default:
771 	  break;
772 	}
773     }
774 
775   fts_close (fts);
776   free (modulesdir[0]);
777   errno = error;
778   return -1;
779 }
INTDEF(dwfl_linux_kernel_find_elf)780 INTDEF (dwfl_linux_kernel_find_elf)
781 
782 
783 /* Dwfl_Callbacks.section_address for kernel modules in the running Linux.
784    We read the information from /sys/module directly.  */
785 
786 int
787 dwfl_linux_kernel_module_section_address
788 (Dwfl_Module *mod __attribute__ ((unused)),
789  void **userdata __attribute__ ((unused)),
790  const char *modname, Dwarf_Addr base __attribute__ ((unused)),
791  const char *secname, Elf32_Word shndx __attribute__ ((unused)),
792  const GElf_Shdr *shdr __attribute__ ((unused)),
793  Dwarf_Addr *addr)
794 {
795   char *sysfile;
796   if (asprintf (&sysfile, SECADDRDIRFMT "%s", modname, secname) < 0)
797     return DWARF_CB_ABORT;
798 
799   FILE *f = fopen (sysfile, "r");
800   free (sysfile);
801 
802   if (f == NULL)
803     {
804       if (errno == ENOENT)
805 	{
806 	  /* The .modinfo and .data.percpu sections are never kept
807 	     loaded in the kernel.  If the kernel was compiled without
808 	     CONFIG_MODULE_UNLOAD, the .exit.* sections are not
809 	     actually loaded at all.
810 
811 	     Setting *ADDR to -1 tells the caller this section is
812 	     actually absent from memory.  */
813 
814 	  if (!strcmp (secname, ".modinfo")
815 	      || !strcmp (secname, ".data.percpu")
816 	      || !strncmp (secname, ".exit", 5))
817 	    {
818 	      *addr = (Dwarf_Addr) -1l;
819 	      return DWARF_CB_OK;
820 	    }
821 
822 	  /* The goofy PPC64 module_frob_arch_sections function tweaks
823 	     the section names as a way to control other kernel code's
824 	     behavior, and this cruft leaks out into the /sys information.
825 	     The file name for ".init*" may actually look like "_init*".  */
826 
827 	  const bool is_init = !strncmp (secname, ".init", 5);
828 	  if (is_init)
829 	    {
830 	      if (asprintf (&sysfile, SECADDRDIRFMT "_%s",
831 			    modname, &secname[1]) < 0)
832 		return ENOMEM;
833 	      f = fopen (sysfile, "r");
834 	      free (sysfile);
835 	      if (f != NULL)
836 		goto ok;
837 	    }
838 
839 	  /* The kernel truncates section names to MODULE_SECT_NAME_LEN - 1.
840 	     In case that size increases in the future, look for longer
841 	     truncated names first.  */
842 	  size_t namelen = strlen (secname);
843 	  if (namelen >= MODULE_SECT_NAME_LEN)
844 	    {
845 	      int len = asprintf (&sysfile, SECADDRDIRFMT "%s",
846 				  modname, secname);
847 	      if (len < 0)
848 		return DWARF_CB_ABORT;
849 	      char *end = sysfile + len;
850 	      do
851 		{
852 		  *--end = '\0';
853 		  f = fopen (sysfile, "r");
854 		  if (is_init && f == NULL && errno == ENOENT)
855 		    {
856 		      sysfile[len - namelen] = '_';
857 		      f = fopen (sysfile, "r");
858 		      sysfile[len - namelen] = '.';
859 		    }
860 		}
861 	      while (f == NULL && errno == ENOENT
862 		     && end - &sysfile[len - namelen] >= MODULE_SECT_NAME_LEN);
863 	      free (sysfile);
864 
865 	      if (f != NULL)
866 		goto ok;
867 	    }
868 	}
869 
870       return DWARF_CB_ABORT;
871     }
872 
873  ok:
874   (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
875 
876   int result = (fscanf (f, "%" PRIx64 "\n", addr) == 1 ? 0
877 		: ferror_unlocked (f) ? errno : ENOEXEC);
878   fclose (f);
879 
880   if (result == 0)
881     return DWARF_CB_OK;
882 
883   errno = result;
884   return DWARF_CB_ABORT;
885 }
INTDEF(dwfl_linux_kernel_module_section_address)886 INTDEF (dwfl_linux_kernel_module_section_address)
887 
888 int
889 dwfl_linux_kernel_report_modules (Dwfl *dwfl)
890 {
891   FILE *f = fopen (MODULELIST, "r");
892   if (f == NULL)
893     return errno;
894 
895   (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
896 
897   int result = 0;
898   Dwarf_Addr modaddr;
899   unsigned long int modsz;
900   char modname[128];
901   char *line = NULL;
902   size_t linesz = 0;
903   /* We can't just use fscanf here because it's not easy to distinguish \n
904      from other whitespace so as to take the optional word following the
905      address but always stop at the end of the line.  */
906   while (getline (&line, &linesz, f) > 0
907 	 && sscanf (line, "%128s %lu %*s %*s %*s %" PRIx64 " %*s\n",
908 		    modname, &modsz, &modaddr) == 3)
909     {
910       Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, modname,
911 						     modaddr, modaddr + modsz);
912       if (mod == NULL)
913 	{
914 	  result = -1;
915 	  break;
916 	}
917 
918       result = check_module_notes (mod);
919     }
920   free (line);
921 
922   if (result == 0)
923     result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC;
924 
925   fclose (f);
926 
927   return result;
928 }
929 INTDEF (dwfl_linux_kernel_report_modules)
930