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
);
112 require_action(extrelocs
, finish
,
114 kxld_log(kKxldLogPatching
, kKxldLogErr
,
115 kKxldLogMalformedVTable
,
116 kxld_demangle(vtable
->name
,
117 &demangled_name
, &demangled_length
)));
119 rval
= init_by_entries_and_relocs(vtable
, vtable_sym
,
120 relocator
, extrelocs
, defined_cxx_symbols
);
121 require_noerr(rval
, finish
);
124 require_action(kxld_sect_get_num_relocs(vtable_sect
) > 0, finish
,
126 kxld_log(kKxldLogPatching
, kKxldLogErr
,
127 kKxldLogMalformedVTable
,
128 kxld_demangle(vtable
->name
,
129 &demangled_name
, &demangled_length
)));
131 rval
= init_by_relocs(vtable
, vtable_sym
, vtable_sect
, relocator
);
132 require_noerr(rval
, finish
);
135 vtable
->is_patched
= FALSE
;
141 if (demangled_name
) kxld_free(demangled_name
, demangled_length
);
146 /*******************************************************************************
147 *******************************************************************************/
149 get_vtable_base_sizes(boolean_t is_32_bit
, u_int
*vtable_entry_size
,
150 u_int
*vtable_header_size
)
152 check(vtable_entry_size
);
153 check(vtable_header_size
);
156 *vtable_entry_size
= VTABLE_ENTRY_SIZE_32
;
157 *vtable_header_size
= VTABLE_HEADER_SIZE_32
;
159 *vtable_entry_size
= VTABLE_ENTRY_SIZE_64
;
160 *vtable_header_size
= VTABLE_HEADER_SIZE_64
;
164 /*******************************************************************************
165 * Initializes a vtable object by matching up relocation entries to the vtable's
166 * entries and finding the corresponding symbols.
167 *******************************************************************************/
169 init_by_relocs(KXLDVTable
*vtable
, const KXLDSym
*vtable_sym
,
170 const KXLDSect
*sect
, const KXLDRelocator
*relocator
)
172 kern_return_t rval
= KERN_FAILURE
;
173 KXLDReloc
*reloc
= NULL
;
174 KXLDVTableEntry
*entry
= NULL
;
176 kxld_addr_t vtable_base_offset
= 0;
177 kxld_addr_t entry_offset
= 0;
180 u_int vtable_entry_size
= 0;
181 u_int vtable_header_size
= 0;
182 u_int base_reloc_index
= 0;
183 u_int reloc_index
= 0;
190 /* Find the first entry past the vtable padding */
192 (void) get_vtable_base_sizes(relocator
->is_32_bit
,
193 &vtable_entry_size
, &vtable_header_size
);
195 vtable_base_offset
= kxld_sym_get_section_offset(vtable_sym
, sect
) +
198 /* Find the relocation entry at the start of the vtable */
200 rval
= kxld_reloc_get_reloc_index_by_offset(§
->relocs
,
201 vtable_base_offset
, &base_reloc_index
);
202 require_noerr(rval
, finish
);
204 /* Count the number of consecutive relocation entries to find the number of
205 * vtable entries. For some reason, the __TEXT,__const relocations are
206 * sorted in descending order, so we have to walk backwards. Also, make
207 * sure we don't run off the end of the section's relocs.
210 reloc_index
= base_reloc_index
;
211 entry_offset
= vtable_base_offset
;
212 reloc
= kxld_array_get_item(§
->relocs
, reloc_index
);
213 while (reloc
->address
== entry_offset
) {
215 if (!reloc_index
) break;
219 reloc
= kxld_array_get_item(§
->relocs
, reloc_index
);
220 entry_offset
+= vtable_entry_size
;
223 /* Allocate the symbol index */
225 rval
= kxld_array_init(&vtable
->entries
, sizeof(KXLDVTableEntry
), nentries
);
226 require_noerr(rval
, finish
);
228 /* Find the symbols for each vtable entry */
230 for (i
= 0; i
< vtable
->entries
.nitems
; ++i
) {
231 reloc
= kxld_array_get_item(§
->relocs
, base_reloc_index
- i
);
232 entry
= kxld_array_get_item(&vtable
->entries
, i
);
234 /* If we can't find a symbol, it means it is a locally-defined,
235 * non-external symbol that has been stripped. We don't patch over
236 * locally-defined symbols, so we leave the symbol as NULL and just
237 * skip it. We won't be able to patch subclasses with this symbol,
238 * but there isn't much we can do about that.
240 sym
= kxld_reloc_get_symbol(relocator
, reloc
, sect
->data
);
242 entry
->unpatched
.sym
= sym
;
243 entry
->unpatched
.reloc
= reloc
;
251 /*******************************************************************************
252 * Initializes a vtable object by reading the symbol values out of the vtable
253 * entries and performing reverse symbol lookups on those values.
254 *******************************************************************************/
256 init_by_entries(KXLDVTable
*vtable
, const KXLDRelocator
*relocator
,
257 const KXLDDict
*defined_cxx_symbols
)
259 kern_return_t rval
= KERN_FAILURE
;
260 KXLDVTableEntry
*tmpentry
= NULL
;
262 kxld_addr_t entry_value
= 0;
264 u_int vtable_entry_size
= 0;
265 u_int vtable_header_size
= 0;
272 (void) get_vtable_base_sizes(relocator
->is_32_bit
,
273 &vtable_entry_size
, &vtable_header_size
);
275 /* Count the number of entries (the vtable is null-terminated) */
277 entry_offset
= vtable_header_size
;
279 entry_value
= kxld_relocator_get_pointer_at_addr(relocator
,
280 vtable
->vtable
, entry_offset
);
281 if (!entry_value
) break;
283 entry_offset
+= vtable_entry_size
;
287 /* Allocate the symbol index */
289 rval
= kxld_array_init(&vtable
->entries
, sizeof(KXLDVTableEntry
), nentries
);
290 require_noerr(rval
, finish
);
292 /* Look up the symbols for each entry */
294 for (i
= 0, entry_offset
= vtable_header_size
;
295 i
< vtable
->entries
.nitems
;
296 ++i
, entry_offset
+= vtable_entry_size
)
298 entry_value
= kxld_relocator_get_pointer_at_addr(relocator
,
299 vtable
->vtable
, entry_offset
);
301 /* If we can't find the symbol, it means that the virtual function was
302 * defined inline. There's not much I can do about this; it just means
303 * I can't patch this function.
305 tmpentry
= kxld_array_get_item(&vtable
->entries
, i
);
306 sym
= kxld_dict_find(defined_cxx_symbols
, &entry_value
);
309 tmpentry
->patched
.name
= sym
->name
;
310 tmpentry
->patched
.addr
= sym
->link_addr
;
312 tmpentry
->patched
.name
= NULL
;
313 tmpentry
->patched
.addr
= 0;
322 /*******************************************************************************
323 * Initializes vtables by performing a reverse lookup on symbol values when
324 * they exist in the vtable entry, and by looking through a matching relocation
325 * entry when the vtable entry is NULL.
327 * Final linked images require this hybrid vtable initialization approach
328 * because they are already internally resolved. This means that the vtables
329 * contain valid entries to local symbols, but still have relocation entries for
331 *******************************************************************************/
333 init_by_entries_and_relocs(KXLDVTable
*vtable
, const KXLDSym
*vtable_sym
,
334 const KXLDRelocator
*relocator
, const KXLDArray
*relocs
,
335 const KXLDDict
*defined_cxx_symbols
)
337 kern_return_t rval
= KERN_FAILURE
;
338 KXLDReloc
*reloc
= NULL
;
339 KXLDVTableEntry
*tmpentry
= NULL
;
341 u_int vtable_entry_size
= 0;
342 u_int vtable_header_size
= 0;
343 kxld_addr_t entry_value
= 0;
344 u_long entry_offset
= 0;
347 char *demangled_name1
= NULL
;
348 size_t demangled_length1
= 0;
355 /* Find the first entry and its offset past the vtable padding */
357 (void) get_vtable_base_sizes(relocator
->is_32_bit
,
358 &vtable_entry_size
, &vtable_header_size
);
360 /* In a final linked image, a vtable slot is valid if it is nonzero
361 * (meaning the userspace linker has already resolved it) or if it has
362 * a relocation entry. We'll know the end of the vtable when we find a
363 * slot that meets neither of these conditions.
365 entry_offset
= vtable_header_size
;
367 entry_value
= kxld_relocator_get_pointer_at_addr(relocator
,
368 vtable
->vtable
, entry_offset
);
370 reloc
= kxld_reloc_get_reloc_by_offset(relocs
,
371 vtable_sym
->base_addr
+ entry_offset
);
376 entry_offset
+= vtable_entry_size
;
379 /* Allocate the symbol index */
381 rval
= kxld_array_init(&vtable
->entries
, sizeof(KXLDVTableEntry
), nentries
);
382 require_noerr(rval
, finish
);
384 /* Find the symbols for each vtable entry */
386 for (i
= 0, entry_offset
= vtable_header_size
;
387 i
< vtable
->entries
.nitems
;
388 ++i
, entry_offset
+= vtable_entry_size
)
390 entry_value
= kxld_relocator_get_pointer_at_addr(relocator
,
391 vtable
->vtable
, entry_offset
);
393 /* If we can't find a symbol, it means it is a locally-defined,
394 * non-external symbol that has been stripped. We don't patch over
395 * locally-defined symbols, so we leave the symbol as NULL and just
396 * skip it. We won't be able to patch subclasses with this symbol,
397 * but there isn't much we can do about that.
401 sym
= kxld_dict_find(defined_cxx_symbols
, &entry_value
);
403 reloc
= kxld_reloc_get_reloc_by_offset(relocs
,
404 vtable_sym
->base_addr
+ entry_offset
);
406 require_action(reloc
, finish
,
408 kxld_log(kKxldLogPatching
, kKxldLogErr
,
409 kKxldLogMalformedVTable
,
410 kxld_demangle(vtable
->name
, &demangled_name1
,
411 &demangled_length1
)));
413 sym
= kxld_reloc_get_symbol(relocator
, reloc
, /* data */ NULL
);
416 tmpentry
= kxld_array_get_item(&vtable
->entries
, i
);
417 tmpentry
->unpatched
.reloc
= reloc
;
418 tmpentry
->unpatched
.sym
= sym
;
426 /*******************************************************************************
427 *******************************************************************************/
429 kxld_vtable_clear(KXLDVTable
*vtable
)
433 vtable
->vtable
= NULL
;
435 vtable
->is_patched
= FALSE
;
436 kxld_array_clear(&vtable
->entries
);
439 /*******************************************************************************
440 *******************************************************************************/
442 kxld_vtable_deinit(KXLDVTable
*vtable
)
446 kxld_array_deinit(&vtable
->entries
);
447 bzero(vtable
, sizeof(*vtable
));
450 /*******************************************************************************
451 *******************************************************************************/
453 kxld_vtable_get_entry_for_offset(const KXLDVTable
*vtable
, u_long offset
,
456 KXLDVTableEntry
*rval
= NULL
;
457 u_int vtable_entry_size
= 0;
458 u_int vtable_header_size
= 0;
459 u_int vtable_entry_idx
= 0;
461 (void) get_vtable_base_sizes(is_32_bit
,
462 &vtable_entry_size
, &vtable_header_size
);
464 if (offset
% vtable_entry_size
) {
468 vtable_entry_idx
= (u_int
) ((offset
- vtable_header_size
) / vtable_entry_size
);
469 rval
= kxld_array_get_item(&vtable
->entries
, vtable_entry_idx
);
474 /*******************************************************************************
475 * Patching vtables allows us to preserve binary compatibility across releases.
476 *******************************************************************************/
478 kxld_vtable_patch(KXLDVTable
*vtable
, const KXLDVTable
*super_vtable
,
481 kern_return_t rval
= KERN_FAILURE
;
482 const KXLDSymtab
*symtab
= NULL
;
483 const KXLDSym
*sym
= NULL
;
484 KXLDVTableEntry
*child_entry
= NULL
;
485 KXLDVTableEntry
*parent_entry
= NULL
;
488 char *demangled_name1
= NULL
;
489 char *demangled_name2
= NULL
;
490 char *demangled_name3
= NULL
;
491 size_t demangled_length1
= 0;
492 size_t demangled_length2
= 0;
493 size_t demangled_length3
= 0;
494 boolean_t failure
= FALSE
;
499 symtab
= kxld_object_get_symtab(object
);
501 require_action(!vtable
->is_patched
, finish
, rval
=KERN_SUCCESS
);
502 require_action(super_vtable
->is_patched
, finish
, rval
=KERN_FAILURE
);
503 require_action(vtable
->entries
.nitems
>= super_vtable
->entries
.nitems
, finish
,
505 kxld_log(kKxldLogPatching
, kKxldLogErr
, kKxldLogMalformedVTable
,
506 kxld_demangle(vtable
->name
, &demangled_name1
, &demangled_length1
)));
508 for (i
= 0; i
< super_vtable
->entries
.nitems
; ++i
) {
509 child_entry
= kxld_array_get_item(&vtable
->entries
, i
);
510 parent_entry
= kxld_array_get_item(&super_vtable
->entries
, i
);
512 /* The child entry can be NULL when a locally-defined, non-external
513 * symbol is stripped. We wouldn't patch this entry anyway, so we
517 if (!child_entry
->unpatched
.sym
) continue;
519 /* It's possible for the patched parent entry not to have a symbol
520 * (e.g. when the definition is inlined). We can't patch this entry no
521 * matter what, so we'll just skip it and die later if it's a problem
522 * (which is not likely).
525 if (!parent_entry
->patched
.name
) continue;
527 /* 1) If the symbol is defined locally, do not patch */
529 if (kxld_sym_is_defined_locally(child_entry
->unpatched
.sym
)) continue;
531 /* 2) If the child is a pure virtual function, do not patch.
532 * In general, we want to proceed with patching when the symbol is
533 * externally defined because pad slots fall into this category.
534 * The pure virtual function symbol is special case, as the pure
535 * virtual property itself overrides the parent's implementation.
538 if (kxld_sym_is_pure_virtual(child_entry
->unpatched
.sym
)) continue;
540 /* 3) If the symbols are the same, do not patch */
542 if (streq(child_entry
->unpatched
.sym
->name
,
543 parent_entry
->patched
.name
))
548 /* 4) If the parent vtable entry is a pad slot, and the child does not
549 * match it, then the child was built against a newer version of the
550 * libraries, so it is binary-incompatible.
553 require_action(!kxld_sym_name_is_padslot(parent_entry
->patched
.name
),
554 finish
, rval
=KERN_FAILURE
;
555 kxld_log(kKxldLogPatching
, kKxldLogErr
,
556 kKxldLogParentOutOfDate
,
557 kxld_demangle(super_vtable
->name
, &demangled_name1
,
559 kxld_demangle(vtable
->name
, &demangled_name2
,
560 &demangled_length2
)));
562 #if KXLD_USER_OR_STRICT_PATCHING
563 /* 5) If we are doing strict patching, we prevent kexts from declaring
564 * virtual functions and not implementing them. We can tell if a
565 * virtual function is declared but not implemented because we resolve
566 * symbols before patching; an unimplemented function will still be
567 * undefined at this point. We then look at whether the symbol has
568 * the same class prefix as the vtable. If it does, the symbol was
569 * declared as part of the class and not inherited, which means we
570 * should not patch it.
573 if (kxld_object_target_supports_strict_patching(object
) &&
574 !kxld_sym_is_defined(child_entry
->unpatched
.sym
))
576 char class_name
[KXLD_MAX_NAME_LEN
];
577 char function_prefix
[KXLD_MAX_NAME_LEN
];
578 u_long function_prefix_len
= 0;
580 rval
= kxld_sym_get_class_name_from_vtable_name(vtable
->name
,
581 class_name
, sizeof(class_name
));
582 require_noerr(rval
, finish
);
584 function_prefix_len
=
585 kxld_sym_get_function_prefix_from_class_name(class_name
,
586 function_prefix
, sizeof(function_prefix
));
587 require(function_prefix_len
, finish
);
589 if (!strncmp(child_entry
->unpatched
.sym
->name
,
590 function_prefix
, function_prefix_len
))
593 kxld_log(kKxldLogPatching
, kKxldLogErr
,
594 "The %s is unpatchable because its class declares the "
595 "method '%s' without providing an implementation.",
596 kxld_demangle(vtable
->name
,
597 &demangled_name1
, &demangled_length1
),
598 kxld_demangle(child_entry
->unpatched
.sym
->name
,
599 &demangled_name2
, &demangled_length2
));
603 #endif /* KXLD_USER_OR_STRICT_PATCHING */
605 /* 6) The child symbol is unresolved and different from its parent, so
606 * we need to patch it up. We do this by modifying the relocation
607 * entry of the vtable entry to point to the symbol of the parent
608 * vtable entry. If that symbol does not exist (i.e. we got the data
609 * from a link state object's vtable representation), then we create a
610 * new symbol in the symbol table and point the relocation entry to
614 sym
= kxld_symtab_get_locally_defined_symbol_by_name(symtab
,
615 parent_entry
->patched
.name
);
617 rval
= kxld_object_add_symbol(object
, parent_entry
->patched
.name
,
618 parent_entry
->patched
.addr
, &sym
);
619 require_noerr(rval
, finish
);
621 require_action(sym
, finish
, rval
=KERN_FAILURE
);
623 rval
= kxld_symtab_get_sym_index(symtab
, sym
, &symindex
);
624 require_noerr(rval
, finish
);
626 rval
= kxld_reloc_update_symindex(child_entry
->unpatched
.reloc
, symindex
);
627 require_noerr(rval
, finish
);
629 kxld_log(kKxldLogPatching
, kKxldLogDetail
,
630 "In vtable '%s', patching '%s' with '%s'.",
631 kxld_demangle(vtable
->name
, &demangled_name1
, &demangled_length1
),
632 kxld_demangle(child_entry
->unpatched
.sym
->name
,
633 &demangled_name2
, &demangled_length2
),
634 kxld_demangle(sym
->name
, &demangled_name3
, &demangled_length3
));
636 rval
= kxld_object_patch_symbol(object
, child_entry
->unpatched
.sym
);
637 require_noerr(rval
, finish
);
639 child_entry
->unpatched
.sym
= sym
;
642 * The C++ ABI requires that functions be aligned on a 2-byte boundary:
643 * http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers
644 * If the LSB of any virtual function's link address is 1, then the
645 * compiler has violated that part of the ABI, and we're going to panic
646 * in _ptmf2ptf() (in OSMetaClass.h). Better to panic here with some
649 assert(kxld_sym_is_pure_virtual(sym
) || !(sym
->link_addr
& 1));
652 require_action(!failure
, finish
, rval
=KERN_FAILURE
);
654 /* Change the vtable representation from the unpatched layout to the
658 for (i
= 0; i
< vtable
->entries
.nitems
; ++i
) {
662 child_entry
= kxld_array_get_item(&vtable
->entries
, i
);
663 if (child_entry
->unpatched
.sym
) {
664 name
= child_entry
->unpatched
.sym
->name
;
665 addr
= child_entry
->unpatched
.sym
->link_addr
;
671 child_entry
->patched
.name
= name
;
672 child_entry
->patched
.addr
= addr
;
675 vtable
->is_patched
= TRUE
;
679 if (demangled_name1
) kxld_free(demangled_name1
, demangled_length1
);
680 if (demangled_name2
) kxld_free(demangled_name2
, demangled_length2
);
681 if (demangled_name3
) kxld_free(demangled_name3
, demangled_length3
);