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_calloc(size_t size
)
158 ptr
= calloc(1, size
);
164 bytes_allocated
+= size
;
172 kxld_alloc(size_t size
)
185 bytes_allocated
+= size
;
192 /*******************************************************************************
193 *******************************************************************************/
195 kxld_page_alloc_untracked(size_t size
)
199 kern_return_t rval
= 0;
200 vm_offset_t addr
= 0;
203 size
= round_page(size
);
206 if (size
< KALLOC_MAX
) {
209 rval
= kmem_alloc(kernel_map
, &addr
, size
, VM_KERN_MEMORY_OSKEXT
);
218 ptr
= calloc(1, size
);
224 /*******************************************************************************
225 *******************************************************************************/
227 kxld_page_alloc(size_t size
)
231 ptr
= kxld_page_alloc_untracked(size
);
235 bytes_allocated
+= round_page(size
);
242 /*******************************************************************************
243 *******************************************************************************/
245 kxld_alloc_pageable(size_t size
)
247 size
= round_page(size
);
250 kern_return_t rval
= 0;
253 rval
= kmem_alloc_pageable(kernel_map
, &ptr
, size
, VM_KERN_MEMORY_OSKEXT
);
260 return kxld_page_alloc_untracked(size
);
264 /*******************************************************************************
265 *******************************************************************************/
267 kxld_free(void *ptr
, size_t size __unused
)
281 /*******************************************************************************
282 *******************************************************************************/
284 kxld_page_free_untracked(void *ptr
, size_t size __unused
)
287 size
= round_page(size
);
289 if (size
< KALLOC_MAX
) {
292 kmem_free(kernel_map
, (vm_offset_t
) ptr
, size
);
300 /*******************************************************************************
301 *******************************************************************************/
303 kxld_page_free(void *ptr
, size_t size
)
307 bytes_freed
+= round_page(size
);
309 kxld_page_free_untracked(ptr
, size
);
312 /*******************************************************************************
313 *******************************************************************************/
315 validate_and_swap_macho_32(u_char
*file
, u_long size
317 , enum NXByteOrder host_order
321 kern_return_t rval
= KERN_FAILURE
;
322 struct mach_header
*mach_hdr
= (struct mach_header
*) ((void *) file
);
323 struct load_command
*load_hdr
= NULL
;
324 struct segment_command
*seg_hdr
= NULL
;
325 struct section
*sects
= NULL
;
326 struct relocation_info
*relocs
= NULL
;
327 struct symtab_command
*symtab_hdr
= NULL
;
328 struct nlist
*symtab
= NULL
;
335 boolean_t swap
= FALSE
;
341 /* Verify that the file is big enough for the mach header */
342 require_action(size
>= sizeof(*mach_hdr
), finish
,
344 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
345 offset
= sizeof(*mach_hdr
);
348 /* Swap the mach header if necessary */
349 if (mach_hdr
->magic
== MH_CIGAM
) {
351 (void) swap_mach_header(mach_hdr
, host_order
);
355 /* Validate the mach_header's magic number */
356 require_action(mach_hdr
->magic
== MH_MAGIC
, finish
,
358 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
359 "Invalid magic number: 0x%x.", mach_hdr
->magic
));
361 /* If in the running kernel, and asked to validate the kernel
362 * (which is the only file of type MH_EXECUTE we should ever see),
363 * then just assume it's ok or we wouldn't be running to begin with.
366 if (mach_hdr
->filetype
== MH_EXECUTE
) {
372 /* Validate and potentially swap the load commands */
373 for (i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= cmdsize
) {
374 /* Get the load command and size */
375 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
377 cmdsize
= load_hdr
->cmdsize
;
381 cmd
= OSSwapInt32(load_hdr
->cmd
);
382 cmdsize
= OSSwapInt32(load_hdr
->cmdsize
);
386 /* Verify that the file is big enough to contain the load command */
387 require_action(size
>= offset
+ cmdsize
, finish
,
389 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
393 /* Get and swap the segment header */
394 seg_hdr
= (struct segment_command
*) load_hdr
;
397 swap_segment_command(seg_hdr
, host_order
);
401 /* Get and swap the section headers */
402 sects
= (struct section
*) &seg_hdr
[1];
405 swap_section(sects
, seg_hdr
->nsects
, host_order
);
409 /* Ignore segments with no vm size */
410 if (!seg_hdr
->vmsize
) {
414 /* Verify that the file is big enough for the segment data. */
415 require_action(size
>= seg_hdr
->fileoff
+ seg_hdr
->filesize
, finish
,
417 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
419 for (j
= 0; j
< seg_hdr
->nsects
; ++j
) {
420 /* Verify that, if the section is not to be zero filled on
421 * demand, that file is big enough for the section's data.
423 require_action((sects
[j
].flags
& S_ZEROFILL
) ||
424 (size
>= sects
[j
].offset
+ sects
[j
].size
), finish
,
426 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
428 /* Verify that the file is big enough for the section's
429 * relocation entries.
431 require_action(size
>=
432 sects
[j
].reloff
+ sects
[j
].nreloc
* sizeof(*relocs
), finish
,
434 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
436 /* Swap the relocation entries */
437 relocs
= (struct relocation_info
*) ((void *) (file
+ sects
[j
].reloff
));
440 swap_relocation_info(relocs
, sects
[j
].nreloc
,
448 /* Get and swap the symtab header */
449 symtab_hdr
= (struct symtab_command
*) load_hdr
;
452 swap_symtab_command(symtab_hdr
, host_order
);
456 /* Verify that the file is big enough for the symbol table */
457 require_action(size
>=
458 symtab_hdr
->symoff
+ symtab_hdr
->nsyms
* sizeof(*symtab
), finish
,
460 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
462 /* Verify that the file is big enough for the string table */
463 require_action(size
>= symtab_hdr
->stroff
+ symtab_hdr
->strsize
, finish
,
465 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
468 /* Swap the symbol table entries */
469 symtab
= (struct nlist
*) ((void *) (file
+ symtab_hdr
->symoff
));
471 swap_nlist(symtab
, symtab_hdr
->nsyms
, host_order
);
478 /* Swap the load command */
480 swap_load_command(load_hdr
, host_order
);
493 /*******************************************************************************
494 *******************************************************************************/
496 validate_and_swap_macho_64(u_char
*file
, u_long size
498 , enum NXByteOrder host_order
502 kern_return_t rval
= KERN_FAILURE
;
503 struct mach_header_64
*mach_hdr
= (struct mach_header_64
*) ((void *) file
);
504 struct load_command
*load_hdr
= NULL
;
505 struct segment_command_64
*seg_hdr
= NULL
;
506 struct section_64
*sects
= NULL
;
507 struct relocation_info
*relocs
= NULL
;
508 struct symtab_command
*symtab_hdr
= NULL
;
509 struct nlist_64
*symtab
= NULL
;
516 boolean_t swap
= FALSE
;
522 /* Verify that the file is big enough for the mach header */
523 require_action(size
>= sizeof(*mach_hdr
), finish
,
525 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
526 offset
= sizeof(*mach_hdr
);
529 /* Swap the mach header if necessary */
530 if (mach_hdr
->magic
== MH_CIGAM_64
) {
532 (void) swap_mach_header_64(mach_hdr
, host_order
);
536 /* Validate the mach_header's magic number */
537 require_action(mach_hdr
->magic
== MH_MAGIC_64
, finish
,
539 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
540 "Invalid magic number: 0x%x.", mach_hdr
->magic
));
542 /* If in the running kernel, and asked to validate the kernel
543 * (which is the only file of type MH_EXECUTE we should ever see),
544 * then just assume it's ok or we wouldn't be running to begin with.
547 if (mach_hdr
->filetype
== MH_EXECUTE
) {
553 /* Validate and potentially swap the load commands */
554 for (i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= cmdsize
) {
555 /* Get the load command and size */
556 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
558 cmdsize
= load_hdr
->cmdsize
;
562 cmd
= OSSwapInt32(load_hdr
->cmd
);
563 cmdsize
= OSSwapInt32(load_hdr
->cmdsize
);
567 /* Verify that the file is big enough to contain the load command */
568 require_action(size
>= offset
+ cmdsize
, finish
,
570 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
573 /* Get and swap the segment header */
574 seg_hdr
= (struct segment_command_64
*) ((void *) load_hdr
);
577 swap_segment_command_64(seg_hdr
, host_order
);
581 /* Get and swap the section headers */
582 sects
= (struct section_64
*) &seg_hdr
[1];
585 swap_section_64(sects
, seg_hdr
->nsects
, host_order
);
589 /* If the segment has no vm footprint, skip it */
590 if (!seg_hdr
->vmsize
) {
594 /* Verify that the file is big enough for the segment data. */
595 require_action(size
>= seg_hdr
->fileoff
+ seg_hdr
->filesize
, finish
,
597 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
599 for (j
= 0; j
< seg_hdr
->nsects
; ++j
) {
600 /* Verify that, if the section is not to be zero filled on
601 * demand, that file is big enough for the section's data.
603 require_action((sects
[j
].flags
& S_ZEROFILL
) ||
604 (size
>= sects
[j
].offset
+ sects
[j
].size
), finish
,
606 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
608 /* Verify that the file is big enough for the section's
609 * relocation entries.
611 require_action(size
>=
612 sects
[j
].reloff
+ sects
[j
].nreloc
* sizeof(*relocs
), finish
,
614 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
616 /* Swap the relocation entries */
617 relocs
= (struct relocation_info
*) ((void *) (file
+ sects
[j
].reloff
));
620 swap_relocation_info(relocs
, sects
[j
].nreloc
,
628 /* Get and swap the symtab header */
629 symtab_hdr
= (struct symtab_command
*) load_hdr
;
632 swap_symtab_command(symtab_hdr
, host_order
);
636 /* Verify that the file is big enough for the symbol table */
637 require_action(size
>=
638 symtab_hdr
->symoff
+ symtab_hdr
->nsyms
* sizeof(*symtab
), finish
,
640 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
642 /* Verify that the file is big enough for the string table */
643 require_action(size
>= symtab_hdr
->stroff
+ symtab_hdr
->strsize
, finish
,
645 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
648 /* Swap the symbol table entries */
649 symtab
= (struct nlist_64
*) ((void *) (file
+ symtab_hdr
->symoff
));
651 swap_nlist_64(symtab
, symtab_hdr
->nsyms
, host_order
);
658 /* Swap the load command */
660 swap_load_command(load_hdr
, host_order
);
674 /*******************************************************************************
675 *******************************************************************************/
677 unswap_macho(u_char
*file
, enum NXByteOrder host_order
,
678 enum NXByteOrder target_order
)
680 struct mach_header
*hdr
= (struct mach_header
*) ((void *) file
);
686 if (hdr
->magic
== MH_MAGIC
) {
687 unswap_macho_32(file
, host_order
, target_order
);
688 } else if (hdr
->magic
== MH_MAGIC_64
) {
689 unswap_macho_64(file
, host_order
, target_order
);
693 /*******************************************************************************
694 *******************************************************************************/
696 unswap_macho_32(u_char
*file
, enum NXByteOrder host_order
,
697 enum NXByteOrder target_order
)
699 struct mach_header
*mach_hdr
= (struct mach_header
*) ((void *) file
);
700 struct load_command
*load_hdr
= NULL
;
701 struct segment_command
*seg_hdr
= NULL
;
702 struct section
*sects
= NULL
;
703 struct symtab_command
*symtab_hdr
= NULL
;
704 struct nlist
*symtab
= NULL
;
712 if (target_order
== host_order
) {
716 offset
= sizeof(*mach_hdr
);
717 for (i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= size
) {
718 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
720 size
= load_hdr
->cmdsize
;
724 seg_hdr
= (struct segment_command
*) load_hdr
;
725 sects
= (struct section
*) &seg_hdr
[1];
727 /* We don't need to unswap relocations because this function is
728 * called when linking is completed (so there are no relocations).
731 swap_section(sects
, seg_hdr
->nsects
, target_order
);
732 swap_segment_command(seg_hdr
, target_order
);
735 symtab_hdr
= (struct symtab_command
*) load_hdr
;
736 symtab
= (struct nlist
*) ((void *) (file
+ symtab_hdr
->symoff
));
738 swap_nlist(symtab
, symtab_hdr
->nsyms
, target_order
);
739 swap_symtab_command(symtab_hdr
, target_order
);
743 swap_load_command(load_hdr
, target_order
);
748 (void) swap_mach_header(mach_hdr
, target_order
);
751 /*******************************************************************************
752 *******************************************************************************/
754 unswap_macho_64(u_char
*file
, enum NXByteOrder host_order
,
755 enum NXByteOrder target_order
)
757 struct mach_header_64
*mach_hdr
= (struct mach_header_64
*) ((void *) file
);
758 struct load_command
*load_hdr
= NULL
;
759 struct segment_command_64
*seg_hdr
= NULL
;
760 struct section_64
*sects
= NULL
;
761 struct symtab_command
*symtab_hdr
= NULL
;
762 struct nlist_64
*symtab
= NULL
;
770 if (target_order
== host_order
) {
774 offset
= sizeof(*mach_hdr
);
775 for (i
= 0; i
< mach_hdr
->ncmds
; ++i
, offset
+= size
) {
776 load_hdr
= (struct load_command
*) ((void *) (file
+ offset
));
778 size
= load_hdr
->cmdsize
;
782 seg_hdr
= (struct segment_command_64
*) ((void *) load_hdr
);
783 sects
= (struct section_64
*) &seg_hdr
[1];
785 /* We don't need to unswap relocations because this function is
786 * called when linking is completed (so there are no relocations).
789 swap_section_64(sects
, seg_hdr
->nsects
, target_order
);
790 swap_segment_command_64(seg_hdr
, target_order
);
793 symtab_hdr
= (struct symtab_command
*) load_hdr
;
794 symtab
= (struct nlist_64
*) ((void *) (file
+ symtab_hdr
->symoff
));
796 swap_nlist_64(symtab
, symtab_hdr
->nsyms
, target_order
);
797 swap_symtab_command(symtab_hdr
, target_order
);
801 swap_load_command(load_hdr
, target_order
);
806 (void) swap_mach_header_64(mach_hdr
, target_order
);
810 /*******************************************************************************
811 *******************************************************************************/
813 kxld_align_address(kxld_addr_t address
, u_int align
)
815 kxld_addr_t alignment
= (1 << align
);
816 kxld_addr_t low_bits
= 0;
822 low_bits
= (address
) & (alignment
- 1);
824 address
+= (alignment
- low_bits
);
830 /*******************************************************************************
831 *******************************************************************************/
833 kxld_is_32_bit(cpu_type_t cputype
)
835 return !(cputype
& CPU_ARCH_ABI64
);
838 /*******************************************************************************
839 * Borrowed (and slightly modified) the libc implementation for the kernel
840 * until the kernel has a supported strstr().
841 * Find the first occurrence of find in s.
842 *******************************************************************************/
844 kxld_strstr(const char *s
, const char *find
)
852 if ((c
= *find
++) != 0) {
856 if ((sc
= *s
++) == 0) {
860 } while (strncmp(s
, find
, len
) != 0);
865 return strstr(s
, find
);
869 /*******************************************************************************
870 *******************************************************************************/
872 kxld_print_memory_report(void)
875 kxld_log(kKxldLogLinking
, kKxldLogExplicit
, "kxld memory usage report:\n"
876 "\tNumber of allocations: %8lu\n"
877 "\tNumber of frees: %8lu\n"
878 "\tAverage allocation size: %8lu\n"
879 "\tTotal bytes allocated: %8lu\n"
880 "\tTotal bytes freed: %8lu\n"
881 "\tTotal bytes leaked: %8lu",
882 num_allocations
, num_frees
, bytes_allocated
/ num_allocations
,
883 bytes_allocated
, bytes_freed
, bytes_allocated
- bytes_freed
);
887 /*********************************************************************
888 *********************************************************************/
891 kxld_set_cross_link_page_size(kxld_size_t target_page_size
)
894 if ((target_page_size
!= 0) &&
895 ((target_page_size
& (target_page_size
- 1)) == 0)) {
896 s_cross_link_enabled
= TRUE
;
897 s_cross_link_page_size
= target_page_size
;
906 /*********************************************************************
907 *********************************************************************/
909 kxld_get_effective_page_size(void)
914 if (s_cross_link_enabled
) {
915 return s_cross_link_page_size
;
922 /*********************************************************************
923 *********************************************************************/
925 kxld_round_page_cross_safe(kxld_addr_t offset
)
928 return round_page(offset
);
930 // assume s_cross_link_page_size is power of 2
931 if (s_cross_link_enabled
) {
932 return (offset
+ (s_cross_link_page_size
- 1)) &
933 (~(s_cross_link_page_size
- 1));
935 return round_page(offset
);
940 #if SPLIT_KEXTS_DEBUG
943 kxld_show_split_info(splitKextLinkInfo
*info
)
945 kxld_log(kKxldLogLinking
, kKxldLogErr
,
946 "splitKextLinkInfo: \n"
947 "kextExecutable %p to %p kextSize %lu \n"
948 "linkedKext %p to %p linkedKextSize %lu \n"
949 "vmaddr_TEXT %p vmaddr_TEXT_EXEC %p "
950 "vmaddr_DATA %p vmaddr_DATA_CONST %p "
951 "vmaddr_LLVM_COV %p vmaddr_LINKEDIT %p",
952 (void *) info
->kextExecutable
,
953 (void *) (info
->kextExecutable
+ info
->kextSize
),
955 (void*) info
->linkedKext
,
956 (void*) (info
->linkedKext
+ info
->linkedKextSize
),
957 info
->linkedKextSize
,
958 (void *) info
->vmaddr_TEXT
,
959 (void *) info
->vmaddr_TEXT_EXEC
,
960 (void *) info
->vmaddr_DATA
,
961 (void *) info
->vmaddr_DATA_CONST
,
962 (void *) info
->vmaddr_LLVM_COV
,
963 (void *) info
->vmaddr_LINKEDIT
);
967 isTargetKextName(const char * the_name
)
969 if (the_name
&& 0 == strcmp(the_name
, KXLD_TARGET_KEXT
)) {