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