2 * Copyright (c) 2007-2016 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 #include <mach-o/loader.h>
31 #include <mach-o/nlist.h>
32 #include <mach-o/reloc.h>
34 #include <kern/kalloc.h>
35 #include <libkern/libkern.h>
36 #include <mach/vm_param.h>
37 #include <vm/vm_kern.h>
41 #include <mach/mach_init.h>
42 #include <mach-o/swap.h>
45 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
46 #include <AssertMacros.h>
48 #include "kxld_util.h"
51 static void unswap_macho_32(u_char
*file
, enum NXByteOrder host_order
,
52 enum NXByteOrder target_order
);
53 static void unswap_macho_64(u_char
*file
, enum NXByteOrder host_order
,
54 enum NXByteOrder target_order
);
58 static unsigned long num_allocations
= 0;
59 static unsigned long num_frees
= 0;
60 static unsigned long bytes_allocated
= 0;
61 static unsigned long bytes_freed
= 0;
64 static KXLDLoggingCallback s_logging_callback
= NULL
;
65 static const char *s_callback_name
= NULL
;
66 static void *s_callback_data
= NULL
;
69 static boolean_t s_cross_link_enabled
= FALSE
;
70 static kxld_size_t s_cross_link_page_size
= PAGE_SIZE
;
74 /*******************************************************************************
75 *******************************************************************************/
77 kxld_set_logging_callback(KXLDLoggingCallback logging_callback
)
79 s_logging_callback
= logging_callback
;
82 /*******************************************************************************
83 *******************************************************************************/
85 kxld_set_logging_callback_data(const char *name
, void *user_data
)
87 s_callback_name
= name
;
88 s_callback_data
= user_data
;
91 /*******************************************************************************
92 *******************************************************************************/
94 kxld_log(KXLDLogSubsystem subsystem
, KXLDLogLevel level
,
95 const char *in_format
, ...)
97 char stack_buffer
[256];
98 char *alloc_buffer
= NULL
;
99 char *format
= stack_buffer
;
100 const char *name
= (s_callback_name
) ? s_callback_name
: "internal";
104 if (s_logging_callback
) {
106 length
= snprintf(stack_buffer
, sizeof(stack_buffer
), "kxld[%s]: %s",
109 if (length
>= sizeof(stack_buffer
)) {
111 alloc_buffer
= kxld_alloc(length
);
112 if (!alloc_buffer
) return;
114 snprintf(alloc_buffer
, length
, "kxld[%s]: %s",
116 format
= alloc_buffer
;
119 va_start(ap
, in_format
);
120 s_logging_callback(subsystem
, level
, format
, ap
, s_callback_data
);
124 kxld_free(alloc_buffer
, length
);
129 /* We'll use kalloc for any page-based allocations under this threshold, and
130 * kmem_alloc otherwise.
132 #define KALLOC_MAX 16 * 1024
134 /*******************************************************************************
135 *******************************************************************************/
137 kxld_alloc(size_t size
)
150 bytes_allocated
+= size
;
157 /*******************************************************************************
158 *******************************************************************************/
160 kxld_page_alloc_untracked(size_t size
)
164 kern_return_t rval
= 0;
165 vm_offset_t addr
= 0;
168 size
= round_page(size
);
171 if (size
< KALLOC_MAX
) {
174 rval
= kmem_alloc(kernel_map
, &addr
, size
, VM_KERN_MEMORY_OSKEXT
);
175 if (!rval
) ptr
= (void *) addr
;
184 /*******************************************************************************
185 *******************************************************************************/
187 kxld_page_alloc(size_t size
)
191 ptr
= kxld_page_alloc_untracked(size
);
195 bytes_allocated
+= round_page(size
);
202 /*******************************************************************************
203 *******************************************************************************/
205 kxld_alloc_pageable(size_t size
)
207 size
= round_page(size
);
210 kern_return_t rval
= 0;
213 rval
= kmem_alloc_pageable(kernel_map
, &ptr
, size
, VM_KERN_MEMORY_OSKEXT
);
218 return kxld_page_alloc_untracked(size
);
222 /*******************************************************************************
223 *******************************************************************************/
225 kxld_free(void *ptr
, size_t size __unused
)
239 /*******************************************************************************
240 *******************************************************************************/
242 kxld_page_free_untracked(void *ptr
, size_t size __unused
)
245 size
= round_page(size
);
247 if (size
< KALLOC_MAX
) {
250 kmem_free(kernel_map
, (vm_offset_t
) ptr
, size
);
258 /*******************************************************************************
259 *******************************************************************************/
261 kxld_page_free(void *ptr
, size_t size
)
265 bytes_freed
+= round_page(size
);
267 kxld_page_free_untracked(ptr
, size
);
270 /*******************************************************************************
271 *******************************************************************************/
273 validate_and_swap_macho_32(u_char
*file
, u_long size
275 , enum NXByteOrder host_order
279 kern_return_t rval
= KERN_FAILURE
;
280 struct mach_header
*mach_hdr
= (struct mach_header
*) ((void *) file
);
281 struct load_command
*load_hdr
= NULL
;
282 struct segment_command
*seg_hdr
= NULL
;
283 struct section
*sects
= NULL
;
284 struct relocation_info
*relocs
= NULL
;
285 struct symtab_command
*symtab_hdr
= NULL
;
286 struct nlist
*symtab
= NULL
;
293 boolean_t swap
= FALSE
;
299 /* Verify that the file is big enough for the mach header */
300 require_action(size
>= sizeof(*mach_hdr
), finish
,
302 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
303 offset
= sizeof(*mach_hdr
);
306 /* Swap the mach header if necessary */
307 if (mach_hdr
->magic
== MH_CIGAM
) {
309 (void) swap_mach_header(mach_hdr
, host_order
);
313 /* Validate the mach_header's magic number */
314 require_action(mach_hdr
->magic
== MH_MAGIC
, finish
,
316 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
317 "Invalid magic number: 0x%x.", mach_hdr
->magic
));
319 /* If in the running kernel, and asked to validate the kernel
320 * (which is the only file of type MH_EXECUTE we should ever see),
321 * then just assume it's ok or we wouldn't be running to begin with.
324 if (mach_hdr
->filetype
== MH_EXECUTE
) {
330 /* Validate and potentially swap the load commands */
331 for(i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= cmdsize
) {
333 /* Get the load command and size */
334 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
336 cmdsize
= load_hdr
->cmdsize
;
340 cmd
= OSSwapInt32(load_hdr
->cmd
);
341 cmdsize
= OSSwapInt32(load_hdr
->cmdsize
);
345 /* Verify that the file is big enough to contain the load command */
346 require_action(size
>= offset
+ cmdsize
, finish
,
348 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
352 /* Get and swap the segment header */
353 seg_hdr
= (struct segment_command
*) load_hdr
;
355 if (swap
) swap_segment_command(seg_hdr
, host_order
);
358 /* Get and swap the section headers */
359 sects
= (struct section
*) &seg_hdr
[1];
361 if (swap
) swap_section(sects
, seg_hdr
->nsects
, host_order
);
364 /* Ignore segments with no vm size */
365 if (!seg_hdr
->vmsize
) continue;
367 /* Verify that the file is big enough for the segment data. */
368 require_action(size
>= seg_hdr
->fileoff
+ seg_hdr
->filesize
, finish
,
370 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
372 for (j
= 0; j
< seg_hdr
->nsects
; ++j
) {
374 /* Verify that, if the section is not to be zero filled on
375 * demand, that file is big enough for the section's data.
377 require_action((sects
[j
].flags
& S_ZEROFILL
) ||
378 (size
>= sects
[j
].offset
+ sects
[j
].size
), finish
,
380 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
382 /* Verify that the file is big enough for the section's
383 * relocation entries.
385 require_action(size
>=
386 sects
[j
].reloff
+ sects
[j
].nreloc
* sizeof(*relocs
), finish
,
388 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
390 /* Swap the relocation entries */
391 relocs
= (struct relocation_info
*) ((void *) (file
+ sects
[j
].reloff
));
394 swap_relocation_info(relocs
, sects
[j
].nreloc
,
402 /* Get and swap the symtab header */
403 symtab_hdr
= (struct symtab_command
*) load_hdr
;
405 if (swap
) swap_symtab_command(symtab_hdr
, host_order
);
408 /* Verify that the file is big enough for the symbol table */
409 require_action(size
>=
410 symtab_hdr
->symoff
+ symtab_hdr
->nsyms
* sizeof(*symtab
), finish
,
412 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
414 /* Verify that the file is big enough for the string table */
415 require_action(size
>= symtab_hdr
->stroff
+ symtab_hdr
->strsize
, finish
,
417 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
420 /* Swap the symbol table entries */
421 symtab
= (struct nlist
*) ((void *) (file
+ symtab_hdr
->symoff
));
422 if (swap
) swap_nlist(symtab
, symtab_hdr
->nsyms
, host_order
);
428 /* Swap the load command */
429 if (swap
) swap_load_command(load_hdr
, host_order
);
441 /*******************************************************************************
442 *******************************************************************************/
444 validate_and_swap_macho_64(u_char
*file
, u_long size
446 , enum NXByteOrder host_order
450 kern_return_t rval
= KERN_FAILURE
;
451 struct mach_header_64
*mach_hdr
= (struct mach_header_64
*) ((void *) file
);
452 struct load_command
*load_hdr
= NULL
;
453 struct segment_command_64
*seg_hdr
= NULL
;
454 struct section_64
*sects
= NULL
;
455 struct relocation_info
*relocs
= NULL
;
456 struct symtab_command
*symtab_hdr
= NULL
;
457 struct nlist_64
*symtab
= NULL
;
464 boolean_t swap
= FALSE
;
470 /* Verify that the file is big enough for the mach header */
471 require_action(size
>= sizeof(*mach_hdr
), finish
,
473 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
474 offset
= sizeof(*mach_hdr
);
477 /* Swap the mach header if necessary */
478 if (mach_hdr
->magic
== MH_CIGAM_64
) {
480 (void) swap_mach_header_64(mach_hdr
, host_order
);
484 /* Validate the mach_header's magic number */
485 require_action(mach_hdr
->magic
== MH_MAGIC_64
, finish
,
487 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
488 "Invalid magic number: 0x%x.", mach_hdr
->magic
));
490 /* If in the running kernel, and asked to validate the kernel
491 * (which is the only file of type MH_EXECUTE we should ever see),
492 * then just assume it's ok or we wouldn't be running to begin with.
495 if (mach_hdr
->filetype
== MH_EXECUTE
) {
501 /* Validate and potentially swap the load commands */
502 for(i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= cmdsize
) {
503 /* Get the load command and size */
504 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
506 cmdsize
= load_hdr
->cmdsize
;
510 cmd
= OSSwapInt32(load_hdr
->cmd
);
511 cmdsize
= OSSwapInt32(load_hdr
->cmdsize
);
515 /* Verify that the file is big enough to contain the load command */
516 require_action(size
>= offset
+ cmdsize
, finish
,
518 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
521 /* Get and swap the segment header */
522 seg_hdr
= (struct segment_command_64
*) ((void *) load_hdr
);
524 if (swap
) swap_segment_command_64(seg_hdr
, host_order
);
527 /* Get and swap the section headers */
528 sects
= (struct section_64
*) &seg_hdr
[1];
530 if (swap
) swap_section_64(sects
, seg_hdr
->nsects
, host_order
);
533 /* If the segment has no vm footprint, skip it */
534 if (!seg_hdr
->vmsize
) continue;
536 /* Verify that the file is big enough for the segment data. */
537 require_action(size
>= seg_hdr
->fileoff
+ seg_hdr
->filesize
, finish
,
539 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
541 for (j
= 0; j
< seg_hdr
->nsects
; ++j
) {
543 /* Verify that, if the section is not to be zero filled on
544 * demand, that file is big enough for the section's data.
546 require_action((sects
[j
].flags
& S_ZEROFILL
) ||
547 (size
>= sects
[j
].offset
+ sects
[j
].size
), finish
,
549 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
551 /* Verify that the file is big enough for the section's
552 * relocation entries.
554 require_action(size
>=
555 sects
[j
].reloff
+ sects
[j
].nreloc
* sizeof(*relocs
), finish
,
557 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
559 /* Swap the relocation entries */
560 relocs
= (struct relocation_info
*) ((void *) (file
+ sects
[j
].reloff
));
563 swap_relocation_info(relocs
, sects
[j
].nreloc
,
571 /* Get and swap the symtab header */
572 symtab_hdr
= (struct symtab_command
*) load_hdr
;
574 if (swap
) swap_symtab_command(symtab_hdr
, host_order
);
577 /* Verify that the file is big enough for the symbol table */
578 require_action(size
>=
579 symtab_hdr
->symoff
+ symtab_hdr
->nsyms
* sizeof(*symtab
), finish
,
581 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
583 /* Verify that the file is big enough for the string table */
584 require_action(size
>= symtab_hdr
->stroff
+ symtab_hdr
->strsize
, finish
,
586 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
589 /* Swap the symbol table entries */
590 symtab
= (struct nlist_64
*) ((void *) (file
+ symtab_hdr
->symoff
));
591 if (swap
) swap_nlist_64(symtab
, symtab_hdr
->nsyms
, host_order
);
597 /* Swap the load command */
598 if (swap
) swap_load_command(load_hdr
, host_order
);
611 /*******************************************************************************
612 *******************************************************************************/
613 void unswap_macho(u_char
*file
, enum NXByteOrder host_order
,
614 enum NXByteOrder target_order
)
616 struct mach_header
*hdr
= (struct mach_header
*) ((void *) file
);
620 if (hdr
->magic
== MH_MAGIC
) {
621 unswap_macho_32(file
, host_order
, target_order
);
622 } else if (hdr
->magic
== MH_MAGIC_64
) {
623 unswap_macho_64(file
, host_order
, target_order
);
627 /*******************************************************************************
628 *******************************************************************************/
630 unswap_macho_32(u_char
*file
, enum NXByteOrder host_order
,
631 enum NXByteOrder target_order
)
633 struct mach_header
*mach_hdr
= (struct mach_header
*) ((void *) file
);
634 struct load_command
*load_hdr
= NULL
;
635 struct segment_command
*seg_hdr
= NULL
;
636 struct section
*sects
= NULL
;
637 struct symtab_command
*symtab_hdr
= NULL
;
638 struct nlist
*symtab
= NULL
;
646 if (target_order
== host_order
) return;
648 offset
= sizeof(*mach_hdr
);
649 for(i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= size
) {
650 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
652 size
= load_hdr
->cmdsize
;
656 seg_hdr
= (struct segment_command
*) load_hdr
;
657 sects
= (struct section
*) &seg_hdr
[1];
659 /* We don't need to unswap relocations because this function is
660 * called when linking is completed (so there are no relocations).
663 swap_section(sects
, seg_hdr
->nsects
, target_order
);
664 swap_segment_command(seg_hdr
, target_order
);
667 symtab_hdr
= (struct symtab_command
*) load_hdr
;
668 symtab
= (struct nlist
*) ((void *) (file
+ symtab_hdr
->symoff
));
670 swap_nlist(symtab
, symtab_hdr
->nsyms
, target_order
);
671 swap_symtab_command(symtab_hdr
, target_order
);
675 swap_load_command(load_hdr
, target_order
);
680 (void) swap_mach_header(mach_hdr
, target_order
);
683 /*******************************************************************************
684 *******************************************************************************/
686 unswap_macho_64(u_char
*file
, enum NXByteOrder host_order
,
687 enum NXByteOrder target_order
)
689 struct mach_header_64
*mach_hdr
= (struct mach_header_64
*) ((void *) file
);
690 struct load_command
*load_hdr
= NULL
;
691 struct segment_command_64
*seg_hdr
= NULL
;
692 struct section_64
*sects
= NULL
;
693 struct symtab_command
*symtab_hdr
= NULL
;
694 struct nlist_64
*symtab
= NULL
;
702 if (target_order
== host_order
) return;
704 offset
= sizeof(*mach_hdr
);
705 for(i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= size
) {
706 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
708 size
= load_hdr
->cmdsize
;
712 seg_hdr
= (struct segment_command_64
*) ((void *) load_hdr
);
713 sects
= (struct section_64
*) &seg_hdr
[1];
715 /* We don't need to unswap relocations because this function is
716 * called when linking is completed (so there are no relocations).
719 swap_section_64(sects
, seg_hdr
->nsects
, target_order
);
720 swap_segment_command_64(seg_hdr
, target_order
);
723 symtab_hdr
= (struct symtab_command
*) load_hdr
;
724 symtab
= (struct nlist_64
*) ((void *) (file
+ symtab_hdr
->symoff
));
726 swap_nlist_64(symtab
, symtab_hdr
->nsyms
, target_order
);
727 swap_symtab_command(symtab_hdr
, target_order
);
731 swap_load_command(load_hdr
, target_order
);
736 (void) swap_mach_header_64(mach_hdr
, target_order
);
740 /*******************************************************************************
741 *******************************************************************************/
743 kxld_align_address(kxld_addr_t address
, u_int align
)
745 kxld_addr_t alignment
= (1 << align
);
746 kxld_addr_t low_bits
= 0;
748 if (!align
) return address
;
750 low_bits
= (address
) & (alignment
- 1);
752 address
+= (alignment
- low_bits
);
758 /*******************************************************************************
759 *******************************************************************************/
761 kxld_is_32_bit(cpu_type_t cputype
)
763 return !(cputype
& CPU_ARCH_ABI64
);
766 /*******************************************************************************
767 * Borrowed (and slightly modified) the libc implementation for the kernel
768 * until the kernel has a supported strstr().
769 * Find the first occurrence of find in s.
770 *******************************************************************************/
772 kxld_strstr(const char *s
, const char *find
)
778 if ((c
= *find
++) != 0) {
782 if ((sc
= *s
++) == 0)
785 } while (strncmp(s
, find
, len
) != 0);
790 return strstr(s
, find
);
794 /*******************************************************************************
795 *******************************************************************************/
797 kxld_print_memory_report(void)
800 kxld_log(kKxldLogLinking
, kKxldLogExplicit
, "kxld memory usage report:\n"
801 "\tNumber of allocations: %8lu\n"
802 "\tNumber of frees: %8lu\n"
803 "\tAverage allocation size: %8lu\n"
804 "\tTotal bytes allocated: %8lu\n"
805 "\tTotal bytes freed: %8lu\n"
806 "\tTotal bytes leaked: %8lu",
807 num_allocations
, num_frees
, bytes_allocated
/ num_allocations
,
808 bytes_allocated
, bytes_freed
, bytes_allocated
- bytes_freed
);
812 /*********************************************************************
813 *********************************************************************/
815 boolean_t
kxld_set_cross_link_page_size(kxld_size_t target_page_size
)
818 if ((target_page_size
!= 0) &&
819 ((target_page_size
& (target_page_size
- 1)) == 0)) {
821 s_cross_link_enabled
= TRUE
;
822 s_cross_link_page_size
= target_page_size
;
831 /*********************************************************************
832 *********************************************************************/
833 kxld_size_t
kxld_get_effective_page_size(void)
838 if (s_cross_link_enabled
) {
839 return s_cross_link_page_size
;
846 /*********************************************************************
847 *********************************************************************/
848 kxld_addr_t
kxld_round_page_cross_safe(kxld_addr_t offset
)
851 return round_page(offset
);
853 // assume s_cross_link_page_size is power of 2
854 if (s_cross_link_enabled
) {
855 return (offset
+ (s_cross_link_page_size
- 1)) &
856 (~(s_cross_link_page_size
- 1));
858 return round_page(offset
);
863 #if SPLIT_KEXTS_DEBUG
865 void kxld_show_split_info(splitKextLinkInfo
*info
)
867 kxld_log(kKxldLogLinking
, kKxldLogErr
,
868 "splitKextLinkInfo: \n"
869 "kextExecutable %p to %p kextSize %lu \n"
870 "linkedKext %p to %p linkedKextSize %lu \n"
871 "vmaddr_TEXT %p vmaddr_TEXT_EXEC %p "
872 "vmaddr_DATA %p vmaddr_DATA_CONST %p vmaddr_LINKEDIT %p",
873 (void *) info
->kextExecutable
,
874 (void *) (info
->kextExecutable
+ info
->kextSize
),
876 (void*) info
->linkedKext
,
877 (void*) (info
->linkedKext
+ info
->linkedKextSize
),
878 info
->linkedKextSize
,
879 (void *) info
->vmaddr_TEXT
,
880 (void *) info
->vmaddr_TEXT_EXEC
,
881 (void *) info
->vmaddr_DATA
,
882 (void *) info
->vmaddr_DATA_CONST
,
883 (void *) info
->vmaddr_LINKEDIT
);
886 boolean_t
isTargetKextName(const char * the_name
)
888 if (the_name
&& 0 == strcmp(the_name
, KXLD_TARGET_KEXT
)) {