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 char s_callback_name
[64] = "internal";
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
)
88 (void)strlcpy(s_callback_name
, name
, sizeof(s_callback_name
));
89 /* disallow format strings in the kxld logging callback name */
90 for (size_t i
= 0; i
< sizeof(s_callback_name
); i
++) {
91 if (s_callback_name
[i
] == '%') {
92 s_callback_name
[i
] = '.';
96 (void)strlcpy(s_callback_name
, "internal", sizeof(s_callback_name
));
99 s_callback_data
= user_data
;
102 /*******************************************************************************
103 *******************************************************************************/
105 kxld_log(KXLDLogSubsystem subsystem
, KXLDLogLevel level
,
106 const char *in_format
, ...)
108 char stack_buffer
[256];
109 char *alloc_buffer
= NULL
;
110 char *format
= stack_buffer
;
114 if (s_logging_callback
) {
115 length
= snprintf(stack_buffer
, sizeof(stack_buffer
), "kxld[%s]: %s",
116 s_callback_name
, in_format
);
118 if (length
>= sizeof(stack_buffer
)) {
120 alloc_buffer
= kxld_alloc(length
);
125 snprintf(alloc_buffer
, length
, "kxld[%s]: %s",
126 s_callback_name
, in_format
);
127 format
= alloc_buffer
;
130 va_start(ap
, in_format
);
131 s_logging_callback(subsystem
, level
, format
, ap
, s_callback_data
);
135 kxld_free(alloc_buffer
, length
);
140 /* We'll use kalloc for any page-based allocations under this threshold, and
141 * kmem_alloc otherwise.
143 #define KALLOC_MAX 16 * 1024
145 /*******************************************************************************
146 *******************************************************************************/
148 kxld_alloc(size_t size
)
161 bytes_allocated
+= size
;
168 /*******************************************************************************
169 *******************************************************************************/
171 kxld_page_alloc_untracked(size_t size
)
175 kern_return_t rval
= 0;
176 vm_offset_t addr
= 0;
179 size
= round_page(size
);
182 if (size
< KALLOC_MAX
) {
185 rval
= kmem_alloc(kernel_map
, &addr
, size
, VM_KERN_MEMORY_OSKEXT
);
197 /*******************************************************************************
198 *******************************************************************************/
200 kxld_page_alloc(size_t size
)
204 ptr
= kxld_page_alloc_untracked(size
);
208 bytes_allocated
+= round_page(size
);
215 /*******************************************************************************
216 *******************************************************************************/
218 kxld_alloc_pageable(size_t size
)
220 size
= round_page(size
);
223 kern_return_t rval
= 0;
226 rval
= kmem_alloc_pageable(kernel_map
, &ptr
, size
, VM_KERN_MEMORY_OSKEXT
);
233 return kxld_page_alloc_untracked(size
);
237 /*******************************************************************************
238 *******************************************************************************/
240 kxld_free(void *ptr
, size_t size __unused
)
254 /*******************************************************************************
255 *******************************************************************************/
257 kxld_page_free_untracked(void *ptr
, size_t size __unused
)
260 size
= round_page(size
);
262 if (size
< KALLOC_MAX
) {
265 kmem_free(kernel_map
, (vm_offset_t
) ptr
, size
);
273 /*******************************************************************************
274 *******************************************************************************/
276 kxld_page_free(void *ptr
, size_t size
)
280 bytes_freed
+= round_page(size
);
282 kxld_page_free_untracked(ptr
, size
);
285 /*******************************************************************************
286 *******************************************************************************/
288 validate_and_swap_macho_32(u_char
*file
, u_long size
290 , enum NXByteOrder host_order
294 kern_return_t rval
= KERN_FAILURE
;
295 struct mach_header
*mach_hdr
= (struct mach_header
*) ((void *) file
);
296 struct load_command
*load_hdr
= NULL
;
297 struct segment_command
*seg_hdr
= NULL
;
298 struct section
*sects
= NULL
;
299 struct relocation_info
*relocs
= NULL
;
300 struct symtab_command
*symtab_hdr
= NULL
;
301 struct nlist
*symtab
= NULL
;
308 boolean_t swap
= FALSE
;
314 /* Verify that the file is big enough for the mach header */
315 require_action(size
>= sizeof(*mach_hdr
), finish
,
317 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
318 offset
= sizeof(*mach_hdr
);
321 /* Swap the mach header if necessary */
322 if (mach_hdr
->magic
== MH_CIGAM
) {
324 (void) swap_mach_header(mach_hdr
, host_order
);
328 /* Validate the mach_header's magic number */
329 require_action(mach_hdr
->magic
== MH_MAGIC
, finish
,
331 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
332 "Invalid magic number: 0x%x.", mach_hdr
->magic
));
334 /* If in the running kernel, and asked to validate the kernel
335 * (which is the only file of type MH_EXECUTE we should ever see),
336 * then just assume it's ok or we wouldn't be running to begin with.
339 if (mach_hdr
->filetype
== MH_EXECUTE
) {
345 /* Validate and potentially swap the load commands */
346 for (i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= cmdsize
) {
347 /* Get the load command and size */
348 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
350 cmdsize
= load_hdr
->cmdsize
;
354 cmd
= OSSwapInt32(load_hdr
->cmd
);
355 cmdsize
= OSSwapInt32(load_hdr
->cmdsize
);
359 /* Verify that the file is big enough to contain the load command */
360 require_action(size
>= offset
+ cmdsize
, finish
,
362 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
366 /* Get and swap the segment header */
367 seg_hdr
= (struct segment_command
*) load_hdr
;
370 swap_segment_command(seg_hdr
, host_order
);
374 /* Get and swap the section headers */
375 sects
= (struct section
*) &seg_hdr
[1];
378 swap_section(sects
, seg_hdr
->nsects
, host_order
);
382 /* Ignore segments with no vm size */
383 if (!seg_hdr
->vmsize
) {
387 /* Verify that the file is big enough for the segment data. */
388 require_action(size
>= seg_hdr
->fileoff
+ seg_hdr
->filesize
, finish
,
390 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
392 for (j
= 0; j
< seg_hdr
->nsects
; ++j
) {
393 /* Verify that, if the section is not to be zero filled on
394 * demand, that file is big enough for the section's data.
396 require_action((sects
[j
].flags
& S_ZEROFILL
) ||
397 (size
>= sects
[j
].offset
+ sects
[j
].size
), finish
,
399 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
401 /* Verify that the file is big enough for the section's
402 * relocation entries.
404 require_action(size
>=
405 sects
[j
].reloff
+ sects
[j
].nreloc
* sizeof(*relocs
), finish
,
407 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
409 /* Swap the relocation entries */
410 relocs
= (struct relocation_info
*) ((void *) (file
+ sects
[j
].reloff
));
413 swap_relocation_info(relocs
, sects
[j
].nreloc
,
421 /* Get and swap the symtab header */
422 symtab_hdr
= (struct symtab_command
*) load_hdr
;
425 swap_symtab_command(symtab_hdr
, host_order
);
429 /* Verify that the file is big enough for the symbol table */
430 require_action(size
>=
431 symtab_hdr
->symoff
+ symtab_hdr
->nsyms
* sizeof(*symtab
), finish
,
433 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
435 /* Verify that the file is big enough for the string table */
436 require_action(size
>= symtab_hdr
->stroff
+ symtab_hdr
->strsize
, finish
,
438 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
441 /* Swap the symbol table entries */
442 symtab
= (struct nlist
*) ((void *) (file
+ symtab_hdr
->symoff
));
444 swap_nlist(symtab
, symtab_hdr
->nsyms
, host_order
);
451 /* Swap the load command */
453 swap_load_command(load_hdr
, host_order
);
466 /*******************************************************************************
467 *******************************************************************************/
469 validate_and_swap_macho_64(u_char
*file
, u_long size
471 , enum NXByteOrder host_order
475 kern_return_t rval
= KERN_FAILURE
;
476 struct mach_header_64
*mach_hdr
= (struct mach_header_64
*) ((void *) file
);
477 struct load_command
*load_hdr
= NULL
;
478 struct segment_command_64
*seg_hdr
= NULL
;
479 struct section_64
*sects
= NULL
;
480 struct relocation_info
*relocs
= NULL
;
481 struct symtab_command
*symtab_hdr
= NULL
;
482 struct nlist_64
*symtab
= NULL
;
489 boolean_t swap
= FALSE
;
495 /* Verify that the file is big enough for the mach header */
496 require_action(size
>= sizeof(*mach_hdr
), finish
,
498 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
499 offset
= sizeof(*mach_hdr
);
502 /* Swap the mach header if necessary */
503 if (mach_hdr
->magic
== MH_CIGAM_64
) {
505 (void) swap_mach_header_64(mach_hdr
, host_order
);
509 /* Validate the mach_header's magic number */
510 require_action(mach_hdr
->magic
== MH_MAGIC_64
, finish
,
512 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
513 "Invalid magic number: 0x%x.", mach_hdr
->magic
));
515 /* If in the running kernel, and asked to validate the kernel
516 * (which is the only file of type MH_EXECUTE we should ever see),
517 * then just assume it's ok or we wouldn't be running to begin with.
520 if (mach_hdr
->filetype
== MH_EXECUTE
) {
526 /* Validate and potentially swap the load commands */
527 for (i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= cmdsize
) {
528 /* Get the load command and size */
529 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
531 cmdsize
= load_hdr
->cmdsize
;
535 cmd
= OSSwapInt32(load_hdr
->cmd
);
536 cmdsize
= OSSwapInt32(load_hdr
->cmdsize
);
540 /* Verify that the file is big enough to contain the load command */
541 require_action(size
>= offset
+ cmdsize
, finish
,
543 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
546 /* Get and swap the segment header */
547 seg_hdr
= (struct segment_command_64
*) ((void *) load_hdr
);
550 swap_segment_command_64(seg_hdr
, host_order
);
554 /* Get and swap the section headers */
555 sects
= (struct section_64
*) &seg_hdr
[1];
558 swap_section_64(sects
, seg_hdr
->nsects
, host_order
);
562 /* If the segment has no vm footprint, skip it */
563 if (!seg_hdr
->vmsize
) {
567 /* Verify that the file is big enough for the segment data. */
568 require_action(size
>= seg_hdr
->fileoff
+ seg_hdr
->filesize
, finish
,
570 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
572 for (j
= 0; j
< seg_hdr
->nsects
; ++j
) {
573 /* Verify that, if the section is not to be zero filled on
574 * demand, that file is big enough for the section's data.
576 require_action((sects
[j
].flags
& S_ZEROFILL
) ||
577 (size
>= sects
[j
].offset
+ sects
[j
].size
), finish
,
579 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
581 /* Verify that the file is big enough for the section's
582 * relocation entries.
584 require_action(size
>=
585 sects
[j
].reloff
+ sects
[j
].nreloc
* sizeof(*relocs
), finish
,
587 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
589 /* Swap the relocation entries */
590 relocs
= (struct relocation_info
*) ((void *) (file
+ sects
[j
].reloff
));
593 swap_relocation_info(relocs
, sects
[j
].nreloc
,
601 /* Get and swap the symtab header */
602 symtab_hdr
= (struct symtab_command
*) load_hdr
;
605 swap_symtab_command(symtab_hdr
, host_order
);
609 /* Verify that the file is big enough for the symbol table */
610 require_action(size
>=
611 symtab_hdr
->symoff
+ symtab_hdr
->nsyms
* sizeof(*symtab
), finish
,
613 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
615 /* Verify that the file is big enough for the string table */
616 require_action(size
>= symtab_hdr
->stroff
+ symtab_hdr
->strsize
, finish
,
618 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
621 /* Swap the symbol table entries */
622 symtab
= (struct nlist_64
*) ((void *) (file
+ symtab_hdr
->symoff
));
624 swap_nlist_64(symtab
, symtab_hdr
->nsyms
, host_order
);
631 /* Swap the load command */
633 swap_load_command(load_hdr
, host_order
);
647 /*******************************************************************************
648 *******************************************************************************/
650 unswap_macho(u_char
*file
, enum NXByteOrder host_order
,
651 enum NXByteOrder target_order
)
653 struct mach_header
*hdr
= (struct mach_header
*) ((void *) file
);
659 if (hdr
->magic
== MH_MAGIC
) {
660 unswap_macho_32(file
, host_order
, target_order
);
661 } else if (hdr
->magic
== MH_MAGIC_64
) {
662 unswap_macho_64(file
, host_order
, target_order
);
666 /*******************************************************************************
667 *******************************************************************************/
669 unswap_macho_32(u_char
*file
, enum NXByteOrder host_order
,
670 enum NXByteOrder target_order
)
672 struct mach_header
*mach_hdr
= (struct mach_header
*) ((void *) file
);
673 struct load_command
*load_hdr
= NULL
;
674 struct segment_command
*seg_hdr
= NULL
;
675 struct section
*sects
= NULL
;
676 struct symtab_command
*symtab_hdr
= NULL
;
677 struct nlist
*symtab
= NULL
;
685 if (target_order
== host_order
) {
689 offset
= sizeof(*mach_hdr
);
690 for (i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= size
) {
691 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
693 size
= load_hdr
->cmdsize
;
697 seg_hdr
= (struct segment_command
*) load_hdr
;
698 sects
= (struct section
*) &seg_hdr
[1];
700 /* We don't need to unswap relocations because this function is
701 * called when linking is completed (so there are no relocations).
704 swap_section(sects
, seg_hdr
->nsects
, target_order
);
705 swap_segment_command(seg_hdr
, target_order
);
708 symtab_hdr
= (struct symtab_command
*) load_hdr
;
709 symtab
= (struct nlist
*) ((void *) (file
+ symtab_hdr
->symoff
));
711 swap_nlist(symtab
, symtab_hdr
->nsyms
, target_order
);
712 swap_symtab_command(symtab_hdr
, target_order
);
716 swap_load_command(load_hdr
, target_order
);
721 (void) swap_mach_header(mach_hdr
, target_order
);
724 /*******************************************************************************
725 *******************************************************************************/
727 unswap_macho_64(u_char
*file
, enum NXByteOrder host_order
,
728 enum NXByteOrder target_order
)
730 struct mach_header_64
*mach_hdr
= (struct mach_header_64
*) ((void *) file
);
731 struct load_command
*load_hdr
= NULL
;
732 struct segment_command_64
*seg_hdr
= NULL
;
733 struct section_64
*sects
= NULL
;
734 struct symtab_command
*symtab_hdr
= NULL
;
735 struct nlist_64
*symtab
= NULL
;
743 if (target_order
== host_order
) {
747 offset
= sizeof(*mach_hdr
);
748 for (i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= size
) {
749 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
751 size
= load_hdr
->cmdsize
;
755 seg_hdr
= (struct segment_command_64
*) ((void *) load_hdr
);
756 sects
= (struct section_64
*) &seg_hdr
[1];
758 /* We don't need to unswap relocations because this function is
759 * called when linking is completed (so there are no relocations).
762 swap_section_64(sects
, seg_hdr
->nsects
, target_order
);
763 swap_segment_command_64(seg_hdr
, target_order
);
766 symtab_hdr
= (struct symtab_command
*) load_hdr
;
767 symtab
= (struct nlist_64
*) ((void *) (file
+ symtab_hdr
->symoff
));
769 swap_nlist_64(symtab
, symtab_hdr
->nsyms
, target_order
);
770 swap_symtab_command(symtab_hdr
, target_order
);
774 swap_load_command(load_hdr
, target_order
);
779 (void) swap_mach_header_64(mach_hdr
, target_order
);
783 /*******************************************************************************
784 *******************************************************************************/
786 kxld_align_address(kxld_addr_t address
, u_int align
)
788 kxld_addr_t alignment
= (1 << align
);
789 kxld_addr_t low_bits
= 0;
795 low_bits
= (address
) & (alignment
- 1);
797 address
+= (alignment
- low_bits
);
803 /*******************************************************************************
804 *******************************************************************************/
806 kxld_is_32_bit(cpu_type_t cputype
)
808 return !(cputype
& CPU_ARCH_ABI64
);
811 /*******************************************************************************
812 * Borrowed (and slightly modified) the libc implementation for the kernel
813 * until the kernel has a supported strstr().
814 * Find the first occurrence of find in s.
815 *******************************************************************************/
817 kxld_strstr(const char *s
, const char *find
)
825 if ((c
= *find
++) != 0) {
829 if ((sc
= *s
++) == 0) {
833 } while (strncmp(s
, find
, len
) != 0);
838 return strstr(s
, find
);
842 /*******************************************************************************
843 *******************************************************************************/
845 kxld_print_memory_report(void)
848 kxld_log(kKxldLogLinking
, kKxldLogExplicit
, "kxld memory usage report:\n"
849 "\tNumber of allocations: %8lu\n"
850 "\tNumber of frees: %8lu\n"
851 "\tAverage allocation size: %8lu\n"
852 "\tTotal bytes allocated: %8lu\n"
853 "\tTotal bytes freed: %8lu\n"
854 "\tTotal bytes leaked: %8lu",
855 num_allocations
, num_frees
, bytes_allocated
/ num_allocations
,
856 bytes_allocated
, bytes_freed
, bytes_allocated
- bytes_freed
);
860 /*********************************************************************
861 *********************************************************************/
864 kxld_set_cross_link_page_size(kxld_size_t target_page_size
)
867 if ((target_page_size
!= 0) &&
868 ((target_page_size
& (target_page_size
- 1)) == 0)) {
869 s_cross_link_enabled
= TRUE
;
870 s_cross_link_page_size
= target_page_size
;
879 /*********************************************************************
880 *********************************************************************/
882 kxld_get_effective_page_size(void)
887 if (s_cross_link_enabled
) {
888 return s_cross_link_page_size
;
895 /*********************************************************************
896 *********************************************************************/
898 kxld_round_page_cross_safe(kxld_addr_t offset
)
901 return round_page(offset
);
903 // assume s_cross_link_page_size is power of 2
904 if (s_cross_link_enabled
) {
905 return (offset
+ (s_cross_link_page_size
- 1)) &
906 (~(s_cross_link_page_size
- 1));
908 return round_page(offset
);
913 #if SPLIT_KEXTS_DEBUG
916 kxld_show_split_info(splitKextLinkInfo
*info
)
918 kxld_log(kKxldLogLinking
, kKxldLogErr
,
919 "splitKextLinkInfo: \n"
920 "kextExecutable %p to %p kextSize %lu \n"
921 "linkedKext %p to %p linkedKextSize %lu \n"
922 "vmaddr_TEXT %p vmaddr_TEXT_EXEC %p "
923 "vmaddr_DATA %p vmaddr_DATA_CONST %p "
924 "vmaddr_LLVM_COV %p vmaddr_LINKEDIT %p",
925 (void *) info
->kextExecutable
,
926 (void *) (info
->kextExecutable
+ info
->kextSize
),
928 (void*) info
->linkedKext
,
929 (void*) (info
->linkedKext
+ info
->linkedKextSize
),
930 info
->linkedKextSize
,
931 (void *) info
->vmaddr_TEXT
,
932 (void *) info
->vmaddr_TEXT_EXEC
,
933 (void *) info
->vmaddr_DATA
,
934 (void *) info
->vmaddr_DATA_CONST
,
935 (void *) info
->vmaddr_LLVM_COV
,
936 (void *) info
->vmaddr_LINKEDIT
);
940 isTargetKextName(const char * the_name
)
942 if (the_name
&& 0 == strcmp(the_name
, KXLD_TARGET_KEXT
)) {