1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * kallsyms.c: in-kernel printing of symbolic oopses and stack traces. 4 * 5 * Rewritten and vastly simplified by Rusty Russell for in-kernel 6 * module loader: 7 * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation 8 * 9 * ChangeLog: 10 * 11 * (25/Aug/2004) Paulo Marques <pmarques@grupopie.com> 12 * Changed the compression method from stem compression to "table lookup" 13 * compression (see scripts/kallsyms.c for a more complete description) 14 */ 15 #include <linux/kallsyms.h> 16 #include <linux/init.h> 17 #include <linux/seq_file.h> 18 #include <linux/fs.h> 19 #include <linux/kdb.h> 20 #include <linux/err.h> 21 #include <linux/proc_fs.h> 22 #include <linux/sched.h> /* for cond_resched */ 23 #include <linux/ctype.h> 24 #include <linux/slab.h> 25 #include <linux/filter.h> 26 #include <linux/ftrace.h> 27 #include <linux/kprobes.h> 28 #include <linux/build_bug.h> 29 #include <linux/compiler.h> 30 #include <linux/module.h> 31 #include <linux/kernel.h> 32 #include <linux/bsearch.h> 33 #include <linux/btf_ids.h> 34 35 #include "kallsyms_internal.h" 36 37 /* 38 * Expand a compressed symbol data into the resulting uncompressed string, 39 * if uncompressed string is too long (>= maxlen), it will be truncated, 40 * given the offset to where the symbol is in the compressed stream. 41 */ 42 static unsigned int kallsyms_expand_symbol(unsigned int off, 43 char *result, size_t maxlen) 44 { 45 int len, skipped_first = 0; 46 const char *tptr; 47 const u8 *data; 48 49 /* Get the compressed symbol length from the first symbol byte. */ 50 data = &kallsyms_names[off]; 51 len = *data; 52 data++; 53 off++; 54 55 /* If MSB is 1, it is a "big" symbol, so needs an additional byte. */ 56 if ((len & 0x80) != 0) { 57 len = (len & 0x7F) | (*data << 7); 58 data++; 59 off++; 60 } 61 62 /* 63 * Update the offset to return the offset for the next symbol on 64 * the compressed stream. 65 */ 66 off += len; 67 68 /* 69 * For every byte on the compressed symbol data, copy the table 70 * entry for that byte. 71 */ 72 while (len) { 73 tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; 74 data++; 75 len--; 76 77 while (*tptr) { 78 if (skipped_first) { 79 if (maxlen <= 1) 80 goto tail; 81 *result = *tptr; 82 result++; 83 maxlen--; 84 } else 85 skipped_first = 1; 86 tptr++; 87 } 88 } 89 90 tail: 91 if (maxlen) 92 *result = '\0'; 93 94 /* Return to offset to the next symbol. */ 95 return off; 96 } 97 98 /* 99 * Get symbol type information. This is encoded as a single char at the 100 * beginning of the symbol name. 101 */ 102 static char kallsyms_get_symbol_type(unsigned int off) 103 { 104 /* 105 * Get just the first code, look it up in the token table, 106 * and return the first char from this token. If MSB of length 107 * is 1, it is a "big" symbol, so needs an additional byte. 108 */ 109 if (kallsyms_names[off] & 0x80) 110 off++; 111 return kallsyms_token_table[kallsyms_token_index[kallsyms_names[off + 1]]]; 112 } 113 114 115 /* 116 * Find the offset on the compressed stream given and index in the 117 * kallsyms array. 118 */ 119 static unsigned int get_symbol_offset(unsigned long pos) 120 { 121 const u8 *name; 122 int i, len; 123 124 /* 125 * Use the closest marker we have. We have markers every 256 positions, 126 * so that should be close enough. 127 */ 128 name = &kallsyms_names[kallsyms_markers[pos >> 8]]; 129 130 /* 131 * Sequentially scan all the symbols up to the point we're searching 132 * for. Every symbol is stored in a [<len>][<len> bytes of data] format, 133 * so we just need to add the len to the current pointer for every 134 * symbol we wish to skip. 135 */ 136 for (i = 0; i < (pos & 0xFF); i++) { 137 len = *name; 138 139 /* 140 * If MSB is 1, it is a "big" symbol, so we need to look into 141 * the next byte (and skip it, too). 142 */ 143 if ((len & 0x80) != 0) 144 len = ((len & 0x7F) | (name[1] << 7)) + 1; 145 146 name = name + len + 1; 147 } 148 149 return name - kallsyms_names; 150 } 151 152 unsigned long kallsyms_sym_address(int idx) 153 { 154 /* values are unsigned offsets */ 155 return kallsyms_relative_base + (u32)kallsyms_offsets[idx]; 156 } 157 158 static unsigned int get_symbol_seq(int index) 159 { 160 unsigned int i, seq = 0; 161 162 for (i = 0; i < 3; i++) 163 seq = (seq << 8) | kallsyms_seqs_of_names[3 * index + i]; 164 165 return seq; 166 } 167 168 static int kallsyms_lookup_names(const char *name, 169 unsigned int *start, 170 unsigned int *end) 171 { 172 int ret; 173 int low, mid, high; 174 unsigned int seq, off; 175 char namebuf[KSYM_NAME_LEN]; 176 177 low = 0; 178 high = kallsyms_num_syms - 1; 179 180 while (low <= high) { 181 mid = low + (high - low) / 2; 182 seq = get_symbol_seq(mid); 183 off = get_symbol_offset(seq); 184 kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); 185 ret = strcmp(name, namebuf); 186 if (ret > 0) 187 low = mid + 1; 188 else if (ret < 0) 189 high = mid - 1; 190 else 191 break; 192 } 193 194 if (low > high) 195 return -ESRCH; 196 197 low = mid; 198 while (low) { 199 seq = get_symbol_seq(low - 1); 200 off = get_symbol_offset(seq); 201 kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); 202 if (strcmp(name, namebuf)) 203 break; 204 low--; 205 } 206 *start = low; 207 208 if (end) { 209 high = mid; 210 while (high < kallsyms_num_syms - 1) { 211 seq = get_symbol_seq(high + 1); 212 off = get_symbol_offset(seq); 213 kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); 214 if (strcmp(name, namebuf)) 215 break; 216 high++; 217 } 218 *end = high; 219 } 220 221 return 0; 222 } 223 224 /* Lookup the address for this symbol. Returns 0 if not found. */ 225 unsigned long kallsyms_lookup_name(const char *name) 226 { 227 int ret; 228 unsigned int i; 229 230 /* Skip the search for empty string. */ 231 if (!*name) 232 return 0; 233 234 ret = kallsyms_lookup_names(name, &i, NULL); 235 if (!ret) 236 return kallsyms_sym_address(get_symbol_seq(i)); 237 238 return module_kallsyms_lookup_name(name); 239 } 240 241 /* 242 * Iterate over all symbols in vmlinux. For symbols from modules use 243 * module_kallsyms_on_each_symbol instead. 244 */ 245 int kallsyms_on_each_symbol(int (*fn)(void *, const char *, unsigned long), 246 void *data) 247 { 248 char namebuf[KSYM_NAME_LEN]; 249 unsigned long i; 250 unsigned int off; 251 int ret; 252 253 for (i = 0, off = 0; i < kallsyms_num_syms; i++) { 254 off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); 255 ret = fn(data, namebuf, kallsyms_sym_address(i)); 256 if (ret != 0) 257 return ret; 258 cond_resched(); 259 } 260 return 0; 261 } 262 263 int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long), 264 const char *name, void *data) 265 { 266 int ret; 267 unsigned int i, start, end; 268 269 ret = kallsyms_lookup_names(name, &start, &end); 270 if (ret) 271 return 0; 272 273 for (i = start; !ret && i <= end; i++) { 274 ret = fn(data, kallsyms_sym_address(get_symbol_seq(i))); 275 cond_resched(); 276 } 277 278 return ret; 279 } 280 281 static unsigned long get_symbol_pos(unsigned long addr, 282 unsigned long *symbolsize, 283 unsigned long *offset) 284 { 285 unsigned long symbol_start = 0, symbol_end = 0; 286 unsigned long i, low, high, mid; 287 288 /* Do a binary search on the sorted kallsyms_offsets array. */ 289 low = 0; 290 high = kallsyms_num_syms; 291 292 while (high - low > 1) { 293 mid = low + (high - low) / 2; 294 if (kallsyms_sym_address(mid) <= addr) 295 low = mid; 296 else 297 high = mid; 298 } 299 300 /* 301 * Search for the first aliased symbol. Aliased 302 * symbols are symbols with the same address. 303 */ 304 while (low && kallsyms_sym_address(low-1) == kallsyms_sym_address(low)) 305 --low; 306 307 symbol_start = kallsyms_sym_address(low); 308 309 /* Search for next non-aliased symbol. */ 310 for (i = low + 1; i < kallsyms_num_syms; i++) { 311 if (kallsyms_sym_address(i) > symbol_start) { 312 symbol_end = kallsyms_sym_address(i); 313 break; 314 } 315 } 316 317 /* If we found no next symbol, we use the end of the section. */ 318 if (!symbol_end) { 319 if (is_kernel_inittext(addr)) 320 symbol_end = (unsigned long)_einittext; 321 else if (IS_ENABLED(CONFIG_KALLSYMS_ALL)) 322 symbol_end = (unsigned long)_end; 323 else 324 symbol_end = (unsigned long)_etext; 325 } 326 327 if (symbolsize) 328 *symbolsize = symbol_end - symbol_start; 329 if (offset) 330 *offset = addr - symbol_start; 331 332 return low; 333 } 334 335 /* 336 * Lookup an address but don't bother to find any names. 337 */ 338 int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, 339 unsigned long *offset) 340 { 341 char namebuf[KSYM_NAME_LEN]; 342 343 if (is_ksym_addr(addr)) { 344 get_symbol_pos(addr, symbolsize, offset); 345 return 1; 346 } 347 return !!module_address_lookup(addr, symbolsize, offset, NULL, NULL, namebuf) || 348 !!bpf_address_lookup(addr, symbolsize, offset, namebuf); 349 } 350 351 static int kallsyms_lookup_buildid(unsigned long addr, 352 unsigned long *symbolsize, 353 unsigned long *offset, char **modname, 354 const unsigned char **modbuildid, char *namebuf) 355 { 356 int ret; 357 358 /* 359 * kallsyms_lookus() returns pointer to namebuf on success and 360 * NULL on error. But some callers ignore the return value. 361 * Instead they expect @namebuf filled either with valid 362 * or empty string. 363 */ 364 namebuf[0] = 0; 365 /* 366 * Initialize the module-related return values. They are not set 367 * when the symbol is in vmlinux or it is a bpf address. 368 */ 369 if (modname) 370 *modname = NULL; 371 if (modbuildid) 372 *modbuildid = NULL; 373 374 if (is_ksym_addr(addr)) { 375 unsigned long pos; 376 377 pos = get_symbol_pos(addr, symbolsize, offset); 378 /* Grab name */ 379 kallsyms_expand_symbol(get_symbol_offset(pos), 380 namebuf, KSYM_NAME_LEN); 381 382 return strlen(namebuf); 383 } 384 385 /* See if it's in a module or a BPF JITed image. */ 386 ret = module_address_lookup(addr, symbolsize, offset, 387 modname, modbuildid, namebuf); 388 if (!ret) 389 ret = bpf_address_lookup(addr, symbolsize, offset, namebuf); 390 391 if (!ret) 392 ret = ftrace_mod_address_lookup(addr, symbolsize, offset, 393 modname, modbuildid, namebuf); 394 395 return ret; 396 } 397 398 /* 399 * Lookup an address 400 * - modname is set to NULL if it's in the kernel. 401 * - We guarantee that the returned name is valid until we reschedule even if. 402 * It resides in a module. 403 * - We also guarantee that modname will be valid until rescheduled. 404 */ 405 const char *kallsyms_lookup(unsigned long addr, 406 unsigned long *symbolsize, 407 unsigned long *offset, 408 char **modname, char *namebuf) 409 { 410 int ret = kallsyms_lookup_buildid(addr, symbolsize, offset, modname, 411 NULL, namebuf); 412 413 if (!ret) 414 return NULL; 415 416 return namebuf; 417 } 418 419 int lookup_symbol_name(unsigned long addr, char *symname) 420 { 421 symname[0] = '\0'; 422 symname[KSYM_NAME_LEN - 1] = '\0'; 423 424 if (is_ksym_addr(addr)) { 425 unsigned long pos; 426 427 pos = get_symbol_pos(addr, NULL, NULL); 428 /* Grab name */ 429 kallsyms_expand_symbol(get_symbol_offset(pos), 430 symname, KSYM_NAME_LEN); 431 return 0; 432 } 433 /* See if it's in a module. */ 434 return lookup_module_symbol_name(addr, symname); 435 } 436 437 #ifdef CONFIG_STACKTRACE_BUILD_ID 438 439 static int append_buildid(char *buffer, const char *modname, 440 const unsigned char *buildid) 441 { 442 if (!modname) 443 return 0; 444 445 if (!buildid) { 446 pr_warn_once("Undefined buildid for the module %s\n", modname); 447 return 0; 448 } 449 450 /* build ID should match length of sprintf */ 451 #ifdef CONFIG_MODULES 452 static_assert(sizeof(typeof_member(struct module, build_id)) == 20); 453 #endif 454 455 return sprintf(buffer, " %20phN", buildid); 456 } 457 458 #else /* CONFIG_STACKTRACE_BUILD_ID */ 459 460 static int append_buildid(char *buffer, const char *modname, 461 const unsigned char *buildid) 462 { 463 return 0; 464 } 465 466 #endif /* CONFIG_STACKTRACE_BUILD_ID */ 467 468 /* Look up a kernel symbol and return it in a text buffer. */ 469 static int __sprint_symbol(char *buffer, unsigned long address, 470 int symbol_offset, int add_offset, int add_buildid) 471 { 472 char *modname; 473 const unsigned char *buildid; 474 unsigned long offset, size; 475 int len; 476 477 /* Prevent module removal until modname and modbuildid are printed */ 478 guard(rcu)(); 479 480 address += symbol_offset; 481 len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid, 482 buffer); 483 if (!len) 484 return sprintf(buffer, "0x%lx", address - symbol_offset); 485 486 offset -= symbol_offset; 487 488 if (add_offset) 489 len += sprintf(buffer + len, "+%#lx/%#lx", offset, size); 490 491 if (modname) { 492 len += sprintf(buffer + len, " [%s", modname); 493 if (add_buildid) 494 len += append_buildid(buffer + len, modname, buildid); 495 len += sprintf(buffer + len, "]"); 496 } 497 498 return len; 499 } 500 501 /** 502 * sprint_symbol - Look up a kernel symbol and return it in a text buffer 503 * @buffer: buffer to be stored 504 * @address: address to lookup 505 * 506 * This function looks up a kernel symbol with @address and stores its name, 507 * offset, size and module name to @buffer if possible. If no symbol was found, 508 * just saves its @address as is. 509 * 510 * This function returns the number of bytes stored in @buffer. 511 */ 512 int sprint_symbol(char *buffer, unsigned long address) 513 { 514 return __sprint_symbol(buffer, address, 0, 1, 0); 515 } 516 EXPORT_SYMBOL_GPL(sprint_symbol); 517 518 /** 519 * sprint_symbol_build_id - Look up a kernel symbol and return it in a text buffer 520 * @buffer: buffer to be stored 521 * @address: address to lookup 522 * 523 * This function looks up a kernel symbol with @address and stores its name, 524 * offset, size, module name and module build ID to @buffer if possible. If no 525 * symbol was found, just saves its @address as is. 526 * 527 * This function returns the number of bytes stored in @buffer. 528 */ 529 int sprint_symbol_build_id(char *buffer, unsigned long address) 530 { 531 return __sprint_symbol(buffer, address, 0, 1, 1); 532 } 533 EXPORT_SYMBOL_GPL(sprint_symbol_build_id); 534 535 /** 536 * sprint_symbol_no_offset - Look up a kernel symbol and return it in a text buffer 537 * @buffer: buffer to be stored 538 * @address: address to lookup 539 * 540 * This function looks up a kernel symbol with @address and stores its name 541 * and module name to @buffer if possible. If no symbol was found, just saves 542 * its @address as is. 543 * 544 * This function returns the number of bytes stored in @buffer. 545 */ 546 int sprint_symbol_no_offset(char *buffer, unsigned long address) 547 { 548 return __sprint_symbol(buffer, address, 0, 0, 0); 549 } 550 EXPORT_SYMBOL_GPL(sprint_symbol_no_offset); 551 552 /** 553 * sprint_backtrace - Look up a backtrace symbol and return it in a text buffer 554 * @buffer: buffer to be stored 555 * @address: address to lookup 556 * 557 * This function is for stack backtrace and does the same thing as 558 * sprint_symbol() but with modified/decreased @address. If there is a 559 * tail-call to the function marked "noreturn", gcc optimized out code after 560 * the call so that the stack-saved return address could point outside of the 561 * caller. This function ensures that kallsyms will find the original caller 562 * by decreasing @address. 563 * 564 * This function returns the number of bytes stored in @buffer. 565 */ 566 int sprint_backtrace(char *buffer, unsigned long address) 567 { 568 return __sprint_symbol(buffer, address, -1, 1, 0); 569 } 570 571 /** 572 * sprint_backtrace_build_id - Look up a backtrace symbol and return it in a text buffer 573 * @buffer: buffer to be stored 574 * @address: address to lookup 575 * 576 * This function is for stack backtrace and does the same thing as 577 * sprint_symbol() but with modified/decreased @address. If there is a 578 * tail-call to the function marked "noreturn", gcc optimized out code after 579 * the call so that the stack-saved return address could point outside of the 580 * caller. This function ensures that kallsyms will find the original caller 581 * by decreasing @address. This function also appends the module build ID to 582 * the @buffer if @address is within a kernel module. 583 * 584 * This function returns the number of bytes stored in @buffer. 585 */ 586 int sprint_backtrace_build_id(char *buffer, unsigned long address) 587 { 588 return __sprint_symbol(buffer, address, -1, 1, 1); 589 } 590 591 /* To avoid using get_symbol_offset for every symbol, we carry prefix along. */ 592 struct kallsym_iter { 593 loff_t pos; 594 loff_t pos_mod_end; 595 loff_t pos_ftrace_mod_end; 596 loff_t pos_bpf_end; 597 unsigned long value; 598 unsigned int nameoff; /* If iterating in core kernel symbols. */ 599 char type; 600 char name[KSYM_NAME_LEN]; 601 char module_name[MODULE_NAME_LEN]; 602 int exported; 603 int show_value; 604 }; 605 606 static int get_ksymbol_mod(struct kallsym_iter *iter) 607 { 608 int ret = module_get_kallsym(iter->pos - kallsyms_num_syms, 609 &iter->value, &iter->type, 610 iter->name, iter->module_name, 611 &iter->exported); 612 if (ret < 0) { 613 iter->pos_mod_end = iter->pos; 614 return 0; 615 } 616 617 return 1; 618 } 619 620 /* 621 * ftrace_mod_get_kallsym() may also get symbols for pages allocated for ftrace 622 * purposes. In that case "__builtin__ftrace" is used as a module name, even 623 * though "__builtin__ftrace" is not a module. 624 */ 625 static int get_ksymbol_ftrace_mod(struct kallsym_iter *iter) 626 { 627 int ret = ftrace_mod_get_kallsym(iter->pos - iter->pos_mod_end, 628 &iter->value, &iter->type, 629 iter->name, iter->module_name, 630 &iter->exported); 631 if (ret < 0) { 632 iter->pos_ftrace_mod_end = iter->pos; 633 return 0; 634 } 635 636 return 1; 637 } 638 639 static int get_ksymbol_bpf(struct kallsym_iter *iter) 640 { 641 int ret; 642 643 strscpy(iter->module_name, "bpf", MODULE_NAME_LEN); 644 iter->exported = 0; 645 ret = bpf_get_kallsym(iter->pos - iter->pos_ftrace_mod_end, 646 &iter->value, &iter->type, 647 iter->name); 648 if (ret < 0) { 649 iter->pos_bpf_end = iter->pos; 650 return 0; 651 } 652 653 return 1; 654 } 655 656 /* 657 * This uses "__builtin__kprobes" as a module name for symbols for pages 658 * allocated for kprobes' purposes, even though "__builtin__kprobes" is not a 659 * module. 660 */ 661 static int get_ksymbol_kprobe(struct kallsym_iter *iter) 662 { 663 strscpy(iter->module_name, "__builtin__kprobes", MODULE_NAME_LEN); 664 iter->exported = 0; 665 return kprobe_get_kallsym(iter->pos - iter->pos_bpf_end, 666 &iter->value, &iter->type, 667 iter->name) < 0 ? 0 : 1; 668 } 669 670 /* Returns space to next name. */ 671 static unsigned long get_ksymbol_core(struct kallsym_iter *iter) 672 { 673 unsigned off = iter->nameoff; 674 675 iter->module_name[0] = '\0'; 676 iter->value = kallsyms_sym_address(iter->pos); 677 678 iter->type = kallsyms_get_symbol_type(off); 679 680 off = kallsyms_expand_symbol(off, iter->name, ARRAY_SIZE(iter->name)); 681 682 return off - iter->nameoff; 683 } 684 685 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos) 686 { 687 iter->name[0] = '\0'; 688 iter->nameoff = get_symbol_offset(new_pos); 689 iter->pos = new_pos; 690 if (new_pos == 0) { 691 iter->pos_mod_end = 0; 692 iter->pos_ftrace_mod_end = 0; 693 iter->pos_bpf_end = 0; 694 } 695 } 696 697 /* 698 * The end position (last + 1) of each additional kallsyms section is recorded 699 * in iter->pos_..._end as each section is added, and so can be used to 700 * determine which get_ksymbol_...() function to call next. 701 */ 702 static int update_iter_mod(struct kallsym_iter *iter, loff_t pos) 703 { 704 iter->pos = pos; 705 706 if ((!iter->pos_mod_end || iter->pos_mod_end > pos) && 707 get_ksymbol_mod(iter)) 708 return 1; 709 710 if ((!iter->pos_ftrace_mod_end || iter->pos_ftrace_mod_end > pos) && 711 get_ksymbol_ftrace_mod(iter)) 712 return 1; 713 714 if ((!iter->pos_bpf_end || iter->pos_bpf_end > pos) && 715 get_ksymbol_bpf(iter)) 716 return 1; 717 718 return get_ksymbol_kprobe(iter); 719 } 720 721 /* Returns false if pos at or past end of file. */ 722 static int update_iter(struct kallsym_iter *iter, loff_t pos) 723 { 724 /* Module symbols can be accessed randomly. */ 725 if (pos >= kallsyms_num_syms) 726 return update_iter_mod(iter, pos); 727 728 /* If we're not on the desired position, reset to new position. */ 729 if (pos != iter->pos) 730 reset_iter(iter, pos); 731 732 iter->nameoff += get_ksymbol_core(iter); 733 iter->pos++; 734 735 return 1; 736 } 737 738 static void *s_next(struct seq_file *m, void *p, loff_t *pos) 739 { 740 (*pos)++; 741 742 if (!update_iter(m->private, *pos)) 743 return NULL; 744 return p; 745 } 746 747 static void *s_start(struct seq_file *m, loff_t *pos) 748 { 749 if (!update_iter(m->private, *pos)) 750 return NULL; 751 return m->private; 752 } 753 754 static void s_stop(struct seq_file *m, void *p) 755 { 756 } 757 758 static int s_show(struct seq_file *m, void *p) 759 { 760 void *value; 761 struct kallsym_iter *iter = m->private; 762 763 /* Some debugging symbols have no name. Ignore them. */ 764 if (!iter->name[0]) 765 return 0; 766 767 value = iter->show_value ? (void *)iter->value : NULL; 768 769 if (iter->module_name[0]) { 770 char type; 771 772 /* 773 * Label it "global" if it is exported, 774 * "local" if not exported. 775 */ 776 type = iter->exported ? toupper(iter->type) : 777 tolower(iter->type); 778 seq_printf(m, "%px %c %s\t[%s]\n", value, 779 type, iter->name, iter->module_name); 780 } else 781 seq_printf(m, "%px %c %s\n", value, 782 iter->type, iter->name); 783 return 0; 784 } 785 786 static const struct seq_operations kallsyms_op = { 787 .start = s_start, 788 .next = s_next, 789 .stop = s_stop, 790 .show = s_show 791 }; 792 793 #ifdef CONFIG_BPF_SYSCALL 794 795 struct bpf_iter__ksym { 796 __bpf_md_ptr(struct bpf_iter_meta *, meta); 797 __bpf_md_ptr(struct kallsym_iter *, ksym); 798 }; 799 800 static int ksym_prog_seq_show(struct seq_file *m, bool in_stop) 801 { 802 struct bpf_iter__ksym ctx; 803 struct bpf_iter_meta meta; 804 struct bpf_prog *prog; 805 806 meta.seq = m; 807 prog = bpf_iter_get_info(&meta, in_stop); 808 if (!prog) 809 return 0; 810 811 ctx.meta = &meta; 812 ctx.ksym = m ? m->private : NULL; 813 return bpf_iter_run_prog(prog, &ctx); 814 } 815 816 static int bpf_iter_ksym_seq_show(struct seq_file *m, void *p) 817 { 818 return ksym_prog_seq_show(m, false); 819 } 820 821 static void bpf_iter_ksym_seq_stop(struct seq_file *m, void *p) 822 { 823 if (!p) 824 (void) ksym_prog_seq_show(m, true); 825 else 826 s_stop(m, p); 827 } 828 829 static const struct seq_operations bpf_iter_ksym_ops = { 830 .start = s_start, 831 .next = s_next, 832 .stop = bpf_iter_ksym_seq_stop, 833 .show = bpf_iter_ksym_seq_show, 834 }; 835 836 static int bpf_iter_ksym_init(void *priv_data, struct bpf_iter_aux_info *aux) 837 { 838 struct kallsym_iter *iter = priv_data; 839 840 reset_iter(iter, 0); 841 842 /* cache here as in kallsyms_open() case; use current process 843 * credentials to tell BPF iterators if values should be shown. 844 */ 845 iter->show_value = kallsyms_show_value(current_cred()); 846 847 return 0; 848 } 849 850 DEFINE_BPF_ITER_FUNC(ksym, struct bpf_iter_meta *meta, struct kallsym_iter *ksym) 851 852 static const struct bpf_iter_seq_info ksym_iter_seq_info = { 853 .seq_ops = &bpf_iter_ksym_ops, 854 .init_seq_private = bpf_iter_ksym_init, 855 .fini_seq_private = NULL, 856 .seq_priv_size = sizeof(struct kallsym_iter), 857 }; 858 859 static struct bpf_iter_reg ksym_iter_reg_info = { 860 .target = "ksym", 861 .feature = BPF_ITER_RESCHED, 862 .ctx_arg_info_size = 1, 863 .ctx_arg_info = { 864 { offsetof(struct bpf_iter__ksym, ksym), 865 PTR_TO_BTF_ID_OR_NULL }, 866 }, 867 .seq_info = &ksym_iter_seq_info, 868 }; 869 870 BTF_ID_LIST_SINGLE(btf_ksym_iter_id, struct, kallsym_iter) 871 872 static int __init bpf_ksym_iter_register(void) 873 { 874 ksym_iter_reg_info.ctx_arg_info[0].btf_id = *btf_ksym_iter_id; 875 return bpf_iter_reg_target(&ksym_iter_reg_info); 876 } 877 878 late_initcall(bpf_ksym_iter_register); 879 880 #endif /* CONFIG_BPF_SYSCALL */ 881 882 static int kallsyms_open(struct inode *inode, struct file *file) 883 { 884 /* 885 * We keep iterator in m->private, since normal case is to 886 * s_start from where we left off, so we avoid doing 887 * using get_symbol_offset for every symbol. 888 */ 889 struct kallsym_iter *iter; 890 iter = __seq_open_private(file, &kallsyms_op, sizeof(*iter)); 891 if (!iter) 892 return -ENOMEM; 893 reset_iter(iter, 0); 894 895 /* 896 * Instead of checking this on every s_show() call, cache 897 * the result here at open time. 898 */ 899 iter->show_value = kallsyms_show_value(file->f_cred); 900 return 0; 901 } 902 903 #ifdef CONFIG_KGDB_KDB 904 const char *kdb_walk_kallsyms(loff_t *pos) 905 { 906 static struct kallsym_iter kdb_walk_kallsyms_iter; 907 if (*pos == 0) { 908 memset(&kdb_walk_kallsyms_iter, 0, 909 sizeof(kdb_walk_kallsyms_iter)); 910 reset_iter(&kdb_walk_kallsyms_iter, 0); 911 } 912 while (1) { 913 if (!update_iter(&kdb_walk_kallsyms_iter, *pos)) 914 return NULL; 915 ++*pos; 916 /* Some debugging symbols have no name. Ignore them. */ 917 if (kdb_walk_kallsyms_iter.name[0]) 918 return kdb_walk_kallsyms_iter.name; 919 } 920 } 921 #endif /* CONFIG_KGDB_KDB */ 922 923 static const struct proc_ops kallsyms_proc_ops = { 924 .proc_open = kallsyms_open, 925 .proc_read = seq_read, 926 .proc_lseek = seq_lseek, 927 .proc_release = seq_release_private, 928 }; 929 930 static int __init kallsyms_init(void) 931 { 932 proc_create("kallsyms", 0444, NULL, &kallsyms_proc_ops); 933 return 0; 934 } 935 device_initcall(kallsyms_init); 936