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