2 * Copyright (c) 2008 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@
29 #include <mach-o/loader.h>
30 #include <sys/types.h>
37 #include <kern/assert.h>
42 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
43 #include <AssertMacros.h>
45 #include "kxld_demangle.h"
46 #include "kxld_dict.h"
47 #include "kxld_object.h"
48 #include "kxld_reloc.h"
49 #include "kxld_sect.h"
51 #include "kxld_symtab.h"
52 #include "kxld_util.h"
53 #include "kxld_vtable.h"
55 #define VTABLE_ENTRY_SIZE_32 4
56 #define VTABLE_HEADER_LEN_32 2
57 #define VTABLE_HEADER_SIZE_32 (VTABLE_HEADER_LEN_32 * VTABLE_ENTRY_SIZE_32)
59 #define VTABLE_ENTRY_SIZE_64 8
60 #define VTABLE_HEADER_LEN_64 2
61 #define VTABLE_HEADER_SIZE_64 (VTABLE_HEADER_LEN_64 * VTABLE_ENTRY_SIZE_64)
63 static void get_vtable_base_sizes(boolean_t is_32_bit
, u_int
*vtable_entry_size
,
64 u_int
*vtable_header_size
);
66 static kern_return_t
init_by_relocs(KXLDVTable
*vtable
, const KXLDSym
*vtable_sym
,
67 const KXLDSect
*sect
, const KXLDRelocator
*relocator
);
69 static kern_return_t
init_by_entries_and_relocs(KXLDVTable
*vtable
,
70 const KXLDSym
*vtable_sym
, const KXLDRelocator
*relocator
,
71 const KXLDArray
*relocs
, const KXLDDict
*defined_cxx_symbols
);
73 static kern_return_t
init_by_entries(KXLDVTable
*vtable
,
74 const KXLDRelocator
*relocator
, const KXLDDict
*defined_cxx_symbols
);
76 /*******************************************************************************
77 *******************************************************************************/
79 kxld_vtable_init(KXLDVTable
*vtable
, const KXLDSym
*vtable_sym
,
80 const KXLDObject
*object
, const KXLDDict
*defined_cxx_symbols
)
82 kern_return_t rval
= KERN_FAILURE
;
83 const KXLDArray
*extrelocs
= NULL
;
84 const KXLDRelocator
*relocator
= NULL
;
85 const KXLDSect
*vtable_sect
= NULL
;
86 char *demangled_name
= NULL
;
87 size_t demangled_length
= 0;
93 relocator
= kxld_object_get_relocator(object
);
95 vtable_sect
= kxld_object_get_section_by_index(object
,
97 require_action(vtable_sect
, finish
, rval
=KERN_FAILURE
);
99 vtable
->name
= vtable_sym
->name
;
100 vtable
->vtable
= vtable_sect
->data
+
101 kxld_sym_get_section_offset(vtable_sym
, vtable_sect
);
103 if (kxld_object_is_linked(object
)) {
104 rval
= init_by_entries(vtable
, relocator
, defined_cxx_symbols
);
105 require_noerr(rval
, finish
);
107 vtable
->is_patched
= TRUE
;
109 if (kxld_object_is_final_image(object
)) {
110 extrelocs
= kxld_object_get_extrelocs(object
);
111 require_action(extrelocs
, finish
,
113 kxld_log(kKxldLogPatching
, kKxldLogErr
,
114 kKxldLogMalformedVTable
,
115 kxld_demangle(vtable
->name
,
116 &demangled_name
, &demangled_length
)));
118 rval
= init_by_entries_and_relocs(vtable
, vtable_sym
,
119 relocator
, extrelocs
, defined_cxx_symbols
);
120 require_noerr(rval
, finish
);
122 require_action(kxld_sect_get_num_relocs(vtable_sect
) > 0, finish
,
124 kxld_log(kKxldLogPatching
, kKxldLogErr
,
125 kKxldLogMalformedVTable
,
126 kxld_demangle(vtable
->name
,
127 &demangled_name
, &demangled_length
)));
129 rval
= init_by_relocs(vtable
, vtable_sym
, vtable_sect
, relocator
);
130 require_noerr(rval
, finish
);
133 vtable
->is_patched
= FALSE
;
138 if (demangled_name
) kxld_free(demangled_name
, demangled_length
);
143 /*******************************************************************************
144 *******************************************************************************/
146 get_vtable_base_sizes(boolean_t is_32_bit
, u_int
*vtable_entry_size
,
147 u_int
*vtable_header_size
)
149 check(vtable_entry_size
);
150 check(vtable_header_size
);
153 *vtable_entry_size
= VTABLE_ENTRY_SIZE_32
;
154 *vtable_header_size
= VTABLE_HEADER_SIZE_32
;
156 *vtable_entry_size
= VTABLE_ENTRY_SIZE_64
;
157 *vtable_header_size
= VTABLE_HEADER_SIZE_64
;
161 /*******************************************************************************
162 * Initializes a vtable object by matching up relocation entries to the vtable's
163 * entries and finding the corresponding symbols.
164 *******************************************************************************/
166 init_by_relocs(KXLDVTable
*vtable
, const KXLDSym
*vtable_sym
,
167 const KXLDSect
*sect
, const KXLDRelocator
*relocator
)
169 kern_return_t rval
= KERN_FAILURE
;
170 KXLDReloc
*reloc
= NULL
;
171 KXLDVTableEntry
*entry
= NULL
;
173 kxld_addr_t vtable_base_offset
= 0;
174 kxld_addr_t entry_offset
= 0;
177 u_int vtable_entry_size
= 0;
178 u_int vtable_header_size
= 0;
179 u_int base_reloc_index
= 0;
180 u_int reloc_index
= 0;
187 /* Find the first entry past the vtable padding */
189 (void) get_vtable_base_sizes(relocator
->is_32_bit
,
190 &vtable_entry_size
, &vtable_header_size
);
192 vtable_base_offset
= kxld_sym_get_section_offset(vtable_sym
, sect
) +
195 /* Find the relocation entry at the start of the vtable */
197 rval
= kxld_reloc_get_reloc_index_by_offset(§
->relocs
,
198 vtable_base_offset
, &base_reloc_index
);
199 require_noerr(rval
, finish
);
201 /* Count the number of consecutive relocation entries to find the number of
202 * vtable entries. For some reason, the __TEXT,__const relocations are
203 * sorted in descending order, so we have to walk backwards. Also, make
204 * sure we don't run off the end of the section's relocs.
207 reloc_index
= base_reloc_index
;
208 entry_offset
= vtable_base_offset
;
209 reloc
= kxld_array_get_item(§
->relocs
, reloc_index
);
210 while (reloc
->address
== entry_offset
) {
212 if (!reloc_index
) break;
216 reloc
= kxld_array_get_item(§
->relocs
, reloc_index
);
217 entry_offset
+= vtable_entry_size
;
220 /* Allocate the symbol index */
222 rval
= kxld_array_init(&vtable
->entries
, sizeof(KXLDVTableEntry
), nentries
);
223 require_noerr(rval
, finish
);
225 /* Find the symbols for each vtable entry */
227 for (i
= 0; i
< vtable
->entries
.nitems
; ++i
) {
228 reloc
= kxld_array_get_item(§
->relocs
, base_reloc_index
- i
);
229 entry
= kxld_array_get_item(&vtable
->entries
, i
);
231 /* If we can't find a symbol, it means it is a locally-defined,
232 * non-external symbol that has been stripped. We don't patch over
233 * locally-defined symbols, so we leave the symbol as NULL and just
234 * skip it. We won't be able to patch subclasses with this symbol,
235 * but there isn't much we can do about that.
237 sym
= kxld_reloc_get_symbol(relocator
, reloc
, sect
->data
);
239 entry
->unpatched
.sym
= sym
;
240 entry
->unpatched
.reloc
= reloc
;
248 /*******************************************************************************
249 * Initializes a vtable object by reading the symbol values out of the vtable
250 * entries and performing reverse symbol lookups on those values.
251 *******************************************************************************/
253 init_by_entries(KXLDVTable
*vtable
, const KXLDRelocator
*relocator
,
254 const KXLDDict
*defined_cxx_symbols
)
256 kern_return_t rval
= KERN_FAILURE
;
257 KXLDVTableEntry
*tmpentry
= NULL
;
259 kxld_addr_t entry_value
= 0;
261 u_int vtable_entry_size
= 0;
262 u_int vtable_header_size
= 0;
269 (void) get_vtable_base_sizes(relocator
->is_32_bit
,
270 &vtable_entry_size
, &vtable_header_size
);
272 /* Count the number of entries (the vtable is null-terminated) */
274 entry_offset
= vtable_header_size
;
276 entry_value
= kxld_relocator_get_pointer_at_addr(relocator
,
277 vtable
->vtable
, entry_offset
);
278 if (!entry_value
) break;
280 entry_offset
+= vtable_entry_size
;
284 /* Allocate the symbol index */
286 rval
= kxld_array_init(&vtable
->entries
, sizeof(KXLDVTableEntry
), nentries
);
287 require_noerr(rval
, finish
);
289 /* Look up the symbols for each entry */
291 for (i
= 0, entry_offset
= vtable_header_size
;
292 i
< vtable
->entries
.nitems
;
293 ++i
, entry_offset
+= vtable_entry_size
)
295 entry_value
= kxld_relocator_get_pointer_at_addr(relocator
,
296 vtable
->vtable
, entry_offset
);
298 /* If we can't find the symbol, it means that the virtual function was
299 * defined inline. There's not much I can do about this; it just means
300 * I can't patch this function.
302 tmpentry
= kxld_array_get_item(&vtable
->entries
, i
);
303 sym
= kxld_dict_find(defined_cxx_symbols
, &entry_value
);
306 tmpentry
->patched
.name
= sym
->name
;
307 tmpentry
->patched
.addr
= sym
->link_addr
;
309 tmpentry
->patched
.name
= NULL
;
310 tmpentry
->patched
.addr
= 0;
319 /*******************************************************************************
320 * Initializes vtables by performing a reverse lookup on symbol values when
321 * they exist in the vtable entry, and by looking through a matching relocation
322 * entry when the vtable entry is NULL.
324 * Final linked images require this hybrid vtable initialization approach
325 * because they are already internally resolved. This means that the vtables
326 * contain valid entries to local symbols, but still have relocation entries for
328 *******************************************************************************/
330 init_by_entries_and_relocs(KXLDVTable
*vtable
, const KXLDSym
*vtable_sym
,
331 const KXLDRelocator
*relocator
, const KXLDArray
*relocs
,
332 const KXLDDict
*defined_cxx_symbols
)
334 kern_return_t rval
= KERN_FAILURE
;
335 KXLDReloc
*reloc
= NULL
;
336 KXLDVTableEntry
*tmpentry
= NULL
;
338 u_int vtable_entry_size
= 0;
339 u_int vtable_header_size
= 0;
340 kxld_addr_t entry_value
= 0;
341 u_long entry_offset
= 0;
344 char *demangled_name1
= NULL
;
345 size_t demangled_length1
= 0;
352 /* Find the first entry and its offset past the vtable padding */
354 (void) get_vtable_base_sizes(relocator
->is_32_bit
,
355 &vtable_entry_size
, &vtable_header_size
);
357 /* In a final linked image, a vtable slot is valid if it is nonzero
358 * (meaning the userspace linker has already resolved it) or if it has
359 * a relocation entry. We'll know the end of the vtable when we find a
360 * slot that meets neither of these conditions.
362 entry_offset
= vtable_header_size
;
364 entry_value
= kxld_relocator_get_pointer_at_addr(relocator
,
365 vtable
->vtable
, entry_offset
);
367 reloc
= kxld_reloc_get_reloc_by_offset(relocs
,
368 vtable_sym
->base_addr
+ entry_offset
);
373 entry_offset
+= vtable_entry_size
;
376 /* Allocate the symbol index */
378 rval
= kxld_array_init(&vtable
->entries
, sizeof(KXLDVTableEntry
), nentries
);
379 require_noerr(rval
, finish
);
381 /* Find the symbols for each vtable entry */
383 for (i
= 0, entry_offset
= vtable_header_size
;
384 i
< vtable
->entries
.nitems
;
385 ++i
, entry_offset
+= vtable_entry_size
)
387 entry_value
= kxld_relocator_get_pointer_at_addr(relocator
,
388 vtable
->vtable
, entry_offset
);
390 /* If we can't find a symbol, it means it is a locally-defined,
391 * non-external symbol that has been stripped. We don't patch over
392 * locally-defined symbols, so we leave the symbol as NULL and just
393 * skip it. We won't be able to patch subclasses with this symbol,
394 * but there isn't much we can do about that.
398 sym
= kxld_dict_find(defined_cxx_symbols
, &entry_value
);
400 reloc
= kxld_reloc_get_reloc_by_offset(relocs
,
401 vtable_sym
->base_addr
+ entry_offset
);
402 require_action(reloc
, finish
,
404 kxld_log(kKxldLogPatching
, kKxldLogErr
,
405 kKxldLogMalformedVTable
,
406 kxld_demangle(vtable
->name
, &demangled_name1
,
407 &demangled_length1
)));
409 sym
= kxld_reloc_get_symbol(relocator
, reloc
, /* data */ NULL
);
412 tmpentry
= kxld_array_get_item(&vtable
->entries
, i
);
413 tmpentry
->unpatched
.reloc
= reloc
;
414 tmpentry
->unpatched
.sym
= sym
;
422 /*******************************************************************************
423 *******************************************************************************/
425 kxld_vtable_clear(KXLDVTable
*vtable
)
429 vtable
->vtable
= NULL
;
431 vtable
->is_patched
= FALSE
;
432 kxld_array_clear(&vtable
->entries
);
435 /*******************************************************************************
436 *******************************************************************************/
438 kxld_vtable_deinit(KXLDVTable
*vtable
)
442 kxld_array_deinit(&vtable
->entries
);
443 bzero(vtable
, sizeof(*vtable
));
446 /*******************************************************************************
447 *******************************************************************************/
449 kxld_vtable_get_entry_for_offset(const KXLDVTable
*vtable
, u_long offset
,
452 KXLDVTableEntry
*rval
= NULL
;
453 u_int vtable_entry_size
= 0;
454 u_int vtable_header_size
= 0;
455 u_int vtable_entry_idx
= 0;
457 (void) get_vtable_base_sizes(is_32_bit
,
458 &vtable_entry_size
, &vtable_header_size
);
460 if (offset
% vtable_entry_size
) {
464 vtable_entry_idx
= (u_int
) ((offset
- vtable_header_size
) / vtable_entry_size
);
465 rval
= kxld_array_get_item(&vtable
->entries
, vtable_entry_idx
);
470 /*******************************************************************************
471 * Patching vtables allows us to preserve binary compatibility across releases.
472 *******************************************************************************/
474 kxld_vtable_patch(KXLDVTable
*vtable
, const KXLDVTable
*super_vtable
,
477 kern_return_t rval
= KERN_FAILURE
;
478 const KXLDSymtab
*symtab
= NULL
;
479 const KXLDSym
*sym
= NULL
;
480 KXLDVTableEntry
*child_entry
= NULL
;
481 KXLDVTableEntry
*parent_entry
= NULL
;
484 char *demangled_name1
= NULL
;
485 char *demangled_name2
= NULL
;
486 char *demangled_name3
= NULL
;
487 size_t demangled_length1
= 0;
488 size_t demangled_length2
= 0;
489 size_t demangled_length3
= 0;
490 boolean_t failure
= FALSE
;
495 symtab
= kxld_object_get_symtab(object
);
497 require_action(!vtable
->is_patched
, finish
, rval
=KERN_SUCCESS
);
498 require_action(super_vtable
->is_patched
, finish
, rval
=KERN_FAILURE
);
499 require_action(vtable
->entries
.nitems
>= super_vtable
->entries
.nitems
, finish
,
501 kxld_log(kKxldLogPatching
, kKxldLogErr
, kKxldLogMalformedVTable
,
502 kxld_demangle(vtable
->name
, &demangled_name1
, &demangled_length1
)));
504 for (i
= 0; i
< super_vtable
->entries
.nitems
; ++i
) {
505 child_entry
= kxld_array_get_item(&vtable
->entries
, i
);
506 parent_entry
= kxld_array_get_item(&super_vtable
->entries
, i
);
508 /* The child entry can be NULL when a locally-defined, non-external
509 * symbol is stripped. We wouldn't patch this entry anyway, so we
513 if (!child_entry
->unpatched
.sym
) continue;
515 /* It's possible for the patched parent entry not to have a symbol
516 * (e.g. when the definition is inlined). We can't patch this entry no
517 * matter what, so we'll just skip it and die later if it's a problem
518 * (which is not likely).
521 if (!parent_entry
->patched
.name
) continue;
523 /* 1) If the symbol is defined locally, do not patch */
525 if (kxld_sym_is_defined_locally(child_entry
->unpatched
.sym
)) continue;
527 /* 2) If the child is a pure virtual function, do not patch.
528 * In general, we want to proceed with patching when the symbol is
529 * externally defined because pad slots fall into this category.
530 * The pure virtual function symbol is special case, as the pure
531 * virtual property itself overrides the parent's implementation.
534 if (kxld_sym_is_pure_virtual(child_entry
->unpatched
.sym
)) continue;
536 /* 3) If the symbols are the same, do not patch */
538 if (streq(child_entry
->unpatched
.sym
->name
,
539 parent_entry
->patched
.name
))
544 /* 4) If the parent vtable entry is a pad slot, and the child does not
545 * match it, then the child was built against a newer version of the
546 * libraries, so it is binary-incompatible.
549 require_action(!kxld_sym_name_is_padslot(parent_entry
->patched
.name
),
550 finish
, rval
=KERN_FAILURE
;
551 kxld_log(kKxldLogPatching
, kKxldLogErr
,
552 kKxldLogParentOutOfDate
,
553 kxld_demangle(super_vtable
->name
, &demangled_name1
,
555 kxld_demangle(vtable
->name
, &demangled_name2
,
556 &demangled_length2
)));
558 #if KXLD_USER_OR_STRICT_PATCHING
559 /* 5) If we are doing strict patching, we prevent kexts from declaring
560 * virtual functions and not implementing them. We can tell if a
561 * virtual function is declared but not implemented because we resolve
562 * symbols before patching; an unimplemented function will still be
563 * undefined at this point. We then look at whether the symbol has
564 * the same class prefix as the vtable. If it does, the symbol was
565 * declared as part of the class and not inherited, which means we
566 * should not patch it.
569 if (kxld_object_target_supports_strict_patching(object
) &&
570 !kxld_sym_is_defined(child_entry
->unpatched
.sym
))
572 char class_name
[KXLD_MAX_NAME_LEN
];
573 char function_prefix
[KXLD_MAX_NAME_LEN
];
574 u_long function_prefix_len
= 0;
576 rval
= kxld_sym_get_class_name_from_vtable_name(vtable
->name
,
577 class_name
, sizeof(class_name
));
578 require_noerr(rval
, finish
);
580 function_prefix_len
=
581 kxld_sym_get_function_prefix_from_class_name(class_name
,
582 function_prefix
, sizeof(function_prefix
));
583 require(function_prefix_len
, finish
);
585 if (!strncmp(child_entry
->unpatched
.sym
->name
,
586 function_prefix
, function_prefix_len
))
589 kxld_log(kKxldLogPatching
, kKxldLogErr
,
590 "The %s is unpatchable because its class declares the "
591 "method '%s' without providing an implementation.",
592 kxld_demangle(vtable
->name
,
593 &demangled_name1
, &demangled_length1
),
594 kxld_demangle(child_entry
->unpatched
.sym
->name
,
595 &demangled_name2
, &demangled_length2
));
599 #endif /* KXLD_USER_OR_STRICT_PATCHING */
601 /* 6) The child symbol is unresolved and different from its parent, so
602 * we need to patch it up. We do this by modifying the relocation
603 * entry of the vtable entry to point to the symbol of the parent
604 * vtable entry. If that symbol does not exist (i.e. we got the data
605 * from a link state object's vtable representation), then we create a
606 * new symbol in the symbol table and point the relocation entry to
610 sym
= kxld_symtab_get_locally_defined_symbol_by_name(symtab
,
611 parent_entry
->patched
.name
);
613 rval
= kxld_object_add_symbol(object
, parent_entry
->patched
.name
,
614 parent_entry
->patched
.addr
, &sym
);
615 require_noerr(rval
, finish
);
617 require_action(sym
, finish
, rval
=KERN_FAILURE
);
619 rval
= kxld_symtab_get_sym_index(symtab
, sym
, &symindex
);
620 require_noerr(rval
, finish
);
622 rval
= kxld_reloc_update_symindex(child_entry
->unpatched
.reloc
, symindex
);
623 require_noerr(rval
, finish
);
624 kxld_log(kKxldLogPatching
, kKxldLogDetail
,
625 "In vtable '%s', patching '%s' with '%s'.",
626 kxld_demangle(vtable
->name
, &demangled_name1
, &demangled_length1
),
627 kxld_demangle(child_entry
->unpatched
.sym
->name
,
628 &demangled_name2
, &demangled_length2
),
629 kxld_demangle(sym
->name
, &demangled_name3
, &demangled_length3
));
631 rval
= kxld_object_patch_symbol(object
, child_entry
->unpatched
.sym
);
632 require_noerr(rval
, finish
);
634 child_entry
->unpatched
.sym
= sym
;
637 * The C++ ABI requires that functions be aligned on a 2-byte boundary:
638 * http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers
639 * If the LSB of any virtual function's link address is 1, then the
640 * compiler has violated that part of the ABI, and we're going to panic
641 * in _ptmf2ptf() (in OSMetaClass.h). Better to panic here with some
644 assert(kxld_sym_is_pure_virtual(sym
) || !(sym
->link_addr
& 1));
647 require_action(!failure
, finish
, rval
=KERN_FAILURE
);
649 /* Change the vtable representation from the unpatched layout to the
653 for (i
= 0; i
< vtable
->entries
.nitems
; ++i
) {
657 child_entry
= kxld_array_get_item(&vtable
->entries
, i
);
658 if (child_entry
->unpatched
.sym
) {
659 name
= child_entry
->unpatched
.sym
->name
;
660 addr
= child_entry
->unpatched
.sym
->link_addr
;
666 child_entry
->patched
.name
= name
;
667 child_entry
->patched
.addr
= addr
;
670 vtable
->is_patched
= TRUE
;
674 if (demangled_name1
) kxld_free(demangled_name1
, demangled_length1
);
675 if (demangled_name2
) kxld_free(demangled_name2
, demangled_length2
);
676 if (demangled_name3
) kxld_free(demangled_name3
, demangled_length3
);