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