1/*- 2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 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 unchanged lines hidden (view full) --- 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 * $Id: module.c,v 1.3 1998/09/03 02:10:08 msmith Exp $ |
27 */ 28 29/* 30 * module function dispatcher, support, etc. |
31 */ 32 33#include <stand.h> 34#include <string.h> 35 36#include "bootstrap.h" 37 38static struct loaded_module *mod_loadmodule(char *name, int argc, char *argv[]); 39static char *mod_searchdep(struct loaded_module *mp); |
40static char *mod_searchfile(char *name); |
41static char *mod_searchmodule(char *name); 42static void mod_append(struct loaded_module *mp); 43 |
44/* load address should be tweaked by first module loaded (kernel) */ |
45static vm_offset_t loadaddr = 0; 46 |
47static char *default_searchpath ="/;/boot"; 48 |
49struct loaded_module *loaded_modules = NULL; 50 51/* 52 * load an object, either a disk file or code module. 53 * 54 * To load a file, the syntax is: 55 * 56 * load -t <type> <path> --- 169 unchanged lines hidden (view full) --- 226 vm_offset_t laddr; 227 228 /* We can't load first */ 229 if ((mod_findmodule(NULL, NULL)) == NULL) { 230 command_errmsg = "can't load file before kernel"; 231 return(CMD_ERROR); 232 } 233 |
234 /* locate the file on the load path */ 235 cp = mod_searchfile(name); 236 if (cp == NULL) { 237 sprintf(command_errbuf, "can't find '%s'", name); 238 return(CMD_ERROR); 239 } 240 name = cp; |
241 242 if ((fd = open(name, O_RDONLY)) < 0) { 243 sprintf(command_errbuf, "can't open '%s': %s", name, strerror(errno)); 244 return(CMD_ERROR); 245 } 246 247 laddr = loadaddr; 248 for (;;) { --- 32 unchanged lines hidden (view full) --- 281 */ 282static struct loaded_module * 283mod_loadmodule(char *name, int argc, char *argv[]) 284{ 285 struct loaded_module *mp; 286 int i, err; 287 char *cp; 288 |
289 /* locate the module on the search path */ 290 cp = mod_searchmodule(name); 291 if (cp == NULL) { 292 sprintf(command_errbuf, "can't find '%s'", name); 293 return(NULL); 294 } 295 name = cp; 296 |
297 err = 0; 298 for (i = 0, mp = NULL; (module_formats[i] != NULL) && (mp == NULL); i++) { 299 if ((err = (module_formats[i]->l_load)(name, loadaddr, &mp)) != 0) { 300 301 /* Unknown to this handler? */ 302 if (err == EFTYPE) 303 continue; 304 --- 121 unchanged lines hidden (view full) --- 426 427 for (md = mp->m_metadata; md != NULL; md = md->md_next) 428 if (md->md_type == type) 429 break; 430 return(md); 431} 432 433/* |
434 * Attempt to find the file (name) on the module searchpath. |
435 * If (name) is qualified in any way, we simply check it and 436 * return it or NULL. If it is not qualified, then we attempt 437 * to construct a path using entries in the environment variable 438 * module_path. 439 * 440 * The path we return a pointer to need never be freed, as we manage 441 * it internally. 442 */ 443static char * |
444mod_searchfile(char *name) |
445{ 446 static char *result = NULL; |
447 char *path; |
448 char *cp, *sp; 449 struct stat sb; 450 451 /* Don't look for nothing */ 452 if ((name == NULL) || (*name == 0)) 453 return(name); 454 455 /* --- 6 unchanged lines hidden (view full) --- 462 return(name); 463 return(NULL); 464 } 465 466 /* 467 * Get the module path 468 */ 469 if ((cp = getenv("module_path")) == NULL) |
470 cp = default_searchpath; |
471 sp = path = strdup(cp); 472 473 /* 474 * Traverse the path, splitting off ';'-delimited components. 475 */ 476 if (result != NULL) 477 free(result); 478 while((cp = strsep(&path, ";")) != NULL) { |
479 result = malloc(strlen(cp) + strlen(name) + 5); 480 strcpy(result, cp); 481 if (cp[strlen(cp) - 1] != '/') 482 strcat(result, "/"); 483 strcat(result, name); 484/* printf("search '%s'\n", result); */ 485 if ((stat(result, &sb) == 0) && 486 S_ISREG(sb.st_mode)) |
487 break; 488 free(result); 489 result = NULL; 490 } 491 free(sp); 492 return(result); 493} 494 495/* |
496 * Attempt to locate the file containing the module (name) 497 */ 498static char * 499mod_searchmodule(char *name) 500{ 501 char *tn, *result; 502 503 /* Look for (name).ko */ 504 tn = malloc(strlen(name) + 3); 505 strcpy(tn, name); 506 strcat(tn, ".ko"); 507 result = mod_searchfile(tn); 508 free(tn); 509 /* Look for just (name) (useful for finding kernels) */ 510 if (result == NULL) 511 result = mod_searchfile(name); 512 513 return(result); 514} 515 516 517/* |
518 * Throw a module away 519 */ 520void 521mod_discard(struct loaded_module *mp) 522{ 523 struct module_metadata *md; 524 |
525 if (mp != NULL) { 526 while (mp->m_metadata != NULL) { 527 md = mp->m_metadata; 528 mp->m_metadata = mp->m_metadata->md_next; 529 free(md); 530 } 531 if (mp->m_name != NULL) 532 free(mp->m_name); 533 if (mp->m_type != NULL) 534 free(mp->m_type); 535 if (mp->m_args != NULL) 536 free(mp->m_args); 537 free(mp); 538 } |
539} 540 541/* |
542 * Allocate a new module; must be used instead of malloc() 543 * to ensure safe initialisation. 544 */ 545struct loaded_module * 546mod_allocmodule(void) 547{ 548 struct loaded_module *mp; 549 550 if ((mp = malloc(sizeof(struct loaded_module))) != NULL) { 551 bzero(mp, sizeof(struct loaded_module)); 552 } 553 return(mp); 554} 555 556 557/* |
558 * Add a module to the chain 559 */ 560static void 561mod_append(struct loaded_module *mp) 562{ 563 struct loaded_module *cm; 564 565 /* Append to list of loaded modules */ 566 mp->m_next = NULL; 567 if (loaded_modules == NULL) { 568 loaded_modules = mp; 569 } else { 570 for (cm = loaded_modules; cm->m_next != NULL; cm = cm->m_next) 571 ; 572 cm->m_next = mp; 573 } 574} |