1 /*- 2 * Copyright (c) 1997 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 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 #ifdef KLD_DEBUG 48 int kld_debug = 0; 49 #endif 50 51 MALLOC_DEFINE(M_LINKER, "kld", "kernel linker"); 52 linker_file_t linker_current_file; 53 linker_file_t linker_kernel_file; 54 55 static struct lock lock; /* lock for the file list */ 56 static linker_class_list_t classes; 57 static linker_file_list_t linker_files; 58 static int next_file_id = 1; 59 60 static void 61 linker_init(void* arg) 62 { 63 lockinit(&lock, PVM, "klink", 0, 0); 64 TAILQ_INIT(&classes); 65 TAILQ_INIT(&linker_files); 66 } 67 68 SYSINIT(linker, SI_SUB_KLD, SI_ORDER_FIRST, linker_init, 0); 69 70 int 71 linker_add_class(const char* desc, void* priv, 72 struct linker_class_ops* ops) 73 { 74 linker_class_t lc; 75 76 lc = malloc(sizeof(struct linker_class), M_LINKER, M_NOWAIT); 77 if (!lc) 78 return ENOMEM; 79 bzero(lc, sizeof(*lc)); 80 81 lc->desc = desc; 82 lc->priv = priv; 83 lc->ops = ops; 84 TAILQ_INSERT_HEAD(&classes, lc, link); 85 86 return 0; 87 } 88 89 static void 90 linker_file_sysinit(linker_file_t lf) 91 { 92 struct linker_set* sysinits; 93 struct sysinit** sipp; 94 struct sysinit** xipp; 95 struct sysinit* save; 96 const moduledata_t *moddata; 97 int error; 98 99 KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n", 100 lf->filename)); 101 102 sysinits = (struct linker_set*) 103 linker_file_lookup_symbol(lf, "sysinit_set", 0); 104 105 KLD_DPF(FILE, ("linker_file_sysinit: SYSINITs %p\n", sysinits)); 106 if (!sysinits) 107 return; 108 109 /* HACK ALERT! */ 110 for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) { 111 if ((*sipp)->func == module_register_init) { 112 moddata = (*sipp)->udata; 113 error = module_register(moddata, lf); 114 if (error) 115 printf("linker_file_sysinit \"%s\" failed to register! %d\n", 116 lf->filename, error); 117 } 118 } 119 120 /* 121 * Perform a bubble sort of the system initialization objects by 122 * their subsystem (primary key) and order (secondary key). 123 * 124 * Since some things care about execution order, this is the 125 * operation which ensures continued function. 126 */ 127 for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) { 128 for (xipp = sipp + 1; *xipp; xipp++) { 129 if ((*sipp)->subsystem <= (*xipp)->subsystem || 130 ((*sipp)->subsystem == (*xipp)->subsystem && 131 (*sipp)->order <= (*xipp)->order)) 132 continue; /* skip*/ 133 save = *sipp; 134 *sipp = *xipp; 135 *xipp = save; 136 } 137 } 138 139 140 /* 141 * Traverse the (now) ordered list of system initialization tasks. 142 * Perform each task, and continue on to the next task. 143 */ 144 for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) { 145 if ((*sipp)->subsystem == SI_SUB_DUMMY) 146 continue; /* skip dummy task(s)*/ 147 148 /* Call function */ 149 (*((*sipp)->func))((*sipp)->udata); 150 } 151 } 152 153 static void 154 linker_file_sysuninit(linker_file_t lf) 155 { 156 struct linker_set* sysuninits; 157 struct sysinit** sipp; 158 struct sysinit** xipp; 159 struct sysinit* save; 160 161 KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n", 162 lf->filename)); 163 164 sysuninits = (struct linker_set*) 165 linker_file_lookup_symbol(lf, "sysuninit_set", 0); 166 167 KLD_DPF(FILE, ("linker_file_sysuninit: SYSUNINITs %p\n", sysuninits)); 168 if (!sysuninits) 169 return; 170 171 /* 172 * Perform a reverse bubble sort of the system initialization objects 173 * by their subsystem (primary key) and order (secondary key). 174 * 175 * Since some things care about execution order, this is the 176 * operation which ensures continued function. 177 */ 178 for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) { 179 for (xipp = sipp + 1; *xipp; xipp++) { 180 if ((*sipp)->subsystem >= (*xipp)->subsystem || 181 ((*sipp)->subsystem == (*xipp)->subsystem && 182 (*sipp)->order >= (*xipp)->order)) 183 continue; /* skip*/ 184 save = *sipp; 185 *sipp = *xipp; 186 *xipp = save; 187 } 188 } 189 190 191 /* 192 * Traverse the (now) ordered list of system initialization tasks. 193 * Perform each task, and continue on to the next task. 194 */ 195 for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) { 196 if ((*sipp)->subsystem == SI_SUB_DUMMY) 197 continue; /* skip dummy task(s)*/ 198 199 /* Call function */ 200 (*((*sipp)->func))((*sipp)->udata); 201 } 202 } 203 204 static void 205 linker_file_register_sysctls(linker_file_t lf) 206 { 207 struct linker_set* sysctls; 208 209 KLD_DPF(FILE, ("linker_file_register_sysctls: registering SYSCTLs for %s\n", 210 lf->filename)); 211 212 sysctls = (struct linker_set*) 213 linker_file_lookup_symbol(lf, "sysctl_set", 0); 214 215 KLD_DPF(FILE, ("linker_file_register_sysctls: SYSCTLs %p\n", sysctls)); 216 if (!sysctls) 217 return; 218 219 sysctl_register_set(sysctls); 220 } 221 222 static void 223 linker_file_unregister_sysctls(linker_file_t lf) 224 { 225 struct linker_set* sysctls; 226 227 KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs for %s\n", 228 lf->filename)); 229 230 sysctls = (struct linker_set*) 231 linker_file_lookup_symbol(lf, "sysctl_set", 0); 232 233 KLD_DPF(FILE, ("linker_file_unregister_sysctls: SYSCTLs %p\n", sysctls)); 234 if (!sysctls) 235 return; 236 237 sysctl_unregister_set(sysctls); 238 } 239 240 int 241 linker_load_file(const char* filename, linker_file_t* result) 242 { 243 linker_class_t lc; 244 linker_file_t lf; 245 int foundfile, error = 0; 246 char *koname = NULL; 247 248 lf = linker_find_file_by_name(filename); 249 if (lf) { 250 KLD_DPF(FILE, ("linker_load_file: file %s is already loaded, incrementing refs\n", filename)); 251 *result = lf; 252 lf->refs++; 253 goto out; 254 } 255 256 koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK); 257 if (koname == NULL) { 258 error = ENOMEM; 259 goto out; 260 } 261 sprintf(koname, "%s.ko", filename); 262 lf = NULL; 263 foundfile = 0; 264 for (lc = TAILQ_FIRST(&classes); lc; lc = TAILQ_NEXT(lc, link)) { 265 KLD_DPF(FILE, ("linker_load_file: trying to load %s as %s\n", 266 filename, lc->desc)); 267 268 error = lc->ops->load_file(koname, &lf); /* First with .ko */ 269 if (lf == NULL && error == ENOENT) 270 error = lc->ops->load_file(filename, &lf); /* Then try without */ 271 /* 272 * If we got something other than ENOENT, then it exists but we cannot 273 * load it for some other reason. 274 */ 275 if (error != ENOENT) 276 foundfile = 1; 277 if (lf) { 278 linker_file_register_sysctls(lf); 279 linker_file_sysinit(lf); 280 281 *result = lf; 282 error = 0; 283 goto out; 284 } 285 } 286 /* 287 * Less than ideal, but tells the user whether it failed to load or 288 * the module was not found. 289 */ 290 if (foundfile) 291 error = ENOEXEC; /* Format not recognised (or unloadable) */ 292 else 293 error = ENOENT; /* Nothing found */ 294 295 out: 296 if (koname) 297 free(koname, M_LINKER); 298 return error; 299 } 300 301 linker_file_t 302 linker_find_file_by_name(const char* filename) 303 { 304 linker_file_t lf = 0; 305 char *koname; 306 307 koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK); 308 if (koname == NULL) 309 goto out; 310 sprintf(koname, "%s.ko", filename); 311 312 lockmgr(&lock, LK_SHARED, 0, curproc); 313 for (lf = TAILQ_FIRST(&linker_files); lf; lf = TAILQ_NEXT(lf, link)) { 314 if (!strcmp(lf->filename, koname)) 315 break; 316 if (!strcmp(lf->filename, filename)) 317 break; 318 } 319 lockmgr(&lock, LK_RELEASE, 0, curproc); 320 321 out: 322 if (koname) 323 free(koname, M_LINKER); 324 return lf; 325 } 326 327 linker_file_t 328 linker_find_file_by_id(int fileid) 329 { 330 linker_file_t lf = 0; 331 332 lockmgr(&lock, LK_SHARED, 0, curproc); 333 for (lf = TAILQ_FIRST(&linker_files); lf; lf = TAILQ_NEXT(lf, link)) 334 if (lf->id == fileid) 335 break; 336 lockmgr(&lock, LK_RELEASE, 0, curproc); 337 338 return lf; 339 } 340 341 linker_file_t 342 linker_make_file(const char* pathname, void* priv, struct linker_file_ops* ops) 343 { 344 linker_file_t lf = 0; 345 int namelen; 346 const char *filename; 347 348 filename = rindex(pathname, '/'); 349 if (filename && filename[1]) 350 filename++; 351 else 352 filename = pathname; 353 354 KLD_DPF(FILE, ("linker_make_file: new file, filename=%s\n", filename)); 355 lockmgr(&lock, LK_EXCLUSIVE, 0, curproc); 356 namelen = strlen(filename) + 1; 357 lf = malloc(sizeof(struct linker_file) + namelen, M_LINKER, M_WAITOK); 358 if (!lf) 359 goto out; 360 bzero(lf, sizeof(*lf)); 361 362 lf->refs = 1; 363 lf->userrefs = 0; 364 lf->flags = 0; 365 lf->filename = (char*) (lf + 1); 366 strcpy(lf->filename, filename); 367 lf->id = next_file_id++; 368 lf->ndeps = 0; 369 lf->deps = NULL; 370 STAILQ_INIT(&lf->common); 371 TAILQ_INIT(&lf->modules); 372 373 lf->priv = priv; 374 lf->ops = ops; 375 TAILQ_INSERT_TAIL(&linker_files, lf, link); 376 377 out: 378 lockmgr(&lock, LK_RELEASE, 0, curproc); 379 return lf; 380 } 381 382 int 383 linker_file_unload(linker_file_t file) 384 { 385 module_t mod, next; 386 struct common_symbol* cp; 387 int error = 0; 388 int i; 389 390 KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs)); 391 lockmgr(&lock, LK_EXCLUSIVE, 0, curproc); 392 if (file->refs == 1) { 393 KLD_DPF(FILE, ("linker_file_unload: file is unloading, informing modules\n")); 394 /* 395 * Inform any modules associated with this file. 396 */ 397 for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) { 398 next = module_getfnext(mod); 399 400 /* 401 * Give the module a chance to veto the unload. 402 */ 403 if ((error = module_unload(mod)) != 0) { 404 KLD_DPF(FILE, ("linker_file_unload: module %x vetoes unload\n", 405 mod)); 406 lockmgr(&lock, LK_RELEASE, 0, curproc); 407 goto out; 408 } 409 410 module_release(mod); 411 } 412 } 413 414 file->refs--; 415 if (file->refs > 0) { 416 lockmgr(&lock, LK_RELEASE, 0, curproc); 417 goto out; 418 } 419 420 /* Don't try to run SYSUNINITs if we are unloaded due to a link error */ 421 if (file->flags & LINKER_FILE_LINKED) { 422 linker_file_sysuninit(file); 423 linker_file_unregister_sysctls(file); 424 } 425 426 TAILQ_REMOVE(&linker_files, file, link); 427 lockmgr(&lock, LK_RELEASE, 0, curproc); 428 429 for (i = 0; i < file->ndeps; i++) 430 linker_file_unload(file->deps[i]); 431 free(file->deps, M_LINKER); 432 433 for (cp = STAILQ_FIRST(&file->common); cp; 434 cp = STAILQ_FIRST(&file->common)) { 435 STAILQ_REMOVE(&file->common, cp, common_symbol, link); 436 free(cp, M_LINKER); 437 } 438 439 file->ops->unload(file); 440 free(file, M_LINKER); 441 442 out: 443 return error; 444 } 445 446 int 447 linker_file_add_dependancy(linker_file_t file, linker_file_t dep) 448 { 449 linker_file_t* newdeps; 450 451 newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t*), 452 M_LINKER, M_WAITOK); 453 if (newdeps == NULL) 454 return ENOMEM; 455 bzero(newdeps, (file->ndeps + 1) * sizeof(linker_file_t*)); 456 457 if (file->deps) { 458 bcopy(file->deps, newdeps, file->ndeps * sizeof(linker_file_t*)); 459 free(file->deps, M_LINKER); 460 } 461 file->deps = newdeps; 462 file->deps[file->ndeps] = dep; 463 file->ndeps++; 464 465 return 0; 466 } 467 468 caddr_t 469 linker_file_lookup_symbol(linker_file_t file, const char* name, int deps) 470 { 471 c_linker_sym_t sym; 472 linker_symval_t symval; 473 linker_file_t lf; 474 caddr_t address; 475 size_t common_size = 0; 476 int i; 477 478 KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%x, name=%s, deps=%d\n", 479 file, name, deps)); 480 481 if (file->ops->lookup_symbol(file, name, &sym) == 0) { 482 file->ops->symbol_values(file, sym, &symval); 483 if (symval.value == 0) 484 /* 485 * For commons, first look them up in the dependancies and 486 * only allocate space if not found there. 487 */ 488 common_size = symval.size; 489 else { 490 KLD_DPF(SYM, ("linker_file_lookup_symbol: symbol.value=%x\n", symval.value)); 491 return symval.value; 492 } 493 } 494 495 if (deps) { 496 for (i = 0; i < file->ndeps; i++) { 497 address = linker_file_lookup_symbol(file->deps[i], name, 0); 498 if (address) { 499 KLD_DPF(SYM, ("linker_file_lookup_symbol: deps value=%x\n", address)); 500 return address; 501 } 502 } 503 504 /* If we have not found it in the dependencies, search globally */ 505 for (lf = TAILQ_FIRST(&linker_files); lf; lf = TAILQ_NEXT(lf, link)) { 506 /* But skip the current file if it's on the list */ 507 if (lf == file) 508 continue; 509 /* And skip the files we searched above */ 510 for (i = 0; i < file->ndeps; i++) 511 if (lf == file->deps[i]) 512 break; 513 if (i < file->ndeps) 514 continue; 515 address = linker_file_lookup_symbol(lf, name, 0); 516 if (address) { 517 KLD_DPF(SYM, ("linker_file_lookup_symbol: global value=%x\n", address)); 518 return address; 519 } 520 } 521 } 522 523 if (common_size > 0) { 524 /* 525 * This is a common symbol which was not found in the 526 * dependancies. We maintain a simple common symbol table in 527 * the file object. 528 */ 529 struct common_symbol* cp; 530 531 for (cp = STAILQ_FIRST(&file->common); cp; 532 cp = STAILQ_NEXT(cp, link)) 533 if (!strcmp(cp->name, name)) { 534 KLD_DPF(SYM, ("linker_file_lookup_symbol: old common value=%x\n", cp->address)); 535 return cp->address; 536 } 537 538 /* 539 * Round the symbol size up to align. 540 */ 541 common_size = (common_size + sizeof(int) - 1) & -sizeof(int); 542 cp = malloc(sizeof(struct common_symbol) 543 + common_size 544 + strlen(name) + 1, 545 M_LINKER, M_WAITOK); 546 if (!cp) { 547 KLD_DPF(SYM, ("linker_file_lookup_symbol: nomem\n")); 548 return 0; 549 } 550 bzero(cp, sizeof(struct common_symbol) + common_size + strlen(name)+ 1); 551 552 cp->address = (caddr_t) (cp + 1); 553 cp->name = cp->address + common_size; 554 strcpy(cp->name, name); 555 bzero(cp->address, common_size); 556 STAILQ_INSERT_TAIL(&file->common, cp, link); 557 558 KLD_DPF(SYM, ("linker_file_lookup_symbol: new common value=%x\n", cp->address)); 559 return cp->address; 560 } 561 562 KLD_DPF(SYM, ("linker_file_lookup_symbol: fail\n")); 563 return 0; 564 } 565 566 #ifdef DDB 567 /* 568 * DDB Helpers. DDB has to look across multiple files with their own 569 * symbol tables and string tables. 570 * 571 * Note that we do not obey list locking protocols here. We really don't 572 * need DDB to hang because somebody's got the lock held. We'll take the 573 * chance that the files list is inconsistant instead. 574 */ 575 576 int 577 linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym) 578 { 579 linker_file_t lf; 580 581 for (lf = TAILQ_FIRST(&linker_files); lf; lf = TAILQ_NEXT(lf, link)) { 582 if (lf->ops->lookup_symbol(lf, symstr, sym) == 0) 583 return 0; 584 } 585 return ENOENT; 586 } 587 588 int 589 linker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp) 590 { 591 linker_file_t lf; 592 u_long off = (uintptr_t)value; 593 u_long diff, bestdiff; 594 c_linker_sym_t best; 595 c_linker_sym_t es; 596 597 best = 0; 598 bestdiff = off; 599 for (lf = TAILQ_FIRST(&linker_files); lf; lf = TAILQ_NEXT(lf, link)) { 600 if (lf->ops->search_symbol(lf, value, &es, &diff) != 0) 601 continue; 602 if (es != 0 && diff < bestdiff) { 603 best = es; 604 bestdiff = diff; 605 } 606 if (bestdiff == 0) 607 break; 608 } 609 if (best) { 610 *sym = best; 611 *diffp = bestdiff; 612 return 0; 613 } else { 614 *sym = 0; 615 *diffp = off; 616 return ENOENT; 617 } 618 } 619 620 int 621 linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval) 622 { 623 linker_file_t lf; 624 625 for (lf = TAILQ_FIRST(&linker_files); lf; lf = TAILQ_NEXT(lf, link)) { 626 if (lf->ops->symbol_values(lf, sym, symval) == 0) 627 return 0; 628 } 629 return ENOENT; 630 } 631 632 #endif 633 634 /* 635 * Syscalls. 636 */ 637 638 int 639 kldload(struct proc* p, struct kldload_args* uap) 640 { 641 char* filename = NULL, *modulename; 642 linker_file_t lf; 643 int error = 0; 644 645 p->p_retval[0] = -1; 646 647 if (securelevel > 0) 648 return EPERM; 649 650 if ((error = suser(p)) != 0) 651 return error; 652 653 filename = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 654 if ((error = copyinstr(SCARG(uap, file), filename, MAXPATHLEN, NULL)) != 0) 655 goto out; 656 657 /* Can't load more than one module with the same name */ 658 modulename = rindex(filename, '/'); 659 if (modulename == NULL) 660 modulename = filename; 661 else 662 modulename++; 663 if (linker_find_file_by_name(modulename)) { 664 error = EEXIST; 665 goto out; 666 } 667 668 if ((error = linker_load_file(filename, &lf)) != 0) 669 goto out; 670 671 lf->userrefs++; 672 p->p_retval[0] = lf->id; 673 674 out: 675 if (filename) 676 free(filename, M_TEMP); 677 return error; 678 } 679 680 int 681 kldunload(struct proc* p, struct kldunload_args* uap) 682 { 683 linker_file_t lf; 684 int error = 0; 685 686 if (securelevel > 0) 687 return EPERM; 688 689 if ((error = suser(p)) != 0) 690 return error; 691 692 lf = linker_find_file_by_id(SCARG(uap, fileid)); 693 if (lf) { 694 KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs)); 695 if (lf->userrefs == 0) { 696 printf("linkerunload: attempt to unload file that was loaded by the kernel\n"); 697 error = EBUSY; 698 goto out; 699 } 700 lf->userrefs--; 701 error = linker_file_unload(lf); 702 if (error) 703 lf->userrefs++; 704 } else 705 error = ENOENT; 706 707 out: 708 return error; 709 } 710 711 int 712 kldfind(struct proc* p, struct kldfind_args* uap) 713 { 714 char* filename = NULL, *modulename; 715 linker_file_t lf; 716 int error = 0; 717 718 p->p_retval[0] = -1; 719 720 filename = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 721 if ((error = copyinstr(SCARG(uap, file), filename, MAXPATHLEN, NULL)) != 0) 722 goto out; 723 724 modulename = rindex(filename, '/'); 725 if (modulename == NULL) 726 modulename = filename; 727 728 lf = linker_find_file_by_name(modulename); 729 if (lf) 730 p->p_retval[0] = lf->id; 731 else 732 error = ENOENT; 733 734 out: 735 if (filename) 736 free(filename, M_TEMP); 737 return error; 738 } 739 740 int 741 kldnext(struct proc* p, struct kldnext_args* uap) 742 { 743 linker_file_t lf; 744 int error = 0; 745 746 if (SCARG(uap, fileid) == 0) { 747 if (TAILQ_FIRST(&linker_files)) 748 p->p_retval[0] = TAILQ_FIRST(&linker_files)->id; 749 else 750 p->p_retval[0] = 0; 751 return 0; 752 } 753 754 lf = linker_find_file_by_id(SCARG(uap, fileid)); 755 if (lf) { 756 if (TAILQ_NEXT(lf, link)) 757 p->p_retval[0] = TAILQ_NEXT(lf, link)->id; 758 else 759 p->p_retval[0] = 0; 760 } else 761 error = ENOENT; 762 763 return error; 764 } 765 766 int 767 kldstat(struct proc* p, struct kldstat_args* uap) 768 { 769 linker_file_t lf; 770 int error = 0; 771 int version; 772 struct kld_file_stat* stat; 773 int namelen; 774 775 lf = linker_find_file_by_id(SCARG(uap, fileid)); 776 if (!lf) { 777 error = ENOENT; 778 goto out; 779 } 780 781 stat = SCARG(uap, stat); 782 783 /* 784 * Check the version of the user's structure. 785 */ 786 if ((error = copyin(&stat->version, &version, sizeof(version))) != 0) 787 goto out; 788 if (version != sizeof(struct kld_file_stat)) { 789 error = EINVAL; 790 goto out; 791 } 792 793 namelen = strlen(lf->filename) + 1; 794 if (namelen > MAXPATHLEN) 795 namelen = MAXPATHLEN; 796 if ((error = copyout(lf->filename, &stat->name[0], namelen)) != 0) 797 goto out; 798 if ((error = copyout(&lf->refs, &stat->refs, sizeof(int))) != 0) 799 goto out; 800 if ((error = copyout(&lf->id, &stat->id, sizeof(int))) != 0) 801 goto out; 802 if ((error = copyout(&lf->address, &stat->address, sizeof(caddr_t))) != 0) 803 goto out; 804 if ((error = copyout(&lf->size, &stat->size, sizeof(size_t))) != 0) 805 goto out; 806 807 p->p_retval[0] = 0; 808 809 out: 810 return error; 811 } 812 813 int 814 kldfirstmod(struct proc* p, struct kldfirstmod_args* uap) 815 { 816 linker_file_t lf; 817 int error = 0; 818 819 lf = linker_find_file_by_id(SCARG(uap, fileid)); 820 if (lf) { 821 if (TAILQ_FIRST(&lf->modules)) 822 p->p_retval[0] = module_getid(TAILQ_FIRST(&lf->modules)); 823 else 824 p->p_retval[0] = 0; 825 } else 826 error = ENOENT; 827 828 return error; 829 } 830 831 int 832 kldsym(struct proc *p, struct kldsym_args *uap) 833 { 834 char *symstr = NULL; 835 c_linker_sym_t sym; 836 linker_symval_t symval; 837 linker_file_t lf; 838 struct kld_sym_lookup lookup; 839 int error = 0; 840 841 if ((error = copyin(SCARG(uap, data), &lookup, sizeof(lookup))) != 0) 842 goto out; 843 if (lookup.version != sizeof(lookup) || SCARG(uap, cmd) != KLDSYM_LOOKUP) { 844 error = EINVAL; 845 goto out; 846 } 847 848 symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 849 if ((error = copyinstr(lookup.symname, symstr, MAXPATHLEN, NULL)) != 0) 850 goto out; 851 852 if (SCARG(uap, fileid) != 0) { 853 lf = linker_find_file_by_id(SCARG(uap, fileid)); 854 if (lf == NULL) { 855 error = ENOENT; 856 goto out; 857 } 858 if (lf->ops->lookup_symbol(lf, symstr, &sym) == 0 && 859 lf->ops->symbol_values(lf, sym, &symval) == 0) { 860 lookup.symvalue = (uintptr_t)symval.value; 861 lookup.symsize = symval.size; 862 error = copyout(&lookup, SCARG(uap, data), sizeof(lookup)); 863 } else 864 error = ENOENT; 865 } else { 866 for (lf = TAILQ_FIRST(&linker_files); lf; lf = TAILQ_NEXT(lf, link)) { 867 if (lf->ops->lookup_symbol(lf, symstr, &sym) == 0 && 868 lf->ops->symbol_values(lf, sym, &symval) == 0) { 869 lookup.symvalue = (uintptr_t)symval.value; 870 lookup.symsize = symval.size; 871 error = copyout(&lookup, SCARG(uap, data), sizeof(lookup)); 872 break; 873 } 874 } 875 if (!lf) 876 error = ENOENT; 877 } 878 out: 879 if (symstr) 880 free(symstr, M_TEMP); 881 return error; 882 } 883 884 /* 885 * Preloaded module support 886 */ 887 888 static void 889 linker_preload(void* arg) 890 { 891 caddr_t modptr; 892 char *modname; 893 char *modtype; 894 linker_file_t lf; 895 linker_class_t lc; 896 int error; 897 struct linker_set *sysinits; 898 struct sysinit **sipp; 899 const moduledata_t *moddata; 900 901 modptr = NULL; 902 while ((modptr = preload_search_next_name(modptr)) != NULL) { 903 modname = (char *)preload_search_info(modptr, MODINFO_NAME); 904 modtype = (char *)preload_search_info(modptr, MODINFO_TYPE); 905 if (modname == NULL) { 906 printf("Preloaded module at %p does not have a name!\n", modptr); 907 continue; 908 } 909 if (modtype == NULL) { 910 printf("Preloaded module at %p does not have a type!\n", modptr); 911 continue; 912 } 913 printf("Preloaded %s \"%s\" at %p.\n", modtype, modname, modptr); 914 lf = linker_find_file_by_name(modname); 915 if (lf) { 916 lf->userrefs++; 917 continue; 918 } 919 lf = NULL; 920 for (lc = TAILQ_FIRST(&classes); lc; lc = TAILQ_NEXT(lc, link)) { 921 error = lc->ops->load_file(modname, &lf); 922 if (error) { 923 lf = NULL; 924 break; 925 } 926 } 927 if (lf) { 928 lf->userrefs++; 929 930 sysinits = (struct linker_set*) 931 linker_file_lookup_symbol(lf, "sysinit_set", 0); 932 if (sysinits) { 933 /* HACK ALERT! 934 * This is to set the sysinit moduledata so that the module 935 * can attach itself to the correct containing file. 936 * The sysinit could be run at *any* time. 937 */ 938 for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) { 939 if ((*sipp)->func == module_register_init) { 940 moddata = (*sipp)->udata; 941 error = module_register(moddata, lf); 942 if (error) 943 printf("Preloaded %s \"%s\" failed to register: %d\n", 944 modtype, modname, error); 945 } 946 } 947 sysinit_add((struct sysinit **)sysinits->ls_items); 948 } 949 linker_file_register_sysctls(lf); 950 } 951 } 952 } 953 954 SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0); 955 956 /* 957 * Search for a not-loaded module by name. 958 * 959 * Modules may be found in the following locations: 960 * 961 * - preloaded (result is just the module name) 962 * - on disk (result is full path to module) 963 * 964 * If the module name is qualified in any way (contains path, etc.) 965 * the we simply return a copy of it. 966 * 967 * The search path can be manipulated via sysctl. Note that we use the ';' 968 * character as a separator to be consistent with the bootloader. 969 */ 970 971 static char linker_path[MAXPATHLEN] = "/;/boot/;/modules/"; 972 973 SYSCTL_STRING(_kern, OID_AUTO, module_path, CTLFLAG_RW, linker_path, 974 sizeof(linker_path), "module load search path"); 975 976 static char * 977 linker_strdup(const char *str) 978 { 979 char *result; 980 981 if ((result = malloc((strlen(str) + 1), M_LINKER, M_WAITOK)) != NULL) 982 strcpy(result, str); 983 return(result); 984 } 985 986 char * 987 linker_search_path(const char *name) 988 { 989 struct nameidata nd; 990 struct proc *p = curproc; /* XXX */ 991 char *cp, *ep, *result; 992 int error; 993 enum vtype type; 994 995 /* qualified at all? */ 996 if (index(name, '/')) 997 return(linker_strdup(name)); 998 999 /* traverse the linker path */ 1000 cp = linker_path; 1001 for (;;) { 1002 1003 /* find the end of this component */ 1004 for (ep = cp; (*ep != 0) && (*ep != ';'); ep++) 1005 ; 1006 result = malloc((strlen(name) + (ep - cp) + 1), M_LINKER, M_WAITOK); 1007 if (result == NULL) /* actually ENOMEM */ 1008 return(NULL); 1009 1010 strncpy(result, cp, ep - cp); 1011 strcpy(result + (ep - cp), name); 1012 1013 /* 1014 * Attempt to open the file, and return the path if we succeed and it's 1015 * a regular file. 1016 */ 1017 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, result, p); 1018 error = vn_open(&nd, FREAD, 0); 1019 if (error == 0) { 1020 type = nd.ni_vp->v_type; 1021 VOP_UNLOCK(nd.ni_vp, 0, p); 1022 vn_close(nd.ni_vp, FREAD, p->p_ucred, p); 1023 if (type == VREG) 1024 return(result); 1025 } 1026 free(result, M_LINKER); 1027 1028 if (*ep == 0) 1029 break; 1030 cp = ep + 1; 1031 } 1032 return(NULL); 1033 } 1034