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