27 */ 28 29#include "opt_ddb.h" 30 31#include <sys/param.h> 32#include <sys/kernel.h> 33#include <sys/systm.h> 34#include <sys/malloc.h> 35#include <sys/sysproto.h> 36#include <sys/sysent.h> 37#include <sys/proc.h> 38#include <sys/lock.h> 39#include <sys/module.h> 40#include <sys/linker.h> 41#include <sys/fcntl.h> 42#include <sys/libkern.h> 43#include <sys/namei.h> 44#include <sys/vnode.h> 45#include <sys/sysctl.h> 46 47 48#include "linker_if.h" 49 50#ifdef KLD_DEBUG 51int kld_debug = 0; 52#endif 53 54static char *linker_search_path(const char *name); 55static const char *linker_basename(const char* path); 56 57MALLOC_DEFINE(M_LINKER, "linker", "kernel linker"); 58 59linker_file_t linker_kernel_file; 60 61static struct lock lock; /* lock for the file list */ 62static linker_class_list_t classes; 63static linker_file_list_t linker_files; 64static int next_file_id = 1; 65 66/* XXX wrong name; we're looking at version provision tags here, not modules */ 67typedef TAILQ_HEAD(, modlist) modlisthead_t; 68struct modlist { 69 TAILQ_ENTRY(modlist) link; /* chain together all modules */ 70 linker_file_t container; 71 const char *name; 72 int version; 73}; 74typedef struct modlist *modlist_t; 75static modlisthead_t found_modules; 76 77static char * 78linker_strdup(const char *str) 79{ 80 char *result; 81 82 if ((result = malloc((strlen(str) + 1), M_LINKER, M_WAITOK)) != NULL) 83 strcpy(result, str); 84 return(result); 85} 86 87static void 88linker_init(void* arg) 89{ 90 lockinit(&lock, PVM, "klink", 0, 0); 91 TAILQ_INIT(&classes); 92 TAILQ_INIT(&linker_files); 93} 94 95SYSINIT(linker, SI_SUB_KLD, SI_ORDER_FIRST, linker_init, 0); 96 97int 98linker_add_class(linker_class_t lc) 99{ 100 kobj_class_compile((kobj_class_t) lc); 101 TAILQ_INSERT_TAIL(&classes, lc, link); 102 return 0; 103} 104 105static void 106linker_file_sysinit(linker_file_t lf) 107{ 108 struct linker_set* sysinits; 109 struct sysinit** sipp; 110 struct sysinit** xipp; 111 struct sysinit* save; 112 113 KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n", 114 lf->filename)); 115 116 sysinits = (struct linker_set*) 117 linker_file_lookup_symbol(lf, "sysinit_set", 0); 118 119 KLD_DPF(FILE, ("linker_file_sysinit: SYSINITs %p\n", sysinits)); 120 if (!sysinits) 121 return; 122 /* 123 * Perform a bubble sort of the system initialization objects by 124 * their subsystem (primary key) and order (secondary key). 125 * 126 * Since some things care about execution order, this is the 127 * operation which ensures continued function. 128 */ 129 for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) { 130 for (xipp = sipp + 1; *xipp; xipp++) { 131 if ((*sipp)->subsystem < (*xipp)->subsystem || 132 ((*sipp)->subsystem == (*xipp)->subsystem && 133 (*sipp)->order <= (*xipp)->order)) 134 continue; /* skip*/ 135 save = *sipp; 136 *sipp = *xipp; 137 *xipp = save; 138 } 139 } 140 141 142 /* 143 * Traverse the (now) ordered list of system initialization tasks. 144 * Perform each task, and continue on to the next task. 145 */ 146 for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) { 147 if ((*sipp)->subsystem == SI_SUB_DUMMY) 148 continue; /* skip dummy task(s)*/ 149 150 /* Call function */ 151 (*((*sipp)->func))((*sipp)->udata); 152 } 153} 154 155static void 156linker_file_sysuninit(linker_file_t lf) 157{ 158 struct linker_set* sysuninits; 159 struct sysinit** sipp; 160 struct sysinit** xipp; 161 struct sysinit* save; 162 163 KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n", 164 lf->filename)); 165 166 sysuninits = (struct linker_set*) 167 linker_file_lookup_symbol(lf, "sysuninit_set", 0); 168 169 KLD_DPF(FILE, ("linker_file_sysuninit: SYSUNINITs %p\n", sysuninits)); 170 if (!sysuninits) 171 return; 172 173 /* 174 * Perform a reverse bubble sort of the system initialization objects 175 * by their subsystem (primary key) and order (secondary key). 176 * 177 * Since some things care about execution order, this is the 178 * operation which ensures continued function. 179 */ 180 for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) { 181 for (xipp = sipp + 1; *xipp; xipp++) { 182 if ((*sipp)->subsystem > (*xipp)->subsystem || 183 ((*sipp)->subsystem == (*xipp)->subsystem && 184 (*sipp)->order >= (*xipp)->order)) 185 continue; /* skip*/ 186 save = *sipp; 187 *sipp = *xipp; 188 *xipp = save; 189 } 190 } 191 192 /* 193 * Traverse the (now) ordered list of system initialization tasks. 194 * Perform each task, and continue on to the next task. 195 */ 196 for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) { 197 if ((*sipp)->subsystem == SI_SUB_DUMMY) 198 continue; /* skip dummy task(s)*/ 199 200 /* Call function */ 201 (*((*sipp)->func))((*sipp)->udata); 202 } 203} 204 205static void 206linker_file_register_sysctls(linker_file_t lf) 207{ 208 struct linker_set* sysctls; 209 210 KLD_DPF(FILE, ("linker_file_register_sysctls: registering SYSCTLs for %s\n", 211 lf->filename)); 212 213 sysctls = (struct linker_set*) 214 linker_file_lookup_symbol(lf, "sysctl_set", 0); 215 216 KLD_DPF(FILE, ("linker_file_register_sysctls: SYSCTLs %p\n", sysctls)); 217 if (!sysctls) 218 return; 219 220 sysctl_register_set(sysctls); 221} 222 223static void 224linker_file_unregister_sysctls(linker_file_t lf) 225{ 226 struct linker_set* sysctls; 227 228 KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs for %s\n", 229 lf->filename)); 230 231 sysctls = (struct linker_set*) 232 linker_file_lookup_symbol(lf, "sysctl_set", 0); 233 234 KLD_DPF(FILE, ("linker_file_unregister_sysctls: SYSCTLs %p\n", sysctls)); 235 if (!sysctls) 236 return; 237 238 sysctl_unregister_set(sysctls); 239} 240 241extern struct linker_set modmetadata_set; 242 243static int 244linker_file_register_modules(linker_file_t lf) 245{ 246 int error; 247 struct linker_set *modules; 248 struct mod_metadata **mdpp; 249 const moduledata_t *moddata; 250 251 KLD_DPF(FILE, ("linker_file_register_modules: registering modules in %s\n", 252 lf->filename)); 253 254 modules = (struct linker_set*) 255 linker_file_lookup_symbol(lf, "modmetadata_set", 0); 256 257 if (!modules && lf == linker_kernel_file) 258 modules = &modmetadata_set; 259 260 if (modules == NULL) 261 return 0; 262 for (mdpp = (struct mod_metadata**)modules->ls_items; *mdpp; mdpp++) { 263 if ((*mdpp)->md_type != MDT_MODULE) 264 continue; 265 moddata = (*mdpp)->md_data; 266 KLD_DPF(FILE, ("Registering module %s in %s\n", 267 moddata->name, lf->filename)); 268 if (module_lookupbyname(moddata->name) != NULL) { 269 printf("Warning: module %s already exists\n", moddata->name); 270 continue; /* or return a error ? */ 271 } 272 error = module_register(moddata, lf); 273 if (error) 274 printf("Module %s failed to register: %d\n", moddata->name, error); 275 } 276 return 0; 277} 278 279static void 280linker_init_kernel_modules(void) 281{ 282 linker_file_register_modules(linker_kernel_file); 283} 284 285SYSINIT(linker_kernel, SI_SUB_KLD, SI_ORDER_ANY, linker_init_kernel_modules, 0); 286 287int 288linker_load_file(const char* filename, linker_file_t* result) 289{ 290 linker_class_t lc; 291 linker_file_t lf; 292 int foundfile, error = 0; 293 294 /* Refuse to load modules if securelevel raised */ 295 if (securelevel > 0) 296 return EPERM; 297 298 lf = linker_find_file_by_name(filename); 299 if (lf) { 300 KLD_DPF(FILE, ("linker_load_file: file %s is already loaded, incrementing refs\n", filename)); 301 *result = lf; 302 lf->refs++; 303 goto out; 304 } 305 306 lf = NULL; 307 foundfile = 0; 308 TAILQ_FOREACH(lc, &classes, link) { 309 KLD_DPF(FILE, ("linker_load_file: trying to load %s as %s\n", 310 filename, lc->desc)); 311 error = LINKER_LOAD_FILE(lc, filename, &lf); 312 /* 313 * If we got something other than ENOENT, then it exists but we cannot 314 * load it for some other reason. 315 */ 316 if (error != ENOENT) 317 foundfile = 1; 318 if (lf) { 319 linker_file_register_modules(lf); 320 linker_file_register_sysctls(lf); 321 linker_file_sysinit(lf); 322 lf->flags |= LINKER_FILE_LINKED; 323 324 *result = lf; 325 error = 0; 326 goto out; 327 } 328 } 329 /* 330 * Less than ideal, but tells the user whether it failed to load or 331 * the module was not found. 332 */ 333 if (foundfile) 334 error = ENOEXEC; /* Format not recognised (or unloadable) */ 335 else 336 error = ENOENT; /* Nothing found */ 337 338out: 339 return error; 340} 341 342linker_file_t 343linker_find_file_by_name(const char* filename) 344{ 345 linker_file_t lf = 0; 346 char *koname; 347 348 koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK); 349 if (koname == NULL) 350 goto out; 351 sprintf(koname, "%s.ko", filename); 352 353 lockmgr(&lock, LK_SHARED, 0, curproc); 354 TAILQ_FOREACH(lf, &linker_files, link) { 355 if (!strcmp(lf->filename, koname)) 356 break; 357 if (!strcmp(lf->filename, filename)) 358 break; 359 } 360 lockmgr(&lock, LK_RELEASE, 0, curproc); 361 362out: 363 if (koname) 364 free(koname, M_LINKER); 365 return lf; 366} 367 368linker_file_t 369linker_find_file_by_id(int fileid) 370{ 371 linker_file_t lf = 0; 372 373 lockmgr(&lock, LK_SHARED, 0, curproc); 374 TAILQ_FOREACH(lf, &linker_files, link) 375 if (lf->id == fileid) 376 break; 377 lockmgr(&lock, LK_RELEASE, 0, curproc); 378 379 return lf; 380} 381 382linker_file_t 383linker_make_file(const char* pathname, linker_class_t lc) 384{ 385 linker_file_t lf = 0; 386 const char *filename; 387 388 filename = linker_basename(pathname); 389 390 KLD_DPF(FILE, ("linker_make_file: new file, filename=%s\n", filename)); 391 lockmgr(&lock, LK_EXCLUSIVE, 0, curproc); 392 lf = (linker_file_t) kobj_create((kobj_class_t) lc, M_LINKER, M_WAITOK); 393 if (!lf) 394 goto out; 395 396 lf->refs = 1; 397 lf->userrefs = 0; 398 lf->flags = 0; 399 lf->filename = linker_strdup(filename); 400 lf->id = next_file_id++; 401 lf->ndeps = 0; 402 lf->deps = NULL; 403 STAILQ_INIT(&lf->common); 404 TAILQ_INIT(&lf->modules); 405 406 TAILQ_INSERT_TAIL(&linker_files, lf, link); 407 408out: 409 lockmgr(&lock, LK_RELEASE, 0, curproc); 410 return lf; 411} 412 413int 414linker_file_unload(linker_file_t file) 415{ 416 module_t mod, next; 417 modlist_t ml, nextml; 418 struct common_symbol* cp; 419 int error = 0; 420 int i; 421 422 /* Refuse to unload modules if securelevel raised */ 423 if (securelevel > 0) 424 return EPERM; 425 426 KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs)); 427 lockmgr(&lock, LK_EXCLUSIVE, 0, curproc); 428 if (file->refs == 1) { 429 KLD_DPF(FILE, ("linker_file_unload: file is unloading, informing modules\n")); 430 /* 431 * Inform any modules associated with this file. 432 */ 433 for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) { 434 next = module_getfnext(mod); 435 436 /* 437 * Give the module a chance to veto the unload. 438 */ 439 if ((error = module_unload(mod)) != 0) { 440 KLD_DPF(FILE, ("linker_file_unload: module %x vetoes unload\n", 441 mod)); 442 lockmgr(&lock, LK_RELEASE, 0, curproc); 443 goto out; 444 } 445 446 module_release(mod); 447 } 448 } 449 450 file->refs--; 451 if (file->refs > 0) { 452 lockmgr(&lock, LK_RELEASE, 0, curproc); 453 goto out; 454 } 455 456 for (ml = TAILQ_FIRST(&found_modules); ml; ml = nextml) { 457 nextml = TAILQ_NEXT(ml, link); 458 if (ml->container == file) { 459 TAILQ_REMOVE(&found_modules, ml, link); 460 } 461 } 462 463 /* Don't try to run SYSUNINITs if we are unloaded due to a link error */ 464 if (file->flags & LINKER_FILE_LINKED) { 465 linker_file_sysuninit(file); 466 linker_file_unregister_sysctls(file); 467 } 468 469 TAILQ_REMOVE(&linker_files, file, link); 470 lockmgr(&lock, LK_RELEASE, 0, curproc); 471 472 if (file->deps) { 473 for (i = 0; i < file->ndeps; i++) 474 linker_file_unload(file->deps[i]); 475 free(file->deps, M_LINKER); 476 file->deps = NULL; 477 } 478 479 for (cp = STAILQ_FIRST(&file->common); cp; 480 cp = STAILQ_FIRST(&file->common)) { 481 STAILQ_REMOVE(&file->common, cp, common_symbol, link); 482 free(cp, M_LINKER); 483 } 484 485 LINKER_UNLOAD(file); 486 if (file->filename) { 487 free(file->filename, M_LINKER); 488 file->filename = NULL; 489 } 490 kobj_delete((kobj_t) file, M_LINKER); 491 492out: 493 return error; 494} 495 496int 497linker_file_add_dependancy(linker_file_t file, linker_file_t dep) 498{ 499 linker_file_t* newdeps; 500 501 newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t*), 502 M_LINKER, M_WAITOK | M_ZERO); 503 if (newdeps == NULL) 504 return ENOMEM; 505 506 if (file->deps) { 507 bcopy(file->deps, newdeps, file->ndeps * sizeof(linker_file_t*)); 508 free(file->deps, M_LINKER); 509 } 510 file->deps = newdeps; 511 file->deps[file->ndeps] = dep; 512 file->ndeps++; 513 514 return 0; 515} 516 517caddr_t 518linker_file_lookup_symbol(linker_file_t file, const char* name, int deps) 519{ 520 c_linker_sym_t sym; 521 linker_symval_t symval; 522 caddr_t address; 523 size_t common_size = 0; 524 int i; 525 526 KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%x, name=%s, deps=%d\n", 527 file, name, deps)); 528 529 if (LINKER_LOOKUP_SYMBOL(file, name, &sym) == 0) { 530 LINKER_SYMBOL_VALUES(file, sym, &symval); 531 if (symval.value == 0) 532 /* 533 * For commons, first look them up in the dependancies and 534 * only allocate space if not found there. 535 */ 536 common_size = symval.size; 537 else { 538 KLD_DPF(SYM, ("linker_file_lookup_symbol: symbol.value=%x\n", symval.value)); 539 return symval.value; 540 } 541 } 542 543 if (deps) { 544 for (i = 0; i < file->ndeps; i++) { 545 address = linker_file_lookup_symbol(file->deps[i], name, 0); 546 if (address) { 547 KLD_DPF(SYM, ("linker_file_lookup_symbol: deps value=%x\n", address)); 548 return address; 549 } 550 } 551 } 552 553 if (common_size > 0) { 554 /* 555 * This is a common symbol which was not found in the 556 * dependancies. We maintain a simple common symbol table in 557 * the file object. 558 */ 559 struct common_symbol* cp; 560 561 STAILQ_FOREACH(cp, &file->common, link) 562 if (!strcmp(cp->name, name)) { 563 KLD_DPF(SYM, ("linker_file_lookup_symbol: old common value=%x\n", cp->address)); 564 return cp->address; 565 } 566 567 /* 568 * Round the symbol size up to align. 569 */ 570 common_size = (common_size + sizeof(int) - 1) & -sizeof(int); 571 cp = malloc(sizeof(struct common_symbol) 572 + common_size 573 + strlen(name) + 1, 574 M_LINKER, M_WAITOK | M_ZERO); 575 if (!cp) { 576 KLD_DPF(SYM, ("linker_file_lookup_symbol: nomem\n")); 577 return 0; 578 } 579 580 cp->address = (caddr_t) (cp + 1); 581 cp->name = cp->address + common_size; 582 strcpy(cp->name, name); 583 bzero(cp->address, common_size); 584 STAILQ_INSERT_TAIL(&file->common, cp, link); 585 586 KLD_DPF(SYM, ("linker_file_lookup_symbol: new common value=%x\n", cp->address)); 587 return cp->address; 588 } 589 590 KLD_DPF(SYM, ("linker_file_lookup_symbol: fail\n")); 591 return 0; 592} 593 594#ifdef DDB 595/* 596 * DDB Helpers. DDB has to look across multiple files with their own 597 * symbol tables and string tables. 598 * 599 * Note that we do not obey list locking protocols here. We really don't 600 * need DDB to hang because somebody's got the lock held. We'll take the 601 * chance that the files list is inconsistant instead. 602 */ 603 604int 605linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym) 606{ 607 linker_file_t lf; 608 609 TAILQ_FOREACH(lf, &linker_files, link) { 610 if (LINKER_LOOKUP_SYMBOL(lf, symstr, sym) == 0) 611 return 0; 612 } 613 return ENOENT; 614} 615 616int 617linker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp) 618{ 619 linker_file_t lf; 620 u_long off = (uintptr_t)value; 621 u_long diff, bestdiff; 622 c_linker_sym_t best; 623 c_linker_sym_t es; 624 625 best = 0; 626 bestdiff = off; 627 TAILQ_FOREACH(lf, &linker_files, link) { 628 if (LINKER_SEARCH_SYMBOL(lf, value, &es, &diff) != 0) 629 continue; 630 if (es != 0 && diff < bestdiff) { 631 best = es; 632 bestdiff = diff; 633 } 634 if (bestdiff == 0) 635 break; 636 } 637 if (best) { 638 *sym = best; 639 *diffp = bestdiff; 640 return 0; 641 } else { 642 *sym = 0; 643 *diffp = off; 644 return ENOENT; 645 } 646} 647 648int 649linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval) 650{ 651 linker_file_t lf; 652 653 TAILQ_FOREACH(lf, &linker_files, link) { 654 if (LINKER_SYMBOL_VALUES(lf, sym, symval) == 0) 655 return 0; 656 } 657 return ENOENT; 658} 659 660#endif 661 662/* 663 * Syscalls. 664 */ 665 666int 667kldload(struct proc* p, struct kldload_args* uap) 668{ 669 char* pathname, *realpath; 670 const char *filename; 671 linker_file_t lf; 672 int error = 0; 673 674 p->p_retval[0] = -1; 675 676 if (securelevel > 0) /* redundant, but that's OK */ 677 return EPERM; 678 679 if ((error = suser(p)) != 0) 680 return error; 681 682 realpath = NULL; 683 pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 684 if ((error = copyinstr(SCARG(uap, file), pathname, MAXPATHLEN, NULL)) != 0) 685 goto out; 686 687 realpath = linker_search_path(pathname); 688 if (realpath == NULL) { 689 error = ENOENT; 690 goto out; 691 } 692 /* Can't load more than one file with the same name */ 693 filename = linker_basename(realpath); 694 if (linker_find_file_by_name(filename)) { 695 error = EEXIST; 696 goto out; 697 } 698 699 if ((error = linker_load_file(realpath, &lf)) != 0) 700 goto out; 701 702 lf->userrefs++; 703 p->p_retval[0] = lf->id; 704 705out: 706 if (pathname) 707 free(pathname, M_TEMP); 708 if (realpath) 709 free(realpath, M_LINKER); 710 return error; 711} 712 713int 714kldunload(struct proc* p, struct kldunload_args* uap) 715{ 716 linker_file_t lf; 717 int error = 0; 718 719 if (securelevel > 0) /* redundant, but that's OK */ 720 return EPERM; 721 722 if ((error = suser(p)) != 0) 723 return error; 724 725 lf = linker_find_file_by_id(SCARG(uap, fileid)); 726 if (lf) { 727 KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs)); 728 if (lf->userrefs == 0) { 729 printf("kldunload: attempt to unload file that was loaded by the kernel\n"); 730 error = EBUSY; 731 goto out; 732 } 733 lf->userrefs--; 734 error = linker_file_unload(lf); 735 if (error) 736 lf->userrefs++; 737 } else 738 error = ENOENT; 739 740out: 741 return error; 742} 743 744int 745kldfind(struct proc* p, struct kldfind_args* uap) 746{ 747 char* pathname; 748 const char *filename; 749 linker_file_t lf; 750 int error = 0; 751 752 p->p_retval[0] = -1; 753 754 pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 755 if ((error = copyinstr(SCARG(uap, file), pathname, MAXPATHLEN, NULL)) != 0) 756 goto out; 757 758 filename = linker_basename(pathname); 759 760 lf = linker_find_file_by_name(filename); 761 if (lf) 762 p->p_retval[0] = lf->id; 763 else 764 error = ENOENT; 765 766out: 767 if (pathname) 768 free(pathname, M_TEMP); 769 return error; 770} 771 772int 773kldnext(struct proc* p, struct kldnext_args* uap) 774{ 775 linker_file_t lf; 776 int error = 0; 777 778 if (SCARG(uap, fileid) == 0) { 779 if (TAILQ_FIRST(&linker_files)) 780 p->p_retval[0] = TAILQ_FIRST(&linker_files)->id; 781 else 782 p->p_retval[0] = 0; 783 return 0; 784 } 785 786 lf = linker_find_file_by_id(SCARG(uap, fileid)); 787 if (lf) { 788 if (TAILQ_NEXT(lf, link)) 789 p->p_retval[0] = TAILQ_NEXT(lf, link)->id; 790 else 791 p->p_retval[0] = 0; 792 } else 793 error = ENOENT; 794 795 return error; 796} 797 798int 799kldstat(struct proc* p, struct kldstat_args* uap) 800{ 801 linker_file_t lf; 802 int error = 0; 803 int version; 804 struct kld_file_stat* stat; 805 int namelen; 806 807 lf = linker_find_file_by_id(SCARG(uap, fileid)); 808 if (!lf) { 809 error = ENOENT; 810 goto out; 811 } 812 813 stat = SCARG(uap, stat); 814 815 /* 816 * Check the version of the user's structure. 817 */ 818 if ((error = copyin(&stat->version, &version, sizeof(version))) != 0) 819 goto out; 820 if (version != sizeof(struct kld_file_stat)) { 821 error = EINVAL; 822 goto out; 823 } 824 825 namelen = strlen(lf->filename) + 1; 826 if (namelen > MAXPATHLEN) 827 namelen = MAXPATHLEN; 828 if ((error = copyout(lf->filename, &stat->name[0], namelen)) != 0) 829 goto out; 830 if ((error = copyout(&lf->refs, &stat->refs, sizeof(int))) != 0) 831 goto out; 832 if ((error = copyout(&lf->id, &stat->id, sizeof(int))) != 0) 833 goto out; 834 if ((error = copyout(&lf->address, &stat->address, sizeof(caddr_t))) != 0) 835 goto out; 836 if ((error = copyout(&lf->size, &stat->size, sizeof(size_t))) != 0) 837 goto out; 838 839 p->p_retval[0] = 0; 840 841out: 842 return error; 843} 844 845int 846kldfirstmod(struct proc* p, struct kldfirstmod_args* uap) 847{ 848 linker_file_t lf; 849 int error = 0; 850 851 lf = linker_find_file_by_id(SCARG(uap, fileid)); 852 if (lf) { 853 if (TAILQ_FIRST(&lf->modules)) 854 p->p_retval[0] = module_getid(TAILQ_FIRST(&lf->modules)); 855 else 856 p->p_retval[0] = 0; 857 } else 858 error = ENOENT; 859 860 return error; 861} 862 863int 864kldsym(struct proc *p, struct kldsym_args *uap) 865{ 866 char *symstr = NULL; 867 c_linker_sym_t sym; 868 linker_symval_t symval; 869 linker_file_t lf; 870 struct kld_sym_lookup lookup; 871 int error = 0; 872 873 if ((error = copyin(SCARG(uap, data), &lookup, sizeof(lookup))) != 0) 874 goto out; 875 if (lookup.version != sizeof(lookup) || SCARG(uap, cmd) != KLDSYM_LOOKUP) { 876 error = EINVAL; 877 goto out; 878 } 879 880 symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 881 if ((error = copyinstr(lookup.symname, symstr, MAXPATHLEN, NULL)) != 0) 882 goto out; 883 884 if (SCARG(uap, fileid) != 0) { 885 lf = linker_find_file_by_id(SCARG(uap, fileid)); 886 if (lf == NULL) { 887 error = ENOENT; 888 goto out; 889 } 890 if (LINKER_LOOKUP_SYMBOL(lf, symstr, &sym) == 0 && 891 LINKER_SYMBOL_VALUES(lf, sym, &symval) == 0) { 892 lookup.symvalue = (uintptr_t)symval.value; 893 lookup.symsize = symval.size; 894 error = copyout(&lookup, SCARG(uap, data), sizeof(lookup)); 895 } else 896 error = ENOENT; 897 } else { 898 TAILQ_FOREACH(lf, &linker_files, link) { 899 if (LINKER_LOOKUP_SYMBOL(lf, symstr, &sym) == 0 && 900 LINKER_SYMBOL_VALUES(lf, sym, &symval) == 0) { 901 lookup.symvalue = (uintptr_t)symval.value; 902 lookup.symsize = symval.size; 903 error = copyout(&lookup, SCARG(uap, data), sizeof(lookup)); 904 break; 905 } 906 } 907 if (!lf) 908 error = ENOENT; 909 } 910out: 911 if (symstr) 912 free(symstr, M_TEMP); 913 return error; 914} 915 916/* 917 * Preloaded module support 918 */ 919 920static modlist_t 921modlist_lookup(const char *name, int ver) 922{ 923 modlist_t mod; 924 925 TAILQ_FOREACH(mod, &found_modules, link) { 926 if (strcmp(mod->name, name) == 0 && (ver == 0 || mod->version == ver)) 927 return mod; 928 } 929 return NULL; 930} 931 932static modlist_t 933modlist_newmodule(char *modname, int version, linker_file_t container) 934{ 935 modlist_t mod; 936 937 mod = malloc(sizeof(struct modlist), M_LINKER, M_NOWAIT); 938 if (mod == NULL) 939 panic("no memory for module list"); 940 bzero(mod, sizeof(*mod)); 941 mod->container = container; 942 mod->name = modname; 943 mod->version = version; 944 TAILQ_INSERT_TAIL(&found_modules, mod, link); 945 return mod; 946} 947 948/* 949 * This routine is cheap and nasty but will work for data pointers. 950 */ 951static void * 952linker_reloc_ptr(linker_file_t lf, void *offset) 953{ 954 return lf->address + (uintptr_t)offset; 955} 956 957/* 958 * Dereference MDT_VERSION metadata into module name and version 959 */ 960static void 961linker_mdt_version(linker_file_t lf, struct mod_metadata *mp, 962 char **modname, int *version) 963{ 964 struct mod_version *mvp; 965 966 if (modname) 967 *modname = linker_reloc_ptr(lf, mp->md_cval); 968 if (version) { 969 mvp = linker_reloc_ptr(lf, mp->md_data); 970 *version = mvp->mv_version; 971 } 972} 973 974/* 975 * Dereference MDT_DEPEND metadata into module name and mod_depend structure 976 */ 977static void 978linker_mdt_depend(linker_file_t lf, struct mod_metadata *mp, 979 char **modname, struct mod_depend **verinfo) 980{ 981 982 if (modname) 983 *modname = linker_reloc_ptr(lf, mp->md_cval); 984 if (verinfo) 985 *verinfo = linker_reloc_ptr(lf, mp->md_data); 986} 987 988static void 989linker_addmodules(linker_file_t lf, struct linker_set *deps, int preload) 990{ 991 struct mod_metadata *mp; 992 char *modname; 993 int i, ver; 994 995 for (i = 0; i < deps->ls_length; i++) { 996 if (preload) 997 mp = deps->ls_items[i]; 998 else 999 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1000 if (mp->md_type != MDT_VERSION) 1001 continue; 1002 if (preload) { 1003 modname = mp->md_cval; 1004 ver = ((struct mod_version*)mp->md_data)->mv_version; 1005 } else 1006 linker_mdt_version(lf, mp, &modname, &ver); 1007 if (modlist_lookup(modname, ver) != NULL) { 1008 printf("module %s already present!\n", modname); 1009 /* XXX what can we do? this is a build error. :-( */ 1010 continue; 1011 } 1012 modlist_newmodule(modname, ver, lf); 1013 } 1014} 1015 1016static void 1017linker_preload(void* arg) 1018{ 1019 caddr_t modptr; 1020 char *modname, *nmodname; 1021 char *modtype; 1022 linker_file_t lf; 1023 linker_class_t lc; 1024 int error; 1025 struct linker_set *sysinits; 1026 linker_file_list_t loaded_files; 1027 linker_file_list_t depended_files; 1028 struct linker_set *deps; 1029 struct mod_metadata *mp, *nmp; 1030 struct mod_depend *verinfo; 1031 int i, j, nver; 1032 int resolves; 1033 modlist_t mod; 1034 1035 TAILQ_INIT(&loaded_files); 1036 TAILQ_INIT(&depended_files); 1037 TAILQ_INIT(&found_modules); 1038 error = 0; 1039 1040 modptr = NULL; 1041 while ((modptr = preload_search_next_name(modptr)) != NULL) { 1042 modname = (char *)preload_search_info(modptr, MODINFO_NAME); 1043 modtype = (char *)preload_search_info(modptr, MODINFO_TYPE); 1044 if (modname == NULL) { 1045 printf("Preloaded module at %p does not have a name!\n", modptr); 1046 continue; 1047 } 1048 if (modtype == NULL) { 1049 printf("Preloaded module at %p does not have a type!\n", modptr); 1050 continue; 1051 } 1052 printf("Preloaded %s \"%s\" at %p.\n", modtype, modname, modptr); 1053 lf = NULL; 1054 TAILQ_FOREACH(lc, &classes, link) { 1055 error = LINKER_LINK_PRELOAD(lc, modname, &lf); 1056 if (error) { 1057 lf = NULL; 1058 break; 1059 } 1060 } 1061 if (lf) 1062 TAILQ_INSERT_TAIL(&loaded_files, lf, loaded); 1063 } 1064 1065 /* 1066 * First get a list of stuff in the kernel. 1067 */ 1068 deps = (struct linker_set*) 1069 linker_file_lookup_symbol(linker_kernel_file, MDT_SETNAME, 0); 1070 if (deps) 1071 linker_addmodules(linker_kernel_file, deps, 1); 1072 1073 /* 1074 * this is a once-off kinky bubble sort 1075 * resolve relocation dependency requirements 1076 */ 1077restart: 1078 TAILQ_FOREACH(lf, &loaded_files, loaded) { 1079 deps = (struct linker_set*) 1080 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); 1081 /* 1082 * First, look to see if we would successfully link with this stuff. 1083 */ 1084 resolves = 1; /* unless we know otherwise */ 1085 if (deps) { 1086 for (i = 0; i < deps->ls_length; i++) { 1087 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1088 if (mp->md_type != MDT_DEPEND) 1089 continue; 1090 linker_mdt_depend(lf, mp, &modname, &verinfo); 1091 for (j = 0; j < deps->ls_length; j++) { 1092 nmp = linker_reloc_ptr(lf, deps->ls_items[j]); 1093 if (nmp->md_type != MDT_VERSION) 1094 continue; 1095 linker_mdt_version(lf, nmp, &nmodname, NULL); 1096 nmodname = linker_reloc_ptr(lf, nmp->md_cval); 1097 if (strcmp(modname, nmodname) == 0) 1098 break; 1099 } 1100 if (j < deps->ls_length) /* it's a self reference */ 1101 continue; 1102 if (modlist_lookup(modname, 0) == NULL) { 1103 /* ok, the module isn't here yet, we are not finished */ 1104 resolves = 0; 1105 } 1106 } 1107 } 1108 /* 1109 * OK, if we found our modules, we can link. So, "provide" the 1110 * modules inside and add it to the end of the link order list. 1111 */ 1112 if (resolves) { 1113 if (deps) { 1114 for (i = 0; i < deps->ls_length; i++) { 1115 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1116 if (mp->md_type != MDT_VERSION) 1117 continue; 1118 linker_mdt_version(lf, mp, &modname, &nver); 1119 if (modlist_lookup(modname, nver) != NULL) { 1120 printf("module %s already present!\n", modname); 1121 linker_file_unload(lf); 1122 TAILQ_REMOVE(&loaded_files, lf, loaded); 1123 goto restart; /* we changed the tailq next ptr */ 1124 } 1125 modlist_newmodule(modname, nver, lf); 1126 } 1127 } 1128 TAILQ_REMOVE(&loaded_files, lf, loaded); 1129 TAILQ_INSERT_TAIL(&depended_files, lf, loaded); 1130 /* 1131 * Since we provided modules, we need to restart the sort so 1132 * that the previous files that depend on us have a chance. 1133 * Also, we've busted the tailq next pointer with the REMOVE. 1134 */ 1135 goto restart; 1136 } 1137 } 1138 1139 /* 1140 * At this point, we check to see what could not be resolved.. 1141 */ 1142 TAILQ_FOREACH(lf, &loaded_files, loaded) { 1143 printf("KLD file %s is missing dependencies\n", lf->filename); 1144 linker_file_unload(lf); 1145 TAILQ_REMOVE(&loaded_files, lf, loaded); 1146 } 1147 1148 /* 1149 * We made it. Finish off the linking in the order we determined. 1150 */ 1151 TAILQ_FOREACH(lf, &depended_files, loaded) { 1152 if (linker_kernel_file) { 1153 linker_kernel_file->refs++; 1154 error = linker_file_add_dependancy(lf, linker_kernel_file); 1155 if (error) 1156 panic("cannot add dependency"); 1157 } 1158 lf->userrefs++; /* so we can (try to) kldunload it */ 1159 deps = (struct linker_set*) 1160 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); 1161 if (deps) { 1162 for (i = 0; i < deps->ls_length; i++) { 1163 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1164 if (mp->md_type != MDT_DEPEND) 1165 continue; 1166 linker_mdt_depend(lf, mp, &modname, &verinfo); 1167 mod = modlist_lookup(modname, 0); 1168 mod->container->refs++; 1169 error = linker_file_add_dependancy(lf, mod->container); 1170 if (error) 1171 panic("cannot add dependency"); 1172 } 1173 } 1174 1175 /* Now do relocation etc using the symbol search paths established by the dependencies */ 1176 error = LINKER_LINK_PRELOAD_FINISH(lf); 1177 if (error) { 1178 printf("KLD file %s - could not finalize loading\n", lf->filename); 1179 linker_file_unload(lf); 1180 continue; 1181 } 1182 1183 linker_file_register_modules(lf); 1184 sysinits = (struct linker_set*) 1185 linker_file_lookup_symbol(lf, "sysinit_set", 0); 1186 if (sysinits) 1187 sysinit_add((struct sysinit **)sysinits->ls_items); 1188 linker_file_register_sysctls(lf); 1189 lf->flags |= LINKER_FILE_LINKED; 1190 } 1191 /* woohoo! we made it! */ 1192} 1193 1194SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0); 1195 1196/* 1197 * Search for a not-loaded module by name. 1198 * 1199 * Modules may be found in the following locations: 1200 * 1201 * - preloaded (result is just the module name) 1202 * - on disk (result is full path to module) 1203 * 1204 * If the module name is qualified in any way (contains path, etc.) 1205 * the we simply return a copy of it. 1206 * 1207 * The search path can be manipulated via sysctl. Note that we use the ';' 1208 * character as a separator to be consistent with the bootloader. 1209 */ 1210
|