1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23#ifdef SHLIB 24#include "shlib.h" 25#undef moninitrld 26#endif /* SHLIB */ 27#ifdef RLD 28/* 29 * This file contains the functions of the RLD package. 30 */ 31#include <mach-o/loader.h> 32#ifndef __OPENSTEP__ 33extern const struct segment_command *getsegbyname(const char *segname); 34extern const struct section *getsectbynamefromheader( 35 const struct mach_header *mhp, 36 const char *segname, 37 const char *sectname); 38#endif 39#if !(defined(KLD) && defined(__STATIC__)) 40#include <libc.h> 41#include <stdio.h> 42#include <mach/mach.h> 43#include "stuff/vm_flush_cache.h" 44#else /* defined(KLD) && defined(__STATIC__) */ 45#include <stdlib.h> 46#include <unistd.h> 47#include <mach/kern_return.h> 48#include <mach/vm_map.h> 49#endif /* !(defined(KLD) && defined(__STATIC__)) */ 50#include <setjmp.h> 51#include <stdarg.h> 52#include <string.h> 53#include <sys/types.h> 54#include <sys/stat.h> 55#include "stuff/openstep_mach.h" 56#include <mach-o/fat.h> 57#include <mach-o/nlist.h> 58#ifdef KLD 59#include <mach-o/kld.h> 60#else /* !defined(KLD) */ 61#include <mach-o/rld.h> 62#include <streams/streams.h> 63#include <objc/zone.h> 64#endif /* KLD */ 65#include <mach-o/rld_state.h> 66#include <mach-o/ldsyms.h> 67#define __darwin_i386_float_state i386_float_state 68#include "stuff/arch.h" 69#include "stuff/best_arch.h" 70 71#include "ld.h" 72#include "live_refs.h" 73#include "objects.h" 74#include "sections.h" 75#include "symbols.h" 76#include "pass1.h" 77#include "layout.h" 78#include "pass2.h" 79#include "sets.h" 80#ifdef SA_RLD 81#include "mach-o/sarld.h" 82#endif /* SA_RLD */ 83#ifdef KLD 84#include "mach-o/kld.h" 85#endif /* KLD */ 86#if defined(SA_RLD) 87#include "standalone/libsa.h" 88#endif 89 90#ifndef __OPENSTEP__ 91#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 92#include <crt_externs.h> 93#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 94#else /* defined(__OPENSTEP__) */ 95#ifdef __DYNAMIC__ 96#include "mach-o/dyld.h" 97#endif /* __DYNAMIC__ */ 98#endif /* !defined(__OPENSTEP__) */ 99 100/* 101 * The user's address function to be called in layout to get the address of 102 * where to link edit the result. 103 */ 104__private_extern__ 105unsigned long (*address_func)(unsigned long size, unsigned long headers_size) = 106 NULL; 107 108static 109enum strip_levels kld_requested_strip_level = STRIP_ALL; 110 111#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 112/* 113 * The function pointer passed to moninitrld() to do profiling of rld loaded 114 * code. If this function pointer is not NULL at the time of an rld_load() 115 * called it is called indirectly to set up the profiling buffers. 116 */ 117static void (*rld_monaddition)(char *lowpc, char *highpc) = NULL; 118#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 119 120/* 121 * This is a hack to let the code in layout_segments() in layout.c to know if 122 * the special output_file flag RLD_DEBUG_OUTPUT_FILENAME is being used so it 123 * can call the address_func (above) with the allocated_size of memory 124 * (including the symbol table) so that it can deallocate it correctly. 125 */ 126__private_extern__ long RLD_DEBUG_OUTPUT_FILENAME_flag = 0; 127 128#ifndef KLD 129/* 130 * The stream passed in to the rld routines to print errors on. 131 */ 132static NXStream *error_stream = NULL; 133#endif /* !defined(KLD) */ 134 135#if !defined(SA_RLD) && !defined(KLD) 136/* 137 * The zone allocation is done from. 138 */ 139static NXZone *zonep = NULL; 140#endif /* !defined(SA_RLD) && !defined(KLD) */ 141 142/* 143 * The jump buffer to get back to rld_load() or rld_unload() used by the error 144 * routines. 145 */ 146static jmp_buf rld_env; 147 148/* 149 * Indicator that a fatal error occured and that no more processing will be 150 * done on all future calls to protect calls from causing a core dump. 151 */ 152static volatile int fatals = 0; 153 154/* 155 * The base file name passed to rld_load_basefile() if it has been called. 156 * This points at an allocated copy of the name. 157 */ 158__private_extern__ char *base_name = NULL; 159 160#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 161/* 162 * These are maintained for the debugger's use. See <rld_state.h> for details. 163 */ 164static enum bool rld_maintain_states = FALSE; 165static unsigned long rld_nallocated_states = 0; 166 167static unsigned long rld_nloaded_states = 0; 168static struct rld_loaded_state *rld_loaded_state = NULL; 169static void rld_loaded_state_changed(void); 170#define NSTATES_INCREMENT 10 171#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 172 173#ifdef KLD 174/* hook for kext tools to set target byte order */ 175void 176kld_set_byteorder(enum NXByteOrder order) 177{ 178 switch (order) { 179 case NX_BigEndian: 180 target_byte_sex = BIG_ENDIAN_BYTE_SEX; 181 break; 182 case NX_LittleEndian: 183 target_byte_sex = LITTLE_ENDIAN_BYTE_SEX; 184 break; 185 default: 186 target_byte_sex = UNKNOWN_BYTE_SEX; 187 } 188} 189#endif 190 191/* The internal routine that implements rld_load_basefiles()'s */ 192#ifdef KLD 193static long internal_kld_load( 194#else /* !defined(KLD) */ 195static long internal_rld_load( 196 NXStream *stream, 197#endif /* KLD */ 198 struct mach_header **header_addr, 199 const char * const *object_filenames, 200 const char *output_filename, 201 const char *file_name, 202 const char *obj_addr, 203 long obj_size); 204 205 206/* The internal routine that implements rld_unload()'s */ 207#ifdef KLD 208static long internal_kld_unload( 209#else /* !defined(KLD) */ 210static long internal_rld_unload( 211 NXStream *stream, 212#endif /* KLD */ 213 enum bool internal_cleanup); 214 215#if !defined(SA_RLD) && !defined(KLD) 216static long internal_rld_load_basefile( 217 NXStream *stream, 218 const char *base_filename, 219 char *base_addr, 220 long base_size); 221#endif /* !defined(SA_RLD) && !defined(KLD) */ 222 223#if defined(KLD) 224static long internal_kld_load_basefile( 225 const char *base_filename, 226 char *base_addr, 227 long base_size); 228#endif /* defined(KLD) */ 229 230#if !defined(SA_RLD) && !defined(KLD) 231/* 232 * rld_load() link edits and loads the specified object filenames in the NULL 233 * terminated array of object file names, object_files, into the program that 234 * called it. If the program wishes to allow the loaded object files to use 235 * symbols from itself it must be built with the -seglinkedit link editor 236 * option to have its symbol table mapped into memory. The symbol table may 237 * be trimed to exactly which symbol are allowed to be referenced by use of the 238 * '-s list_filenam' option to strip(1). For this routine only global symbols 239 * are used so the -x option to the link editor or strip(1) can be used to save 240 * space in the final program. The set of object files being loaded will only 241 * be successfull if there are no link edit errors (undefined symbols, etc.). 242 * If an error ocurrs the set of object files is unloaded automaticly. If 243 * errors occur and the value specified for stream is not NULL error messages 244 * are printed in that stream. If the link editing and loading is successfull 245 * the address of the header of what was loaded is returned through the pointer 246 * header_addr it if is not NULL. rld_load() returns 1 for success and 0 for 247 * failure. If a fatal system error (out of memory, etc.) occurs then all 248 * future calls will fail. 249 */ 250long 251rld_load( 252NXStream *stream, 253struct mach_header **header_addr, 254const char * const *object_filenames, 255const char *output_filename) 256{ 257 return(internal_rld_load(stream, header_addr, object_filenames, 258 output_filename, NULL, NULL, 0)); 259} 260#endif /* !defined(SA_RLD) && !defined(KLD) */ 261 262#if defined(KLD) && defined(__DYNAMIC__) 263/* 264 * kld_load() is used by kextload(8) for loading kernel drivers running in 265 * user space. It is like rld_load() above but only takes one object_filename 266 * argument. Errors for the kld api's are done through kld_error_vprintf() 267 * which kextload(8) provides. 268 * 269 * Note thes symbols are really __private_extern__ and done by the "nmedit -p" 270 * command in the Makefile so that the other __private_extern__ symbols can be 271 * hidden by the "ld -r" first. 272 */ 273long 274kld_load( 275struct mach_header **header_addr, 276const char *object_filename, 277const char *output_filename) 278{ 279 const char *object_filenames[2]; 280 281 object_filenames[0] = object_filename; 282 object_filenames[1] = NULL; 283 284 return(internal_kld_load(header_addr, object_filenames, 285 output_filename, NULL, NULL, 0)); 286} 287 288/* 289 * kld_load_from_memory() is the same as kld_load() but loads one object file 290 * that has been mapped into memory. The object is described by its name, 291 * object_name, at address object_addr and is of size object_size. 292 */ 293long 294kld_load_from_memory( 295struct mach_header **header_addr, 296const char *object_name, 297char *object_addr, 298long object_size, 299const char *output_filename) 300{ 301 return(internal_kld_load(header_addr, NULL, output_filename, 302 object_name, object_addr, object_size)); 303} 304#endif /* defined(KLD) && defined(__DYNAMIC__) */ 305 306#if !defined(SA_RLD) && !defined(KLD) 307/* 308 * rld_load_from_memory() is the same as rld_load() but loads one object file 309 * that has been mapped into memory. The object is described by its name, 310 * object_name, at address object_addr and is of size object_size. 311 */ 312long 313rld_load_from_memory( 314NXStream *stream, 315struct mach_header **header_addr, 316const char *object_name, 317char *object_addr, 318long object_size, 319const char *output_filename) 320{ 321 return(internal_rld_load(stream, header_addr, NULL, output_filename, 322 object_name, object_addr, object_size)); 323} 324#endif /* !defined(SA_RLD) && !defined(KLD) */ 325 326#if defined(KLD) && defined(__STATIC__) 327/* 328 * rld_load_from_memory() is used by /mach_kernel for loading boot drivers 329 * running in the kernel. It is like rld_load_from_memory() above but 330 * does not produce an output file. Errors for the kld api's are done through 331 * kld_error_vprintf() which /mach_kernel provides. 332 * 333 * Note this symbol is really __private_extern__ and done by the "nmedit -p" 334 * command in the Makefile so that the other __private_extern__ symbols can be 335 * hidden by the "ld -r" first. 336 */ 337long 338kld_load_from_memory( 339struct mach_header **header_addr, 340const char *object_name, 341char *object_addr, 342long object_size) 343{ 344 return(internal_kld_load(header_addr, NULL, NULL, 345 object_name, object_addr, object_size)); 346} 347#endif /* defined(KLD) && defined(__DYNAMIC__) */ 348 349/* 350 * internal_rld_load() is the internal routine that implements rld_load()'s. 351 */ 352static 353long 354#ifdef KLD 355internal_kld_load( 356#else /* !defined(KLD) */ 357internal_rld_load( 358NXStream *stream, 359#endif /* KLD */ 360struct mach_header **header_addr, 361const char * const *object_filenames, 362const char *output_filename, 363const char *file_name, 364const char *obj_addr, 365long obj_size) 366{ 367#if !(defined(KLD) && defined(__STATIC__)) 368 kern_return_t r; 369#endif /* !(defined(KLD) && defined(__STATIC__)) */ 370#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 371 int i, n; 372 int fd; 373 long symbol_size, deallocate_size; 374 char dir[MAXPATHLEN]; 375 long dir_len; 376 const struct section *s; 377 void (**routines)(void); 378 379 dir[0] = '\0'; 380 dir_len = 0; 381#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 382 383#ifndef KLD 384 error_stream = stream; 385#endif /* !defined(KLD) */ 386 387 if(header_addr != NULL) 388 *header_addr = NULL; 389 390 /* If a fatal error has ever occured no other calls will be processed */ 391 if(fatals == 1){ 392 print("previous fatal errors occured, can no longer succeed"); 393 return(0); 394 } 395 396 /* 397 * Set up and handle link edit errors and fatal errors 398 */ 399 if(setjmp(rld_env) != 0){ 400 /* 401 * It takes a longjmp() to get to this point. If it was not a fatal 402 * error unload the set of object files being loaded. Otherwise 403 * just return failure. 404 */ 405 if(fatals == 0) 406#ifdef KLD 407 internal_kld_unload(TRUE); 408#else /* !defined(KLD) */ 409 internal_rld_unload(stream, TRUE); 410#endif /* KLD */ 411 return(0); 412 } 413 414 /* Set up the globals for rld */ 415#ifdef KLD 416 progname = "kld()"; 417#else /* !defined(KLD) */ 418 progname = "rld()"; 419#endif /* KLD */ 420 host_pagesize = getpagesize(); 421 host_byte_sex = get_host_byte_sex(); 422 force_cpusubtype_ALL = TRUE; 423 filetype = MH_OBJECT; 424 flush = FALSE; 425 nmerged_symbols = 0; 426 merged_string_size = 0; 427 nlocal_symbols = 0; 428 local_string_size = 0; 429 /* 430 * If there is to be an output file then save the symbols. Only the 431 * symbols from the current set will be placed in the output file. The 432 * symbols from the base file are never placed in any output file. 433 */ 434 strip_base_symbols = TRUE; 435 if(output_filename != NULL) 436 strip_level = STRIP_NONE; 437 else 438 strip_level = kld_requested_strip_level; 439 440 /* This must be cleared for each call to rld() */ 441 errors = 0; 442 443#if !defined(SA_RLD) && !(defined(KLD) && defined(__DYNAMIC__)) 444 /* 445 * If the symbols from base program has not been loaded load them. 446 * This will happen the first time rld() is called or will not happen. 447 */ 448 if(base_obj == NULL){ 449 /* 450 * The NeXT global variable that gets set to argv in crt0.o. Used 451 * here to set the name of the base program's object file 452 * (NXArgv[0]). 453 */ 454#if !defined(__OPENSTEP__) && !defined(KLD) 455 static char ***NXArgv_pointer = NULL; 456 static struct mach_header *_mh_execute_header_pointer = NULL; 457 struct segment_command *sg; 458 459 if(NXArgv_pointer == NULL) 460 NXArgv_pointer = _NSGetArgv(); 461 if(_mh_execute_header_pointer == NULL) 462 _mh_execute_header_pointer = _NSGetMachExecuteHeader(); 463 464 sg = (struct segment_command *)getsegbyname(SEG_LINKEDIT); 465 if(sg != NULL) 466 merge_base_program((*NXArgv_pointer)[0], 467 _mh_execute_header_pointer, sg, 468 NULL, 0, NULL, 0); 469#else /* !defined(__OPENSTEP__) && !defined(KLD) */ 470 struct segment_command *sg; 471#ifndef __DYNAMIC__ 472#ifdef KLD 473#ifndef _LIBSA_STDLIB_H_ 474 /* 475 * This needs to match what is in 476 * /System/Library/Frameworks/Kernel.framework/PrivateHeaders/ 477 * libsa/stdlib.h 478 * if it exists on the system. 479 */ 480 __private_extern__ const char *kld_basefile_name; 481#endif /* !defined(_LIBSA_STDLIB_H_) */ 482#else /* !defined(KLD) */ 483 extern char **NXArgv; 484#endif /* KLD */ 485#else /* defined(__DYNAMIC__) */ 486 static char ***NXArgv_pointer = NULL; 487 static struct mach_header *_mh_execute_header_pointer = NULL; 488 489 if(NXArgv_pointer == NULL) 490 _dyld_lookup_and_bind("_NXArgv", 491 (unsigned long *)&NXArgv_pointer, NULL); 492 if(_mh_execute_header_pointer == NULL) 493 _dyld_lookup_and_bind("__mh_execute_header", 494 (unsigned long *)&_mh_execute_header_pointer, NULL); 495#endif /* !defined(__DYNAMIC__) */ 496 497 sg = (struct segment_command *)getsegbyname(SEG_LINKEDIT); 498 if(sg != NULL) 499#ifndef __DYNAMIC__ 500#ifdef KLD 501 merge_base_program(kld_basefile_name, 502 (struct mach_header *)&_mh_execute_header, sg, 503 NULL, 0, NULL, 0); 504#else 505 merge_base_program( 506 NXArgv[0], (struct mach_header *)&_mh_execute_header, sg, 507 NULL, 0, NULL, 0); 508#endif /* KLD */ 509#else /* defined(__DYNAMIC__) */ 510 merge_base_program((*NXArgv_pointer)[0], 511 _mh_execute_header_pointer, sg, 512 NULL, 0, NULL, 0); 513#endif /* !defined(__DYNAMIC__) */ 514#endif /* !defined(__OPENSTEP__) && !defined(KLD) */ 515 if (target_byte_sex == UNKNOWN_BYTE_SEX) 516 target_byte_sex = host_byte_sex; 517 /* 518 * If there were any errors in processing the base program it is 519 * treated as a fatal error and no futher processing is done. 520 */ 521 if(errors){ 522 fatals = 1; 523 return(0); 524 } 525#ifndef KLD 526 /* 527 * Since we are loading into this program maintain state for the 528 * debugger. 529 */ 530 rld_maintain_states = TRUE; 531#endif /* KLD */ 532 } 533#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__DYNAMIC__)) */ 534 535 /* 536 * Create an entry in the sets array for this new set. This has to be 537 * done after the above base program has been merged so it does not 538 * appear apart of any set. 539 */ 540 new_set(); 541 542 /* 543 * The merged section sizes need to be zeroed before we start loading. 544 * The only case they would not be zero would be if a previous rld_load 545 * failed with a pass1 error they would not get reset. 546 */ 547 zero_merged_sections_sizes(); 548 549 /* 550 * Do pass1() for each object file or merge() for the one object in 551 * memory. 552 */ 553#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 554 if(file_name == NULL){ 555 for(i = 0; object_filenames[i] != NULL; i++) 556 pass1((char *)object_filenames[i], FALSE, FALSE, FALSE, FALSE, 557 FALSE); 558 } 559 else 560#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 561 { 562 cur_obj = new_object_file(); 563 cur_obj->file_name = allocate(strlen(file_name) + 1); 564 strcpy(cur_obj->file_name, file_name); 565 cur_obj->user_obj_addr = TRUE; 566 cur_obj->obj_addr = (char *)obj_addr; 567 cur_obj->obj_size = obj_size; 568 merge(FALSE, FALSE, FALSE); 569 } 570 571 if(errors){ 572#ifdef KLD 573 internal_kld_unload(TRUE); 574#else /* !defined(KLD) */ 575 internal_rld_unload(stream, TRUE); 576#endif /* KLD */ 577 return(0); 578 } 579 580 if(output_filename == RLD_DEBUG_OUTPUT_FILENAME) 581 RLD_DEBUG_OUTPUT_FILENAME_flag = 1; 582 else 583 RLD_DEBUG_OUTPUT_FILENAME_flag = 0; 584 layout(); 585 if(errors){ 586#ifdef KLD 587 internal_kld_unload(TRUE); 588#else /* !defined(KLD) */ 589 internal_rld_unload(stream, TRUE); 590#endif /* KLD */ 591 return(0); 592 } 593 594 pass2(); 595 if(errors){ 596#ifdef KLD 597 internal_kld_unload(TRUE); 598#else /* !defined(KLD) */ 599 internal_rld_unload(stream, TRUE); 600#endif /* KLD */ 601 return(0); 602 } 603 604 /* 605 * Place the merged sections back on their list of their merged segment 606 * (since now the are all in one segment after layout() placed them 607 * there for the MH_OBJECT format) and also reset the sizes of the 608 * sections to zero for any future loads. 609 */ 610 reset_merged_sections(); 611 612 /* 613 * Clean the object structures of things from this set that are not 614 * needed once the object has been successfully loaded. 615 */ 616 clean_objects(); 617 clean_archives_and_fats(); 618 619#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 620 if(output_filename != NULL && 621 output_filename != RLD_DEBUG_OUTPUT_FILENAME){ 622 /* 623 * Create the output file. The unlink() is done to handle the 624 * problem when the outputfile is not writable but the directory 625 * allows the file to be removed (since the file may not be there 626 * the return code of the unlink() is ignored). 627 */ 628 symbol_size = output_symtab_info.symtab_command.nsyms * 629 sizeof(struct nlist) + 630 output_symtab_info.symtab_command.strsize; 631 (void)unlink(output_filename); 632 if((fd = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC, 633 0666)) == -1){ 634 system_error("can't create output file: %s", output_filename); 635#ifdef KLD 636 internal_kld_unload(TRUE); 637#else /* !defined(KLD) */ 638 internal_rld_unload(stream, TRUE); 639#endif /* KLD */ 640 return(0); 641 } 642 else { 643 /* 644 * Write the entire output file. 645 */ 646 if(write(fd, output_addr, output_size + symbol_size) != 647 (int)(output_size + symbol_size)){ 648 system_error("can't write output file: %s",output_filename); 649#ifdef KLD 650 internal_kld_unload(TRUE); 651#else /* !defined(KLD) */ 652 internal_rld_unload(stream, TRUE); 653#endif /* KLD */ 654 return(0); 655 } 656 if(close(fd) == -1){ 657 system_error("can't close output file: %s",output_filename); 658#ifdef KLD 659 internal_kld_unload(TRUE); 660#else /* !defined(KLD) */ 661 internal_rld_unload(stream, TRUE); 662#endif /* KLD */ 663 return(0); 664 } 665 } 666 /* 667 * Deallocate the pages of memory for the symbol table if there are 668 * any whole pages. 669 */ 670 if (strip_level == STRIP_ALL) 671 deallocate_size = rnd(output_size + symbol_size, host_pagesize) - 672 rnd(output_size, host_pagesize); 673 else { 674 deallocate_size = 0; 675 sets[cur_set].output_size += symbol_size; 676 } 677 678 if(deallocate_size > 0){ 679 if((r = vm_deallocate(mach_task_self(), 680 (vm_address_t)(output_addr + 681 rnd(output_size, host_pagesize)), 682 deallocate_size)) != KERN_SUCCESS) 683 mach_fatal(r, "can't vm_deallocate() buffer for output " 684 "file's symbol table"); 685#ifdef RLD_VM_ALLOC_DEBUG 686 print("rld() vm_deallocate: addr = 0x%0x size = 0x%x\n", 687 (unsigned int)(output_addr + 688 rnd(output_size, host_pagesize)), 689 (unsigned int)deallocate_size); 690#endif /* RLD_VM_ALLOC_DEBUG */ 691 } 692 } 693#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 694 695 /* 696 * Now that this was successfull all that is left to do is return the 697 * address of the header if requested. 698 */ 699 if(header_addr != NULL) 700 *header_addr = (struct mach_header *)output_addr; 701 702#if !(defined(KLD) && defined(__STATIC__)) 703 /* 704 * Flush the cache of the output buffer so the the caller can execute 705 * the instructions written on by the relocation. 706 */ 707 if((r = vm_flush_cache(mach_task_self(), (vm_address_t)output_addr, 708 output_size)) != KERN_SUCCESS) 709#ifndef SA_RLD 710 mach_fatal(r, "can't vm_flush_cache() output buffer"); 711#else 712 fatal("can't vm_flush_cache() output buffer"); 713#endif 714#endif /* !(defined(KLD) && defined(__STATIC__)) */ 715 716 717#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 718 /* 719 * Now that this was successfull if the state for the debugger is to 720 * be maintained fill it in. 721 */ 722 if(rld_maintain_states == TRUE){ 723 if(rld_nloaded_states + 1 >= rld_nallocated_states){ 724 rld_loaded_state = reallocate(rld_loaded_state, 725 sizeof(struct rld_loaded_state) * 726 (rld_nallocated_states + NSTATES_INCREMENT) ); 727 rld_nallocated_states += NSTATES_INCREMENT; 728 } 729 730 if(file_name == NULL){ 731 for(i = 0; object_filenames[i] != NULL; ) 732 i++; 733 rld_loaded_state[rld_nloaded_states].object_filenames = 734 allocate(i * sizeof(char *)); 735 rld_loaded_state[rld_nloaded_states].nobject_filenames = i; 736 737 for(i = 0; object_filenames[i] != NULL; i++){ 738 if(object_filenames[i][0] != '/'){ 739 if(dir[0] == '\0'){ 740 getwd(dir); 741 dir_len = strlen(dir); 742 } 743 rld_loaded_state[rld_nloaded_states]. 744 object_filenames[i] = 745 allocate(dir_len + 1 + 746 strlen(object_filenames[i]) + 1); 747 strcpy(rld_loaded_state[rld_nloaded_states]. 748 object_filenames[i], dir); 749 strcat(rld_loaded_state[rld_nloaded_states]. 750 object_filenames[i], "/"); 751 strcat(rld_loaded_state[rld_nloaded_states]. 752 object_filenames[i], object_filenames[i]); 753 } 754 else{ 755 rld_loaded_state[rld_nloaded_states]. 756 object_filenames[i] = 757 allocate(strlen(object_filenames[i]) + 1); 758 strcpy(rld_loaded_state[rld_nloaded_states]. 759 object_filenames[i], object_filenames[i]); 760 } 761 } 762 } 763 else{ 764 rld_loaded_state[rld_nloaded_states].object_filenames = 765 allocate(sizeof(char *)); 766 rld_loaded_state[rld_nloaded_states].nobject_filenames = 1; 767 rld_loaded_state[rld_nloaded_states].object_filenames[0] = 768 allocate(strlen(file_name) + 1); 769 strcpy(rld_loaded_state[rld_nloaded_states]. 770 object_filenames[0], file_name); 771 } 772 rld_loaded_state[rld_nloaded_states].header_addr = 773 (struct mach_header *)output_addr; 774 775 rld_nloaded_states += 1; 776 rld_loaded_state_changed(); 777 } 778 779 /* 780 * If the base file comes from the executable then the profiling and 781 * constructor calls should be made. Else an rld_load_basefile() was 782 * done and these calls should not be made. 783 */ 784 if(base_name == NULL){ 785 /* 786 * If moninitrld() was called and it save away a pointer to 787 * monaddition() then profiling for the rld_load'ed code is wanted 788 * and make the indirect call to monaddition(). 789 */ 790 if(rld_monaddition != NULL && rld_maintain_states == TRUE){ 791 (*rld_monaddition)(output_addr, output_addr + output_size); 792 } 793 /* 794 * Call the C++ constructors and register the C++ destructors. 795 */ 796 s = getsectbynamefromheader((struct mach_header *)output_addr, 797 "__TEXT", "__constructor"); 798 if(s != NULL){ 799 routines = (void(**)(void))s->addr; 800 n = s->size / sizeof(routines[0]); 801 for(i = 0; i < n; i++) 802 (*routines[i])(); 803 } 804 s = getsectbynamefromheader((struct mach_header *)output_addr, 805 "__TEXT", "__destructor"); 806 if(s != NULL){ 807 routines = (void(**)(void))s->addr; 808 n = s->size / sizeof(routines[0]); 809 for(i = 0; i < n; i++) 810 atexit(routines[i]); 811 } 812 } 813#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 814 815 return(1); 816} 817 818#if !defined(SA_RLD) 819/* 820 * rld_load_basefile() loads a base file from an object file rather than just 821 * picking up the link edit segment from this program. 822 */ 823#if defined(KLD) 824#if !defined(__STATIC__) 825long 826kld_load_basefile( 827const char *base_filename) 828{ 829 return(internal_kld_load_basefile(base_filename, NULL, 0)); 830} 831#endif /* !defined(__STATIC__) */ 832 833long 834kld_load_basefile_from_memory( 835const char *base_filename, 836char *base_addr, 837long base_size) 838{ 839 return(internal_kld_load_basefile(base_filename, base_addr, base_size)); 840} 841 842#else /* !defined(KLD) */ 843long 844rld_load_basefile( 845NXStream *stream, 846const char *base_filename) 847{ 848 return(internal_rld_load_basefile(stream, base_filename, NULL, 0)); 849} 850#endif /* defined(KLD) */ 851 852/* 853 * rld_load_basefile() loads a base file from an object file rather than just 854 * picking up the link edit segment from this program. 855 */ 856static long 857#ifdef KLD 858internal_kld_load_basefile( 859#else /* !defined(KLD) */ 860internal_rld_load_basefile( 861NXStream *stream, 862#endif 863const char *base_filename, 864char *base_addr, 865long base_size) 866{ 867#if !(defined(KLD) && defined(__STATIC__)) 868 unsigned long size; 869 char *addr; 870 int fd; 871 struct stat stat_buf; 872 kern_return_t r; 873 struct fat_header *fat_header; 874#ifdef __LITTLE_ENDIAN__ 875 struct fat_header struct_fat_header; 876#endif /* __LITTLE_ENDIAN__ */ 877 struct fat_arch *fat_archs, *best_fat_arch; 878 struct arch_flag host_arch_flag; 879 enum bool from_fat_file; 880 881 size = 0; 882 from_fat_file = FALSE; 883 884#endif /* !(defined(KLD) && defined(__STATIC__)) */ 885 886#ifndef KLD 887 error_stream = stream; 888#endif /* !defined(KLD) */ 889 890 /* If a fatal error has ever occured no other calls will be processed */ 891 if(fatals == 1){ 892 print("previous fatal errors occured, can no longer succeed"); 893 return(0); 894 } 895 896 /* 897 * Set up and handle link edit errors and fatal errors 898 */ 899 if(setjmp(rld_env) != 0){ 900 /* 901 * It takes a longjmp() to get to this point. If it was not a fatal 902 * error unload the base file being loaded. Otherwise just return 903 * failure. 904 */ 905 if(fatals == 0) 906#ifdef KLD 907 kld_unload_all(1); 908#else /* !defined(KLD) */ 909 rld_unload_all(stream, 1); 910#endif /* KLD */ 911 return(0); 912 } 913 914 /* This must be cleared for each call to rld() */ 915 errors = 0; 916 917 /* 918 * If a base file has been loaded at this point return failure. 919 */ 920 if(base_obj != NULL){ 921 error("a base program is currently loaded"); 922 return(0); 923 } 924 if(cur_set != -1){ 925 error("object sets are currently loaded (base file must be loaded" 926 "before object sets)"); 927 return(0); 928 } 929 930 /* Set up the globals for rld */ 931#ifdef KLD 932 progname = "kld()"; 933#else /* !defined(KLD) */ 934 progname = "rld()"; 935#endif /* KLD */ 936 host_pagesize = getpagesize(); 937 host_byte_sex = get_host_byte_sex(); 938 strip_base_symbols = TRUE; 939 force_cpusubtype_ALL = TRUE; 940 base_name = allocate(strlen(base_filename) + 1); 941 strcpy(base_name, base_filename); 942 943#if !(defined(KLD) && defined(__STATIC__)) 944 945 /* 946 * If there is to be an output file then save the symbols. Only the 947 * symbols from the current set will be placed in the output file. The 948 * symbols from the base file are never placed in any output file. 949 */ 950 951 if (base_addr == NULL) { 952 /* 953 * Open this file and map it in. 954 */ 955 if((fd = open(base_name, O_RDONLY, 0)) == -1){ 956 system_error("Can't open: %s", base_name); 957 free(base_name); 958 base_name = NULL; 959 return(0); 960 } 961 if(fstat(fd, &stat_buf) == -1) 962 system_fatal("Can't stat file: %s", base_name); 963 /* 964 * For some reason mapping files with zero size fails so it has to 965 * be handled specially. 966 */ 967 if(stat_buf.st_size == 0){ 968 error("file: %s is empty (not an object)", base_name); 969 close(fd); 970 free(base_name); 971 base_name = NULL; 972 return(0); 973 } 974 size = stat_buf.st_size; 975 if((r = map_fd((int)fd, (vm_offset_t)0, (vm_offset_t *)&addr, 976 (boolean_t)TRUE, (vm_size_t)size)) != KERN_SUCCESS) 977 mach_fatal(r, "can't map file: %s", base_name); 978#ifdef RLD_VM_ALLOC_DEBUG 979 print("rld() map_fd: addr = 0x%0x size = 0x%x\n", 980 (unsigned int)addr, (unsigned int)size); 981#endif /* RLD_VM_ALLOC_DEBUG */ 982 /* 983 * The mapped file can't be made read-only because even in the case 984 * of errors where a wrong bytesex file is attempted to be loaded 985 * it must be writeable to detect the error. 986 * if((r = vm_protect(mach_task_self(), (vm_address_t)addr, size, 987 * FALSE, VM_PROT_READ)) != KERN_SUCCESS) 988 * mach_fatal(r, "can't make memory for mapped file: %s " 989 * "read-only", base_name); 990 */ 991 close(fd); 992 993 /* 994 * Determine what type of file it is (fat or thin object file). 995 */ 996 if(sizeof(struct fat_header) > size){ 997 error("truncated or malformed file: %s (file size too small " 998 "to be any kind of object)", base_name); 999 free(base_name); 1000 base_name = NULL; 1001 return(0); 1002 } 1003 from_fat_file = FALSE; 1004 fat_header = (struct fat_header *)addr; 1005#ifdef __LITTLE_ENDIAN__ 1006 fat_archs = NULL; 1007#endif /* __LITTLE_ENDIAN__ */ 1008#ifdef __BIG_ENDIAN__ 1009 if(fat_header->magic == FAT_MAGIC) 1010#endif /* __BIG_ENDIAN__ */ 1011#ifdef __LITTLE_ENDIAN__ 1012 if(fat_header->magic == SWAP_LONG(FAT_MAGIC)) 1013#endif /* __LITTLE_ENDIAN__ */ 1014 { 1015 from_fat_file = TRUE; 1016#ifdef __LITTLE_ENDIAN__ 1017 struct_fat_header = *fat_header; 1018 swap_fat_header(&struct_fat_header, host_byte_sex); 1019 fat_header = &struct_fat_header; 1020#endif /* __LITTLE_ENDIAN__ */ 1021 1022 if(sizeof(struct fat_header) + fat_header->nfat_arch * 1023 sizeof(struct fat_arch) > (unsigned long)size){ 1024 error("fat file: %s truncated or malformed (fat_arch " 1025 "structs would extend past the end of the file)", 1026 base_name); 1027 goto rld_load_basefile_error_return; 1028 } 1029 1030#ifdef __BIG_ENDIAN__ 1031 fat_archs = (struct fat_arch *) 1032 (addr + sizeof(struct fat_header)); 1033#endif /* __BIG_ENDIAN__ */ 1034#ifdef __LITTLE_ENDIAN__ 1035 fat_archs = allocate(fat_header->nfat_arch * 1036 sizeof(struct fat_arch)); 1037 memcpy(fat_archs, addr + sizeof(struct fat_header), 1038 fat_header->nfat_arch * sizeof(struct fat_arch)); 1039 swap_fat_arch(fat_archs, fat_header->nfat_arch, host_byte_sex); 1040#endif /* __LITTLE_ENDIAN__ */ 1041 1042 /* check the fat file */ 1043 check_fat(base_name, size, fat_header, fat_archs, NULL, 0); 1044 if(errors){ 1045 goto rld_load_basefile_error_return; 1046 return(0); 1047 } 1048 1049#if defined(KLD) && defined(__STATIC__) 1050 best_fat_arch = cpusubtype_findbestarch( 1051 arch_flag.cputype, arch_flag.cpusubtype, 1052 fat_archs, fat_header->nfat_arch); 1053#else /* !(defined(KLD) && defined(__STATIC__)) */ 1054 if(get_arch_from_host(&host_arch_flag, NULL) == 0){ 1055 error("can't determine the host architecture (fix " 1056 "get_arch_from_host() )"); 1057 goto rld_load_basefile_error_return; 1058 } 1059 best_fat_arch = cpusubtype_findbestarch( 1060 host_arch_flag.cputype, 1061 host_arch_flag.cpusubtype, 1062 fat_archs, fat_header->nfat_arch); 1063#endif /* defined(KLD) && defined(__STATIC__) */ 1064 if(best_fat_arch != NULL){ 1065 cur_obj = new_object_file(); 1066 cur_obj->file_name = base_name; 1067 cur_obj->obj_addr = addr + best_fat_arch->offset; 1068 cur_obj->obj_size = best_fat_arch->size; 1069 cur_obj->from_fat_file = TRUE; 1070 base_obj = cur_obj; 1071 } 1072 if(base_obj == NULL){ 1073 error("fat file: %s does not contain the host architecture " 1074 "(can't be used as a base file)", base_name); 1075 goto rld_load_basefile_error_return; 1076 } 1077#ifdef __LITTLE_ENDIAN__ 1078 free(fat_archs); 1079#endif /* __LITTLE_ENDIAN__ */ 1080 } 1081 else{ 1082 cur_obj = new_object_file(); 1083 cur_obj->file_name = base_name; 1084 cur_obj->obj_addr = addr; 1085 cur_obj->obj_size = size; 1086 base_obj = cur_obj; 1087 } 1088 } 1089 else 1090#endif /* !(defined(KLD) && defined(__STATIC__)) */ 1091 { 1092 cur_obj = new_object_file(); 1093 cur_obj->file_name = base_name; 1094 cur_obj->obj_addr = base_addr; 1095 cur_obj->obj_size = base_size; 1096 cur_obj->user_obj_addr = TRUE; 1097 base_obj = cur_obj; 1098 } 1099 1100 /* 1101 * Now that the file is mapped in merge it as the base file. 1102 */ 1103 merge(FALSE, FALSE, FALSE); 1104 1105 if(errors){ 1106#ifdef KLD 1107 kld_unload_all(1); 1108#else /* !defined(KLD) */ 1109 rld_unload_all(stream, 1); 1110#endif /* KLD */ 1111 return(0); 1112 } 1113 1114 /* 1115 * This is called to deallocate the memory for the base file and to 1116 * clean up it's section map. 1117 */ 1118 clean_objects(); 1119 clean_archives_and_fats(); 1120#if !(defined(KLD) && defined(__STATIC__)) 1121 if(from_fat_file == TRUE){ 1122 if((r = vm_deallocate(mach_task_self(), (vm_address_t)addr, 1123 (vm_size_t)size)) != KERN_SUCCESS) 1124 mach_fatal(r, "can't vm_deallocate() memory for mapped file %s", 1125 base_name); 1126#ifdef RLD_VM_ALLOC_DEBUG 1127 print("rld() vm_deallocate: addr = 0x%0x size = 0x%x\n", 1128 (unsigned int)addr, (unsigned int)size); 1129#endif /* RLD_VM_ALLOC_DEBUG */ 1130 } 1131 1132 /* 1133 * Since we are NOT loading into this program don't maintain state for 1134 * the debugger. 1135 */ 1136 rld_maintain_states = FALSE; 1137 1138#endif /* !(defined(KLD) && defined(__STATIC__)) */ 1139 1140 return(1); 1141 1142#if !(defined(KLD) && defined(__STATIC__)) 1143rld_load_basefile_error_return: 1144 if((r = vm_deallocate(mach_task_self(), (vm_address_t)addr, 1145 (vm_size_t)size)) != KERN_SUCCESS) 1146 mach_fatal(r, "can't vm_deallocate() memory for mapped file %s", 1147 base_name); 1148#ifdef RLD_VM_ALLOC_DEBUG 1149 print("rld() vm_deallocate: addr = 0x%0x size = 0x%x\n", 1150 (unsigned int)addr, (unsigned int)size); 1151#endif /* RLD_VM_ALLOC_DEBUG */ 1152 free(base_name); 1153 base_name = NULL; 1154#ifdef __LITTLE_ENDIAN__ 1155 if(fat_archs != NULL) 1156 free(fat_archs); 1157#endif /* __LITTLE_ENDIAN__ */ 1158 return(0); 1159#endif /* !(defined(KLD) && defined(__STATIC__)) */ 1160} 1161 1162#ifndef KLD 1163/* 1164 * rld_unload() unlinks and unloads that last object set that was loaded. 1165 * It returns 1 if it is successfull and 0 otherwize. If any errors ocurr 1166 * and the specified stream, stream, is not zero the error messages are printed 1167 * on that stream. 1168 */ 1169long 1170rld_unload( 1171NXStream *stream) 1172{ 1173 return(internal_rld_unload(stream, FALSE)); 1174} 1175#endif /* KLD */ 1176#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 1177 1178/* 1179 * internal_rld_unload() does the work for rld_unload() and takes one extra 1180 * parameter which is used to know if to remove the state maintained by the 1181 * debugger. 1182 */ 1183static 1184long 1185#ifdef KLD 1186internal_kld_unload( 1187#else /* !defined(KLD) */ 1188internal_rld_unload( 1189NXStream *stream, 1190#endif /* KLD */ 1191enum bool internal_cleanup) 1192{ 1193#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 1194 kern_return_t r; 1195 unsigned long i; 1196#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 1197 1198#ifndef KLD 1199 error_stream = stream; 1200#endif /* !defined(KLD) */ 1201 1202 /* If a fatal error has ever occured no other calls will be processed */ 1203 if(fatals == 1){ 1204 print("previous fatal errors occured, can no longer succeed"); 1205 return(0); 1206 } 1207 1208 /* 1209 * Set up and handle link edit errors and fatal errors 1210 */ 1211 if(setjmp(rld_env) != 0){ 1212 /* 1213 * It takes a longjmp() to get to this point. If it was a fatal 1214 * error or not just return failure. 1215 */ 1216 return(0); 1217 } 1218 1219 /* Set up the globals for rld */ 1220#ifdef KLD 1221 progname = "kld()"; 1222#else /* !defined(KLD) */ 1223 progname = "rld()"; 1224#endif /* KLD */ 1225 host_byte_sex = get_host_byte_sex(); 1226 force_cpusubtype_ALL = TRUE; 1227 1228 /* This must be cleared for each call to rld() */ 1229 errors = 0; 1230 1231 free_multiple_defs(); 1232 free_undefined_list(); 1233 1234 /* 1235 * If no set has been loaded at this point return failure. 1236 */ 1237 if(cur_set == -1){ 1238 error("no object sets currently loaded"); 1239 return(0); 1240 } 1241 1242#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 1243 /* 1244 * First adjust the state maintained for the debugger. This is done 1245 * first before the unload happens so if the debugger attaches while 1246 * in this unload it does not use the state that is being unloaded. 1247 */ 1248 if(internal_cleanup == FALSE && rld_maintain_states == TRUE){ 1249 rld_nloaded_states -= 1; 1250 for(i = 0; 1251 i < rld_loaded_state[rld_nloaded_states].nobject_filenames; 1252 i++){ 1253 free(rld_loaded_state[rld_nloaded_states]. 1254 object_filenames[i]); 1255 } 1256 free(rld_loaded_state[rld_nloaded_states].object_filenames); 1257 1258 rld_loaded_state[rld_nloaded_states].object_filenames = NULL; 1259 rld_loaded_state[rld_nloaded_states].nobject_filenames = 0; 1260 rld_loaded_state[rld_nloaded_states].header_addr = NULL; 1261 } 1262#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 1263 1264 /* 1265 * Remove the merged symbols for the current set of objects. 1266 */ 1267 remove_merged_symbols(); 1268 1269 /* 1270 * Remove the merged sections for the current set of objects. 1271 */ 1272 remove_merged_sections(); 1273 1274 /* 1275 * Clean and remove the object strcutures for the current set of 1276 * objects. 1277 */ 1278 clean_objects(); 1279 clean_archives_and_fats(); 1280 remove_objects(); 1281 1282 /* 1283 * deallocate the output memory for the current set if it had been 1284 * allocated. 1285 */ 1286 if(sets[cur_set].output_addr != NULL){ 1287#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 1288 if((r = vm_deallocate(mach_task_self(), 1289 (vm_address_t)sets[cur_set].output_addr, 1290 sets[cur_set].output_size)) != KERN_SUCCESS) 1291 mach_fatal(r, "can't vm_deallocate() memory for output"); 1292#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 1293#ifdef RLD_VM_ALLOC_DEBUG 1294 print("rld() vm_deallocate: addr = 0x%0x size = 0x%x\n", 1295 (unsigned int)sets[cur_set].output_addr, 1296 (unsigned int)sets[cur_set].output_size); 1297#endif /* RLD_VM_ALLOC_DEBUG */ 1298 sets[cur_set].output_addr = NULL; 1299 } 1300 1301 /* 1302 * The very last thing to do to unload a set is to remove the set 1303 * allocated in the sets array and reduce the cur_set. 1304 */ 1305 remove_set(); 1306 1307#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) 1308 /* 1309 * If we were maintaining state for the debugger let it know the state 1310 * has changed. 1311 */ 1312 if(rld_maintain_states == TRUE) 1313 rld_loaded_state_changed(); 1314#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ 1315 1316 return(1); 1317} 1318 1319#ifndef SA_RLD 1320/* 1321 * rld_unload_all() frees up all dynamic memory for the rld package that store 1322 * the information about all object sets and the base program. Also if the 1323 * parameter deallocate_sets is non-zero it deallocates the object sets 1324 * otherwise it leaves them around and can be still be used by the program. 1325 * It returns 1 if it is successfull and 0 otherwize. If any errors ocurr 1326 * and the specified stream, stream, is not zero the error messages are printed 1327 * on that stream. 1328 */ 1329long 1330#ifdef KLD 1331kld_unload_all( 1332#else /* !defined(KLD) */ 1333rld_unload_all( 1334NXStream *stream, 1335#endif /* KLD */ 1336long deallocate_sets) 1337{ 1338#if !(defined(KLD) && defined(__STATIC__)) 1339 kern_return_t r; 1340#endif /* !(defined(KLD) && defined(__STATIC__)) */ 1341#ifndef KLD 1342 unsigned long i, j, n; 1343#endif /* !defined(KLD) */ 1344 1345#ifndef KLD 1346 error_stream = stream; 1347#endif /* !defined(KLD) */ 1348 1349 /* If a fatal error has ever occured no other calls will be processed */ 1350 if(fatals == 1){ 1351 print("previous fatal errors occured, can no longer succeed"); 1352 return(0); 1353 } 1354 1355 /* 1356 * Set up and handle link edit errors and fatal errors 1357 */ 1358 if(setjmp(rld_env) != 0){ 1359 /* 1360 * It takes a longjmp() to get to this point. If it was a fatal 1361 * error or not just return failure. 1362 */ 1363 return(0); 1364 } 1365 1366 /* Set up the globals for rld */ 1367#ifdef KLD 1368 progname = "kld()"; 1369#else /* !defined(KLD) */ 1370 progname = "rld()"; 1371#endif /* KLD */ 1372 host_byte_sex = get_host_byte_sex(); 1373 force_cpusubtype_ALL = TRUE; 1374 1375 /* This must be cleared for each call to rld() */ 1376 errors = 0; 1377 1378 free_multiple_defs(); 1379 free_undefined_list(); 1380 1381 /* 1382 * If nothing has been loaded at this point return failure. 1383 */ 1384 if(cur_set == -1 && base_obj == NULL){ 1385 error("no object sets or base program currently loaded"); 1386 return(0); 1387 } 1388 1389#ifndef KLD 1390 /* 1391 * First adjust the state maintained for the debugger. This is done 1392 * first before the unload happens so if the debugger attaches while 1393 * in this unload it does not use the state that is being unloaded. 1394 */ 1395 if(rld_maintain_states == TRUE){ 1396 n = rld_nloaded_states; 1397 rld_nloaded_states = 0; 1398 for(i = 0; i < n; i++){ 1399 for(j = 0; j < rld_loaded_state[i].nobject_filenames; j++) 1400 free(rld_loaded_state[i].object_filenames[j]); 1401 free(rld_loaded_state[i].object_filenames); 1402 1403 rld_loaded_state[i].object_filenames = NULL; 1404 rld_loaded_state[i].nobject_filenames = 0; 1405 rld_loaded_state[i].header_addr = NULL; 1406 } 1407 free(rld_loaded_state); 1408 rld_loaded_state = NULL; 1409 rld_nallocated_states = 0; 1410 } 1411#endif /* !defined(KLD) */ 1412 1413 /* 1414 * Remove all sets currently loaded. 1415 */ 1416 while(cur_set != -1){ 1417 /* 1418 * Remove the merged symbols for the current set of objects. 1419 */ 1420 remove_merged_symbols(); 1421 1422 /* 1423 * Remove the merged sections for the current set of objects. 1424 */ 1425 remove_merged_sections(); 1426 1427 /* 1428 * Clean and remove the object structures for the current set of 1429 * objects. 1430 */ 1431 clean_objects(); 1432 clean_archives_and_fats(); 1433 remove_objects(); 1434 1435#if !(defined(KLD) && defined(__STATIC__)) 1436 /* 1437 * deallocate the output memory for the current set if specified and 1438 * it had been allocated. 1439 */ 1440 if(deallocate_sets && sets[cur_set].output_addr != NULL){ 1441 if((r = vm_deallocate(mach_task_self(), 1442 (vm_address_t)sets[cur_set].output_addr, 1443 sets[cur_set].output_size)) != KERN_SUCCESS) 1444 mach_fatal(r, "can't vm_deallocate() memory for output"); 1445#ifdef RLD_VM_ALLOC_DEBUG 1446 print("rld() vm_deallocate: addr = 0x%0x size = 0x%x\n", 1447 (unsigned int)sets[cur_set].output_addr, 1448 (unsigned int)sets[cur_set].output_size); 1449#endif /* RLD_VM_ALLOC_DEBUG */ 1450 } 1451#endif /* !(defined(KLD) && defined(__STATIC__)) */ 1452 sets[cur_set].output_addr = NULL; 1453 1454 /* 1455 * The very last thing to do to unload a set is to remove the set 1456 * allocated in the sets array and reduce the cur_set. 1457 */ 1458 remove_set(); 1459 } 1460 /* 1461 * Remove the merged symbols for the base program. 1462 */ 1463 remove_merged_symbols(); 1464 1465 /* 1466 * Remove the merged sections for the base program. 1467 */ 1468 remove_merged_sections(); 1469 1470 /* 1471 * Remove the object structure for the base program. 1472 */ 1473 if(base_name != NULL){ 1474 clean_objects(); 1475 clean_archives_and_fats(); 1476 free(base_name); 1477 base_name = NULL; 1478 } 1479 remove_objects(); 1480 1481 /* 1482 * Now free the memory for the sets. 1483 */ 1484 free_sets(); 1485 1486 /* 1487 * Set the pointer to the base object to NULL so that if another load 1488 * is done it will get reloaded. 1489 */ 1490 base_obj = NULL; 1491 1492#ifndef KLD 1493 /* 1494 * If we were maintaining state for the debugger let it know the state 1495 * has changed. Then clear the flag for maintaining state for the 1496 * debugger. 1497 */ 1498 if(rld_maintain_states == TRUE) 1499 rld_loaded_state_changed(); 1500 rld_maintain_states = FALSE; 1501 1502 if(zonep != NULL) 1503 NXDestroyZone(zonep); 1504 zonep = NULL; 1505#endif /* !defined(KLD) */ 1506 1507 target_byte_sex = UNKNOWN_BYTE_SEX; 1508 return(1); 1509} 1510#endif /* !defined(SA_RLD) */ 1511 1512#ifndef SA_RLD 1513 1514/* 1515 * rld_lookup() looks up the specified symbol name, symbol_name, and returns 1516 * its value indirectly through the pointer specified, value. It returns 1517 * 1 if it finds the symbol and 0 otherwise. If any errors ocurr and the 1518 * specified stream, stream, is not zero the error messages are printed on 1519 * that stream (for this routine only internal errors could result). 1520 */ 1521long 1522#ifdef KLD 1523kld_lookup( 1524#else /* !defined(KLD) */ 1525rld_lookup( 1526NXStream *stream, 1527#endif /* KLD */ 1528const char *symbol_name, 1529unsigned long *value) 1530{ 1531 struct merged_symbol *merged_symbol; 1532 1533#ifndef KLD 1534 error_stream = stream; 1535#endif /* !defined(KLD) */ 1536 1537 /* If a fatal error has ever occured no other calls will be processed */ 1538 if(fatals == 1){ 1539 print("previous fatal errors occured, can no longer succeed"); 1540 return(0); 1541 } 1542 1543 /* This must be cleared for each call to rld() */ 1544 errors = 0; 1545 1546 merged_symbol = lookup_symbol((char *)symbol_name); 1547 if(merged_symbol->name_len != 0){ 1548 if(value != NULL) 1549 *value = merged_symbol->nlist.n_value; 1550 return(1); 1551 } 1552 else{ 1553 if(value != NULL) 1554 *value = 0; 1555 return(0); 1556 } 1557} 1558 1559/* 1560 * rld_forget_symbol() looks up the specified symbol name, symbol_name, and 1561 * stomps on the name so rld effectively forgets the symbol exists. It returns 1562 * 1 if it finds the symbol and 0 otherwise. If any errors ocurr and the 1563 * specified stream, stream, is not zero the error messages are printed on 1564 * that stream (for this routine only internal errors could result). 1565 */ 1566long 1567#ifdef KLD 1568kld_forget_symbol( 1569#else /* !defined(KLD) */ 1570rld_forget_symbol( 1571NXStream *stream, 1572#endif /* KLD */ 1573const char *symbol_name) 1574{ 1575 struct merged_symbol *merged_symbol; 1576 1577#ifndef KLD 1578 error_stream = stream; 1579#endif /* !defined(KLD) */ 1580 1581 /* If a fatal error has ever occured no other calls will be processed */ 1582 if(fatals == 1){ 1583 print("previous fatal errors occured, can no longer succeed"); 1584 return(0); 1585 } 1586 1587 /* This must be cleared for each call to rld() */ 1588 errors = 0; 1589 1590 merged_symbol = lookup_symbol((char *)symbol_name); 1591 if(merged_symbol->name_len != 0){ 1592 merged_symbol->nlist.n_un.n_name[0] = '\0'; 1593 return(1); 1594 } 1595 else{ 1596 return(0); 1597 } 1598} 1599 1600#ifndef KLD 1601/* 1602 * rld_write_symfile() writes a object file containing just absolute symbols 1603 * mirroring the last set loaded. This can be used to recreate the stack of 1604 * the loaded state to come back after things are unloaded and load more stuff. 1605 */ 1606long 1607rld_write_symfile( 1608NXStream *stream, 1609const char *output_filename) 1610{ 1611 int fd; 1612 long symbol_size, return_value; 1613 kern_return_t r; 1614 1615 return_value = 1; 1616 error_stream = stream; 1617 1618 /* If a fatal error has ever occured no other calls will be processed */ 1619 if(fatals == 1){ 1620 print("previous fatal errors occured, can no longer succeed"); 1621 return(0); 1622 } 1623 1624 /* 1625 * Set up and handle link edit errors and fatal errors 1626 */ 1627 if(setjmp(rld_env) != 0){ 1628 /* 1629 * It takes a longjmp() to get to this point. If it was a fatal 1630 * error or not just return failure. 1631 */ 1632 return(0); 1633 } 1634 1635 /* Set up the globals for rld */ 1636#ifdef KLD 1637 progname = "kld()"; 1638#else /* !defined(KLD) */ 1639 progname = "rld()"; 1640#endif /* KLD */ 1641 host_byte_sex = get_host_byte_sex(); 1642 force_cpusubtype_ALL = TRUE; 1643 1644 /* This must be cleared for each call to rld() */ 1645 errors = 0; 1646 1647 /* 1648 * If no set has been loaded at this point return failure. That is a 1649 * basefile and at least one object set must be loaded to create a 1650 * symfile. 1651 */ 1652 if(cur_set < 0){ 1653 error("no object sets currently loaded"); 1654 return(0); 1655 } 1656 1657 layout_rld_symfile(); 1658 if(errors){ 1659 return_value = 0; 1660 goto deallocate_and_return; 1661 } 1662 1663 pass2_rld_symfile(); 1664 if(errors){ 1665 return_value = 0; 1666 goto deallocate_and_return; 1667 } 1668 1669 /* 1670 * Create the output file. The unlink() is done to handle the 1671 * problem when the outputfile is not writable but the directory 1672 * allows the file to be removed (since the file may not be there 1673 * the return code of the unlink() is ignored). 1674 */ 1675 symbol_size = output_symtab_info.symtab_command.nsyms * 1676 sizeof(struct nlist) + 1677 output_symtab_info.symtab_command.strsize; 1678 (void)unlink(output_filename); 1679 if((fd = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC, 1680 0666)) == -1){ 1681 system_error("can't create output file: %s", output_filename); 1682 return_value = 0; 1683 goto deallocate_and_return; 1684 } 1685 else { 1686 /* 1687 * Write the entire output file. 1688 */ 1689 if(write(fd, output_addr, output_size + symbol_size) != 1690 (int)(output_size + symbol_size)){ 1691 system_error("can't write output file: %s",output_filename); 1692 (void)unlink(output_filename); 1693 return_value = 0; 1694 goto deallocate_and_return; 1695 } 1696 if(close(fd) == -1){ 1697 system_error("can't close output file: %s",output_filename); 1698 (void)unlink(output_filename); 1699 return_value = 0; 1700 goto deallocate_and_return; 1701 } 1702 } 1703 1704deallocate_and_return: 1705 1706 if((r = vm_deallocate(mach_task_self(), (vm_address_t)(output_addr), 1707 output_size)) != KERN_SUCCESS) 1708 mach_fatal(r, "can't vm_deallocate() buffer for output " 1709 "file's symbol table"); 1710#ifdef RLD_VM_ALLOC_DEBUG 1711 print("rld() vm_deallocate: addr = 0x%0x size = 0x%x\n", 1712 (unsigned int)(output_addr), output_size); 1713 rnd(output_size, host_pagesize)), 1714 (unsigned int)deallocate_size); 1715#endif /* RLD_VM_ALLOC_DEBUG */ 1716 return(return_value); 1717} 1718#endif /* !defined(KLD) */ 1719 1720#if !(defined(KLD) && defined(__STATIC__)) 1721/* 1722 * The debugger places a break point at this routine and it is called when the 1723 * the loaded state into the program has changed. 1724 */ 1725static 1726void 1727rld_loaded_state_changed( 1728void) 1729{ 1730#ifdef RLD_TEST 1731 1732 unsigned long i, j; 1733 1734 if(rld_maintain_states == TRUE) 1735 print("rld_maintain_states = TRUE\n"); 1736 else 1737 print("rld_maintain_states = FALSE\n"); 1738 print("rld_nloaded_states = %lu\n", rld_nloaded_states); 1739 print("rld_loaded_state 0x%x\n", (unsigned int)rld_loaded_state); 1740 for(i = 0; i < rld_nloaded_states; i++){ 1741 print("state %lu\n\tnobject_filenames %lu\n\tobject_filenames 0x%x" 1742 "\n\theader_addr 0x%x\n", i, 1743 rld_loaded_state[i].nobject_filenames, 1744 (unsigned int)(rld_loaded_state[i].object_filenames), 1745 (unsigned int)(rld_loaded_state[i].header_addr)); 1746 for(j = 0; j < rld_loaded_state[i].nobject_filenames; j++) 1747 print("\t\t%s\n", rld_loaded_state[i].object_filenames[j]); 1748 } 1749#endif /* RLD_TEST */ 1750} 1751#endif /* !(defined(KLD) && defined(__STATIC__)) */ 1752 1753#ifndef KLD 1754/* 1755 * rld_get_loaded_state() is returned by moninitrld() to allow the profiling 1756 * runtime routine monoutput() to get the rld_loaded_state and write it into 1757 * the gmon.out file for later processing by gprof(1). 1758 */ 1759static 1760void 1761rld_get_loaded_state( 1762struct rld_loaded_state **s, 1763unsigned long *n) 1764{ 1765 *s = rld_loaded_state; 1766 *n = rld_nloaded_states; 1767} 1768 1769/* 1770 * moninitrld() is called from the profiling runtime routine moninit() to cause 1771 * the rld loaded code to be profiled. It is passed a pointer to the the 1772 * profiling runtime routine monaddtion() to be called after a sucessfull 1773 * rld_load. It returns a pointer to rld_get_loaded_state() and is used as 1774 * described above. 1775 */ 1776void (* 1777moninitrld( 1778void (*m)(char *lowpc, char *highpc)) 1779)(struct rld_loaded_state **s, unsigned long *n) 1780{ 1781 rld_monaddition = m; 1782 return(rld_get_loaded_state); 1783} 1784 1785/* 1786 * rld_get_current_header() is only used by the objective-C runtime to do 1787 * unloading to get the current header so it does not have to save this 1788 * information. It returns NULL if there is nothing is loaded currently. 1789 */ 1790char * 1791rld_get_current_header( 1792void) 1793{ 1794 /* 1795 * If no set has been loaded at this point return NULL. 1796 */ 1797 if(cur_set == -1) 1798 return(NULL); 1799 else 1800 return(sets[cur_set].output_addr); 1801} 1802#endif /* !defined(KLD) */ 1803 1804/* 1805 * rld_address_func() is passed a pointer to a function that is then called on 1806 * subsequent rld_load() calls to get the address that the user wants the object 1807 * set loaded at. That function is passed the memory size of the resulting 1808 * object set. 1809 */ 1810void 1811#ifdef KLD 1812kld_address_func( 1813#else /* !defined(KLD) */ 1814rld_address_func( 1815#endif /* KLD */ 1816unsigned long (*func)(unsigned long size, unsigned long headers_size)) 1817{ 1818 address_func = func; 1819} 1820 1821/* 1822 * kld_set_link_options() . 1823 */ 1824void 1825#ifdef KLD 1826kld_set_link_options( 1827#else /* !defined(KLD) */ 1828rld_set_link_options( 1829#endif /* KLD */ 1830unsigned long link_options) 1831{ 1832#ifdef KLD 1833 if(KLD_STRIP_NONE & link_options) 1834 kld_requested_strip_level = STRIP_NONE; 1835 else 1836#endif /* KLD */ 1837 kld_requested_strip_level = STRIP_ALL; 1838} 1839#endif /* !defined(SA_RLD) */ 1840 1841/* 1842 * cleanup() is called by all routines handling fatal errors. 1843 */ 1844__private_extern__ 1845void 1846cleanup(void) 1847{ 1848 fatals = 1; 1849 longjmp(rld_env, 1); 1850} 1851 1852#if !defined(SA_RLD) && !defined(KLD) 1853/* 1854 * All printing of all messages goes through this function. 1855 */ 1856__private_extern__ 1857void 1858vprint( 1859const char *format, 1860va_list ap) 1861{ 1862 if(error_stream != NULL) 1863 NXVPrintf(error_stream, format, ap); 1864NXVPrintf(error_stream, format, ap); 1865} 1866#endif /* !defined(SA_RLD) && !defined(KLD) */ 1867 1868#ifdef KLD 1869/* 1870 * All printing of all messages goes through this function. 1871 */ 1872__private_extern__ 1873void 1874vprint( 1875const char *format, 1876va_list ap) 1877{ 1878 kld_error_vprintf(format, ap); 1879} 1880#endif /* KLD */ 1881 1882#if !defined(SA_RLD) && !defined(KLD) 1883/* 1884 * allocate() is just a wrapper around malloc that prints and error message and 1885 * exits if the malloc fails. 1886 */ 1887__private_extern__ 1888void * 1889allocate( 1890unsigned long size) 1891{ 1892 void *p; 1893 1894 if(zonep == NULL){ 1895 zonep = NXCreateZone(vm_page_size, vm_page_size, 1); 1896 if(zonep == NULL) 1897 fatal("can't create NXZone"); 1898 NXNameZone(zonep, "rld"); 1899 } 1900 if(size == 0) 1901 return(NULL); 1902 if((p = NXZoneMalloc(zonep, size)) == NULL) 1903 system_fatal("virtual memory exhausted (NXZoneMalloc failed)"); 1904 return(p); 1905} 1906 1907/* 1908 * reallocate() is just a wrapper around realloc that prints and error message 1909 * and exits if the realloc fails. 1910 */ 1911__private_extern__ 1912void * 1913reallocate( 1914void *p, 1915unsigned long size) 1916{ 1917 if(zonep == NULL){ 1918 zonep = NXCreateZone(vm_page_size, vm_page_size, 1); 1919 if(zonep == NULL) 1920 fatal("can't create NXZone"); 1921 NXNameZone(zonep, "rld"); 1922 } 1923 if(p == NULL) 1924 return(allocate(size)); 1925 if((p = NXZoneRealloc(zonep, p, size)) == NULL) 1926 system_fatal("virtual memory exhausted (NXZoneRealloc failed)"); 1927 return(p); 1928} 1929#endif /* !defined(SA_RLD) && !defined(KLD) */ 1930 1931#ifdef SA_RLD 1932/* 1933 * These two variables are set in sa_rld() and used in layout_segments() 1934 * as the place to put the output in memory. 1935 */ 1936__private_extern__ char *sa_rld_output_addr = NULL; 1937__private_extern__ unsigned long sa_rld_output_size = 0; 1938 1939/* 1940 * These two variables are set in sa_rld() and used in vprint() (defined in this 1941 * file) as the buffer to put error messages and the size of the buffer. 1942 */ 1943static char *sa_rld_error_buf_addr = NULL; 1944static unsigned long sa_rld_error_buf_size = 0; 1945 1946/* 1947 * If this is FALSE the SA_RLD malloc package has not been initialized 1948 * and needs to be. 1949 */ 1950static enum bool sa_rld_malloc_initialized = FALSE; 1951 1952/* 1953 * sa_rld_internal() is the function that implements sa_rld() and 1954 * sa_rld_with_symtab(). If symtab is NULL then the symbol table is found via 1955 * the mach header. 1956 */ 1957static 1958int 1959sa_rld_internal( 1960char *basefile_name, /* base file name */ 1961struct mach_header *basefile_addr, /* mach header of the base file */ 1962 1963char *object_name, /* name of the object to load */ 1964char *object_addr, /* addr of the object in memory to load */ 1965unsigned long object_size, /* size of the object in memory to load */ 1966 1967char *workmem_addr, /* address of working memory */ 1968unsigned long *workmem_size, /* size of working memory (in/out) */ 1969 1970char *error_buf_addr, /* address of error message buffer */ 1971unsigned long error_buf_size, /* size of error message buffer */ 1972 1973char *malloc_addr, /* address to use for initializing malloc */ 1974unsigned long malloc_len, /* length to use for same */ 1975 1976struct nlist *symtab, /* pointer to the symbol table */ 1977unsigned long nsyms, /* number of symbols */ 1978 1979char *strtab, /* pointer to the string table */ 1980unsigned long strsize) /* sizeof the string table */ 1981{ 1982 int status; 1983 struct segment_command *linkedit; 1984 1985 /* 1986 * Initialized the stand alone malloc package if needed. 1987 */ 1988 if(sa_rld_malloc_initialized == FALSE){ 1989 malloc_init(malloc_addr, malloc_len, 1000); 1990 sa_rld_malloc_initialized = TRUE; 1991 } 1992 1993 /* 1994 * Set up and handle link edit errors and fatal errors 1995 */ 1996 if(setjmp(rld_env) != 0){ 1997 /* 1998 * It takes a longjmp() to get to this point. If it was not a fatal 1999 * error unload the base file being loaded. Otherwise just return 2000 * failure. 2001 */ 2002 if(fatals == 0) 2003 rld_unload_all(NULL, 1); 2004 return(0); 2005 } 2006 2007 /* This must be cleared for each call to rld() */ 2008 errors = 0; 2009 2010 /* Set up the globals for rld */ 2011#ifdef KLD 2012 progname = "kld()"; 2013#else /* !defined(KLD) */ 2014 progname = "rld()"; 2015#endif /* KLD */ 2016 host_pagesize = getpagesize(); 2017 host_byte_sex = get_host_byte_sex(); 2018 strip_base_symbols = TRUE; 2019 force_cpusubtype_ALL = TRUE; 2020 2021 /* Set up the globals for sa_rld */ 2022 sa_rld_output_size = *workmem_size; 2023 sa_rld_output_addr = workmem_addr; 2024 sa_rld_error_buf_addr = error_buf_addr; 2025 sa_rld_error_buf_size = error_buf_size; 2026 2027 /* 2028 * If the symbols from base program has not been loaded load them. 2029 * This will happen the first time rld() is called or will not happen. 2030 */ 2031 if(base_obj == NULL){ 2032 if(symtab == NULL){ 2033 linkedit = getsegbynamefromheader(basefile_addr, SEG_LINKEDIT); 2034 if(linkedit != NULL) 2035 merge_base_program(basefile_name, basefile_addr, linkedit, 2036 NULL, 0, NULL, 0); 2037 } 2038 else{ 2039 merge_base_program(basefile_name, basefile_addr, NULL, 2040 symtab, nsyms, strtab, strsize); 2041 } 2042 if (target_byte_sex == UNKNOWN_BYTE_SEX) 2043 target_byte_sex = host_byte_sex; 2044 /* 2045 * If there were any errors in processing the base program it is 2046 * treated as a fatal error and no futher processing is done. 2047 */ 2048 if(errors){ 2049 fatals = 1; 2050 return(0); 2051 } 2052 } 2053 2054 /* 2055 * The work of loading the mapped file is done like very much like 2056 * a call to rld_load_from_memory(). 2057 */ 2058 status = internal_rld_load(NULL, /* NXStream *stream */ 2059 NULL, /* struct mach_header **header_addr */ 2060 NULL, /* char * const *object_filenames, */ 2061 NULL, /* char *output_filename */ 2062 object_name, object_addr, object_size); 2063 if(status == 0) 2064 return(0); 2065 2066 /* 2067 * Now that the mapped file has been loaded unload it but leave the 2068 * linked output in memory. This is done with a normal call to 2069 * internal_rld_unload() which has in it an ifdef SA_RLD to not 2070 * deallocate the output memory. 2071 */ 2072 status = internal_rld_unload(NULL, FALSE); 2073 2074 /* 2075 * Return the size of the working memory used for the output. 2076 */ 2077 *workmem_size = output_size; 2078 2079 return(status); 2080} 2081 2082/* 2083 * sa_rld() loads the specified object in memory against the specified base file 2084 * in memory. The output is placed in memory starting at the value of the 2085 * parameter workmem_addr and the size of the memory used for the output 2086 * returned indirectly through workmem_size. Initially *workmem_size is the 2087 * size of the working memory. 2088 */ 2089int 2090sa_rld( 2091char *basefile_name, /* base file name */ 2092struct mach_header *basefile_addr, /* mach header of the base file */ 2093 2094char *object_name, /* name of the object to load */ 2095char *object_addr, /* addr of the object in memory to load */ 2096unsigned long object_size, /* size of the object in memory to load */ 2097 2098char *workmem_addr, /* address of working memory */ 2099unsigned long *workmem_size, /* size of working memory (in/out) */ 2100 2101char *error_buf_addr, /* address of error message buffer */ 2102unsigned long error_buf_size, /* size of error message buffer */ 2103 2104char *malloc_addr, /* address to use for initializing malloc */ 2105unsigned long malloc_len) /* length to use for same */ 2106{ 2107 return(sa_rld_internal(basefile_name, basefile_addr, object_name, 2108 object_addr, object_size, workmem_addr, 2109 workmem_size, error_buf_addr, error_buf_size, 2110 malloc_addr, malloc_len, NULL, 0, NULL, 0)); 2111} 2112 2113/* 2114 * sa_rld_with_symtab() is the same as sa_rld() except it passed in a pointer 2115 * to the symbol table, its size and a pointer to the string table and its 2116 * size. Rather getting the the symbol table off of the mach header and the 2117 * link edit segment. 2118 */ 2119int 2120sa_rld_with_symtab( 2121char *basefile_name, /* base file name */ 2122struct mach_header *basefile_addr, /* mach header of the base file */ 2123 2124char *object_name, /* name of the object to load */ 2125char *object_addr, /* addr of the object in memory to load */ 2126unsigned long object_size, /* size of the object in memory to load */ 2127 2128char *workmem_addr, /* address of working memory */ 2129unsigned long *workmem_size, /* size of working memory (in/out) */ 2130 2131char *error_buf_addr, /* address of error message buffer */ 2132unsigned long error_buf_size, /* size of error message buffer */ 2133 2134char *malloc_addr, /* address to use for initializing malloc */ 2135unsigned long malloc_len, /* length to use for same */ 2136 2137struct nlist *symtab, /* pointer to the symbol table */ 2138unsigned long nsyms, /* number of symbols */ 2139 2140char *strtab, /* pointer to the string table */ 2141unsigned long strsize) /* sizeof the string table */ 2142{ 2143 return(sa_rld_internal(basefile_name, basefile_addr, object_name, 2144 object_addr, object_size, workmem_addr, 2145 workmem_size, error_buf_addr, error_buf_size, 2146 malloc_addr, malloc_len, symtab, nsyms, strtab, 2147 strsize)); 2148} 2149 2150/* 2151 * All printing of all SA_RLD messages goes through this function. 2152 */ 2153__private_extern__ 2154void 2155vprint( 2156const char *format, 2157va_list ap) 2158{ 2159 unsigned long new; 2160 2161 new = slvprintf(sa_rld_error_buf_addr, 2162 sa_rld_error_buf_size, format, ap); 2163 sa_rld_error_buf_addr += new; 2164 sa_rld_error_buf_size -= new; 2165} 2166#endif /* SA_RLD */ 2167 2168#if defined(SA_RLD) || defined(KLD) 2169 2170/* 2171 * allocate() is just a wrapper around malloc that prints and error message and 2172 * exits if the malloc fails. 2173 */ 2174__private_extern__ 2175void * 2176allocate( 2177unsigned long size) 2178{ 2179 void *p; 2180 2181 if(size == 0) 2182 return(NULL); 2183 if((p = malloc(size)) == NULL) 2184 fatal("virtual memory exhausted (malloc failed)"); 2185 return(p); 2186} 2187 2188/* 2189 * reallocate() is just a wrapper around realloc that prints and error message 2190 * and exits if the realloc fails. 2191 */ 2192__private_extern__ 2193void * 2194reallocate( 2195void *p, 2196unsigned long size) 2197{ 2198 if(p == NULL) 2199 return(allocate(size)); 2200 if((p = realloc(p, size)) == NULL) 2201 fatal("virtual memory exhausted (realloc failed)"); 2202 return(p); 2203} 2204#endif /* defined(SA_RLD) || defined(KLD) */ 2205 2206/* 2207 * savestr() malloc's space for the string passed to it, copys the string into 2208 * the space and returns a pointer to that space. 2209 */ 2210__private_extern__ 2211char * 2212savestr( 2213const char *s) 2214{ 2215 long len; 2216 char *r; 2217 2218 len = strlen(s) + 1; 2219 r = (char *)allocate(len); 2220 strcpy(r, s); 2221 return(r); 2222} 2223 2224#if defined(KLD) && defined(__STATIC__) 2225/* 2226 * The Kernel framework does not provide this API so we have a copy here. 2227 */ 2228__private_extern__ 2229struct mach_header * 2230_NSGetMachExecuteHeader(void) 2231{ 2232 return((struct mach_header *)&_mh_execute_header); 2233} 2234#endif /* defined(KLD) && defined(__STATIC__) */ 2235 2236#endif /* RLD */ 2237