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, ¬es); 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