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