]> git.saurik.com Git - apple/xnu.git/blame - libkern/kxld/kxld_kext.c
xnu-3789.70.16.tar.gz
[apple/xnu.git] / libkern / kxld / kxld_kext.c
CommitLineData
b0d623f7 1/*
39236c6e 2 * Copyright (c) 2008, 2013 Apple Inc. All rights reserved.
b0d623f7
A
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28#include <string.h>
b0d623f7
A
29#include <mach/vm_param.h>
30#include <mach/vm_types.h>
31#include <mach/kmod.h>
32#include <mach-o/loader.h>
33#include <mach-o/nlist.h>
34#include <mach-o/reloc.h>
35#include <sys/types.h>
36
37#if KERNEL
38 #include <libkern/kernel_mach_header.h>
39 #include <libkern/OSKextLib.h>
40 #include <libkern/OSKextLibPrivate.h>
41 #include <mach/vm_param.h>
42 #include <mach-o/fat.h>
43#else /* !KERNEL */
44 #include <architecture/byte_order.h>
45 #include <mach/mach_init.h>
46 #include <mach-o/arch.h>
47 #include <mach-o/swap.h>
39037602 48
b0d623f7
A
49#endif /* KERNEL */
50
51#define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
52#include <AssertMacros.h>
53
b7266188 54#include "kxld_demangle.h"
b0d623f7
A
55#include "kxld_dict.h"
56#include "kxld_kext.h"
6d2010ae 57#include "kxld_object.h"
b0d623f7
A
58#include "kxld_reloc.h"
59#include "kxld_sect.h"
60#include "kxld_seg.h"
b0d623f7
A
61#include "kxld_symtab.h"
62#include "kxld_util.h"
b0d623f7
A
63#include "kxld_vtable.h"
64
39037602
A
65extern boolean_t isSplitKext;
66
b0d623f7
A
67struct symtab_command;
68
b0d623f7 69struct kxld_kext {
6d2010ae
A
70 KXLDObject *kext;
71 KXLDObject *interface;
b0d623f7 72 KXLDArray vtables;
b0d623f7 73 KXLDDict vtable_index;
6d2010ae
A
74 boolean_t vtables_created;
75 boolean_t vtable_index_created;
b0d623f7
A
76};
77
78/*******************************************************************************
79* Prototypes
80*******************************************************************************/
81
6d2010ae
A
82static kern_return_t export_symbols_through_interface(
83 const KXLDObject *kext, const KXLDObject *interface,
84 KXLDDict *defined_symbols_by_name,
85 KXLDDict *defined_cxx_symbol_by_value,
86 KXLDDict *obsolete_symbols_by_name);
87static kern_return_t export_symbols(const KXLDObject *kext,
88 KXLDDict *defined_symbols_by_name,
89 KXLDDict *defined_cxx_symbols_by_value);
90
91static kern_return_t create_vtables(KXLDKext *kext,
92 const KXLDDict *defined_symbols, const KXLDDict *defined_cxx_symbols);
93static kern_return_t get_vtable_syms_from_smcp(KXLDKext *kext,
94 const KXLDDict *defined_symbols, KXLDSym *super_metaclass_ptr_sym,
95 KXLDSym **vtable_sym_out, KXLDSym **meta_vtable_sym_out);
96
97static kern_return_t resolve_symbols(KXLDKext *kext,
98 const KXLDDict *defined_symbols, const KXLDDict *obsolete_symbols);
99
b0d623f7 100static kern_return_t patch_vtables(KXLDKext *kext, KXLDDict *patched_vtables,
6d2010ae 101 const KXLDDict *defined_symbols);
6d2010ae 102static kern_return_t create_vtable_index(KXLDKext *kext);
39037602
A
103static const KXLDSym *get_metaclass_symbol_from_super_meta_class_pointer_symbol(
104 KXLDKext *kext, KXLDSym *super_metaclass_pointer_sym);
6d2010ae 105
b0d623f7 106static kern_return_t validate_symbols(KXLDKext *kext);
b0d623f7
A
107
108/*******************************************************************************
109*******************************************************************************/
110size_t
111kxld_kext_sizeof(void)
112{
113 return sizeof(KXLDKext);
114}
115
116/*******************************************************************************
117*******************************************************************************/
118kern_return_t
6d2010ae
A
119kxld_kext_init(KXLDKext *kext, KXLDObject *kext_object,
120 KXLDObject *interface_object)
b0d623f7
A
121{
122 kern_return_t rval = KERN_FAILURE;
b0d623f7
A
123
124 check(kext);
6d2010ae 125 check(kext_object);
b0d623f7 126
6d2010ae 127 kext->kext = kext_object;
b0d623f7 128
6d2010ae
A
129 if (interface_object) {
130 kext->interface = interface_object;
b0d623f7 131
6d2010ae
A
132 rval = kxld_object_index_symbols_by_name(kext->kext);
133 require_noerr(rval, finish);
134 }
135
136 rval = KERN_SUCCESS;
137finish:
138 return rval;
139}
b0d623f7 140
6d2010ae
A
141/*******************************************************************************
142*******************************************************************************/
143void
144kxld_kext_clear(KXLDKext *kext)
145{
146 KXLDVTable *vtable = NULL;
147 u_int i;
b0d623f7 148
6d2010ae 149 check(kext);
b0d623f7 150
6d2010ae
A
151 for (i = 0; i < kext->vtables.nitems; ++i) {
152 vtable = kxld_array_get_item(&kext->vtables, i);
153 kxld_vtable_clear(vtable);
154 }
155 kxld_array_reset(&kext->vtables);
156 kxld_dict_clear(&kext->vtable_index);
b0d623f7 157
6d2010ae
A
158 kext->kext = NULL;
159 kext->interface = NULL;
160 kext->vtables_created = FALSE;
161 kext->vtable_index_created = FALSE;
162}
b0d623f7 163
b0d623f7 164
6d2010ae
A
165/*******************************************************************************
166*******************************************************************************/
167void
168kxld_kext_deinit(KXLDKext *kext)
169{
170 KXLDVTable *vtable = NULL;
171 u_int i;
b0d623f7 172
6d2010ae 173 check(kext);
b0d623f7 174
6d2010ae
A
175 for (i = 0; i < kext->vtables.maxitems; ++i) {
176 vtable = kxld_array_get_slot(&kext->vtables, i);
177 kxld_vtable_deinit(vtable);
b0d623f7 178 }
6d2010ae
A
179 kxld_array_deinit(&kext->vtables);
180 kxld_dict_deinit(&kext->vtable_index);
b0d623f7 181
6d2010ae
A
182 bzero(kext, sizeof(*kext));
183}
b0d623f7 184
6d2010ae
A
185/*******************************************************************************
186*******************************************************************************/
187kern_return_t
188kxld_kext_export_symbols(const KXLDKext *kext,
316670eb
A
189 KXLDDict *defined_symbols_by_name,
190 KXLDDict *obsolete_symbols_by_name,
191 KXLDDict *defined_cxx_symbols_by_value)
6d2010ae
A
192{
193 kern_return_t rval = KERN_FAILURE;
194
195 check(kext);
b0d623f7 196
6d2010ae
A
197 if (kext->interface) {
198 rval = export_symbols_through_interface(kext->kext, kext->interface,
199 defined_symbols_by_name, obsolete_symbols_by_name,
200 defined_cxx_symbols_by_value);
201 require_noerr(rval, finish);
202 } else {
203 rval = export_symbols(kext->kext, defined_symbols_by_name,
204 defined_cxx_symbols_by_value);
b0d623f7 205 require_noerr(rval, finish);
b0d623f7
A
206 }
207
208 rval = KERN_SUCCESS;
209finish:
210 return rval;
211}
212
213/*******************************************************************************
214*******************************************************************************/
215kern_return_t
6d2010ae
A
216export_symbols_through_interface(const KXLDObject *kext,
217 const KXLDObject *interface, KXLDDict *defined_symbols_by_name,
218 KXLDDict *obsolete_symbols_by_name, KXLDDict *defined_cxx_symbols_by_value)
b0d623f7 219{
b0d623f7 220 kern_return_t rval = KERN_FAILURE;
6d2010ae
A
221 KXLDSymtabIterator iter;
222 const KXLDSymtab *kext_symtab = NULL;
223 const KXLDSymtab *interface_symtab = NULL;
224 KXLDSym *kext_sym = NULL;
225 const KXLDSym *interface_sym = NULL;
b0d623f7
A
226
227 check(kext);
6d2010ae
A
228 check(interface);
229
230 kext_symtab = kxld_object_get_symtab(kext);
231 interface_symtab = kxld_object_get_symtab(interface);
232
233 if (defined_symbols_by_name) {
234 /* Add exported symbols */
235 (void) kxld_symtab_iterator_init(&iter, interface_symtab,
236 kxld_sym_is_undefined, FALSE);
237 while ((interface_sym = kxld_symtab_iterator_get_next(&iter))) {
238 kext_sym = kxld_symtab_get_locally_defined_symbol_by_name(kext_symtab,
239 interface_sym->name);
240 if (!kext_sym) {
241 kxld_log(kKxldLogLinking, kKxldLogWarn,
242 "In interface %s of %s, couldn't find symbol %s\n",
243 kxld_object_get_name(interface), kxld_object_get_name(kext),
244 interface_sym->name);
245 continue;
246 }
b0d623f7 247
6d2010ae
A
248 rval = kxld_dict_insert(defined_symbols_by_name,
249 kext_sym->name, kext_sym);
250 require_noerr(rval, finish);
251 }
b0d623f7 252
6d2010ae
A
253 /* Add indirect symbols */
254 (void) kxld_symtab_iterator_init(&iter, interface_symtab,
255 kxld_sym_is_indirect, FALSE);
256 while ((interface_sym = kxld_symtab_iterator_get_next(&iter))) {
257 kext_sym = kxld_symtab_get_locally_defined_symbol_by_name(kext_symtab,
258 interface_sym->alias);
259 if (!kext_sym) {
260 kxld_log(kKxldLogLinking, kKxldLogWarn,
261 "In interface %s of %s, couldn't find indirect symbol %s (%s)\n",
262 kxld_object_get_name(interface), kxld_object_get_name(kext),
263 interface_sym->alias, interface_sym->name);
264 continue;
265 }
b0d623f7 266
6d2010ae
A
267 rval = kxld_dict_insert(defined_symbols_by_name,
268 interface_sym->name, kext_sym);
269 require_noerr(rval, finish);
b0d623f7
A
270 }
271 }
272
6d2010ae
A
273 /* Add obsolete symbols */
274 if (obsolete_symbols_by_name) {
275 (void) kxld_symtab_iterator_init(&iter, interface_symtab,
276 kxld_sym_is_obsolete, FALSE);
277 while ((kext_sym = kxld_symtab_iterator_get_next(&iter))) {
278 rval = kxld_dict_insert(obsolete_symbols_by_name,
279 kext_sym->name, kext_sym);
280 require_noerr(rval, finish);
281 }
282 }
b0d623f7 283
6d2010ae
A
284 /* Add C++ symbols */
285 if (defined_cxx_symbols_by_value) {
286 (void) kxld_symtab_iterator_init(&iter, kext_symtab,
287 kxld_sym_is_cxx, FALSE);
288 while ((kext_sym = kxld_symtab_iterator_get_next(&iter))) {
289 rval = kxld_dict_insert(defined_cxx_symbols_by_value,
290 &kext_sym->link_addr, kext_sym);
291 require_noerr(rval, finish);
292 }
b0d623f7
A
293 }
294
295 rval = KERN_SUCCESS;
b0d623f7
A
296finish:
297 return rval;
b0d623f7
A
298}
299
300/*******************************************************************************
301*******************************************************************************/
6d2010ae
A
302kern_return_t
303export_symbols(const KXLDObject *kext, KXLDDict *defined_symbols_by_name,
304 KXLDDict *defined_cxx_symbols_by_value)
b0d623f7
A
305{
306 kern_return_t rval = KERN_FAILURE;
6d2010ae
A
307 KXLDSymtabIterator iter;
308 KXLDSym *sym = NULL;
b0d623f7 309
6d2010ae
A
310 (void) kxld_symtab_iterator_init(&iter, kxld_object_get_symtab(kext),
311 kxld_sym_is_exported, FALSE);
312 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
313 if (defined_symbols_by_name) {
314 rval = kxld_dict_insert(defined_symbols_by_name, sym->name, sym);
315 require_noerr(rval, finish);
b0d623f7
A
316 }
317
6d2010ae
A
318 if (kxld_sym_is_cxx(sym) && defined_cxx_symbols_by_value) {
319 rval = kxld_dict_insert(defined_cxx_symbols_by_value,
320 &sym->link_addr, sym);
321 require_noerr(rval, finish);
322 }
b0d623f7 323 }
b0d623f7
A
324
325 rval = KERN_SUCCESS;
326finish:
327 return rval;
328}
329
330/*******************************************************************************
331*******************************************************************************/
6d2010ae
A
332kern_return_t
333kxld_kext_export_vtables(KXLDKext *kext, const KXLDDict *defined_cxx_symbols,
334 const KXLDDict *defined_symbols, KXLDDict *vtables)
b0d623f7 335{
6d2010ae
A
336 kern_return_t rval = KERN_FAILURE;
337 KXLDVTable *vtable = NULL;
338 u_int i = 0;
339
b0d623f7 340 check(kext);
6d2010ae
A
341 check(defined_symbols);
342 check(defined_cxx_symbols);
343 check(vtables);
b0d623f7 344
6d2010ae
A
345 rval = create_vtables(kext, defined_cxx_symbols, defined_symbols);
346 require_noerr(rval, finish);
b0d623f7 347
6d2010ae
A
348 for (i = 0; i < kext->vtables.nitems; ++i) {
349 vtable = kxld_array_get_item(&kext->vtables, i);
b0d623f7 350
6d2010ae
A
351 rval = kxld_dict_insert(vtables, vtable->name, vtable);
352 require_noerr(rval, finish);
353 }
354
355 rval = KERN_SUCCESS;
356finish:
357 return rval;
b0d623f7
A
358}
359
39037602
A
360/*******************************************************************************
361 *******************************************************************************/
362void
363kxld_kext_get_vmsize_for_seg_by_name(const KXLDKext *kext,
364 const char *segname,
365 u_long *vmsize)
366{
367 (void) kxld_object_get_vmsize_for_seg_by_name(kext->kext, segname, vmsize);
368}
369
b0d623f7
A
370/*******************************************************************************
371*******************************************************************************/
6d2010ae
A
372void
373kxld_kext_get_vmsize(const KXLDKext *kext,
374 u_long *header_size, u_long *vmsize)
b0d623f7 375{
6d2010ae 376 (void) kxld_object_get_vmsize(kext->kext, header_size, vmsize);
b0d623f7 377}
316670eb
A
378
379/*******************************************************************************
380 *******************************************************************************/
39037602 381void
316670eb
A
382kxld_kext_set_linked_object_size(KXLDKext *kext, u_long vmsize)
383{
384 (void) kxld_object_set_linked_object_size(kext->kext, vmsize);
385}
386
b0d623f7
A
387/*******************************************************************************
388*******************************************************************************/
6d2010ae
A
389kern_return_t
390kxld_kext_export_linked_object(const KXLDKext *kext,
39037602
A
391 void *linked_object,
392 kxld_addr_t *kmod_info)
b0d623f7 393{
6d2010ae
A
394 kern_return_t rval = KERN_FAILURE;
395 const KXLDSym *kmodsym = NULL;
b0d623f7 396
6d2010ae
A
397 kmodsym = kxld_symtab_get_locally_defined_symbol_by_name(
398 kxld_object_get_symtab(kext->kext), KXLD_KMOD_INFO_SYMBOL);
39037602 399
6d2010ae
A
400 require_action(kmodsym, finish, rval=KERN_FAILURE;
401 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogNoKmodInfo));
39037602 402
6d2010ae
A
403 *kmod_info = kmodsym->link_addr;
404
405 rval = kxld_object_export_linked_object(kext->kext, linked_object);
406finish:
407 return rval;
b0d623f7
A
408}
409
410/*******************************************************************************
411*******************************************************************************/
6d2010ae 412kern_return_t
39037602
A
413kxld_kext_relocate(KXLDKext *kext,
414 kxld_addr_t link_address,
415 KXLDDict *patched_vtables,
416 const KXLDDict *defined_symbols,
417 const KXLDDict *obsolete_symbols,
418 const KXLDDict *defined_cxx_symbols)
b0d623f7
A
419{
420 kern_return_t rval = KERN_FAILURE;
b0d623f7
A
421
422 check(kext);
6d2010ae
A
423 check(patched_vtables);
424 check(defined_symbols);
425 check(obsolete_symbols);
426
427 /* Kexts that are being relocated need symbols indexed by value for vtable
428 * creation and patching. Note that we don't need to index by value for
429 * dependencies that have already been linked because their symbols are
430 * already in the global cxx value table. It's important to index the
431 * symbols by value before we relocate the symbols because the vtable
432 * entries will still have unrelocated values.
b0d623f7 433 */
6d2010ae
A
434 rval = kxld_object_index_cxx_symbols_by_value(kext->kext);
435 require_noerr(rval, finish);
b0d623f7 436
6d2010ae
A
437 rval = kxld_object_index_symbols_by_name(kext->kext);
438 require_noerr(rval, finish);
b0d623f7 439
6d2010ae
A
440 rval = kxld_object_relocate(kext->kext, link_address);
441 require_noerr(rval, finish);
b0d623f7 442
6d2010ae
A
443 rval = resolve_symbols(kext, defined_symbols, obsolete_symbols);
444 require_noerr(rval, finish);
b0d623f7 445
6d2010ae
A
446 rval = create_vtables(kext, defined_cxx_symbols, /* defined_symbols */ NULL);
447 require_noerr(rval, finish);
b0d623f7 448
39037602
A
449 if (isSplitKext == FALSE) {
450 rval = patch_vtables(kext, patched_vtables, defined_symbols);
451 require_noerr(rval, finish);
452 }
453
6d2010ae
A
454 rval = validate_symbols(kext);
455 require_noerr(rval, finish);
b0d623f7 456
6d2010ae
A
457 rval = kxld_object_process_relocations(kext->kext, patched_vtables);
458 require_noerr(rval, finish);
b0d623f7
A
459
460 rval = KERN_SUCCESS;
461finish:
39037602 462 return rval;
b0d623f7 463}
b0d623f7
A
464
465/*******************************************************************************
6d2010ae
A
466* The defined symbols argument is optional. When supplied, create_vtables()
467* will look for vtable symbols in the defined_symbols dictionary. Otherwise,
468* it will look in the kext's symbol table for vtable symbols.
469*
470* We do this because there are two types of KXLDKext objects that call
471* create_vtables(), those that have been linked, and those that haven't. The
472* linked kexts export their symbols into the global symbol table that is used
473* for symbol resolution, so we can look there for vtable symbols without
474* having to index their local symbol table separately.
475*
476* Unlinked kexts haven't yet had their symbols exported into the global table,
477* so we have to index their local symbol table separately.
b0d623f7 478*******************************************************************************/
6d2010ae
A
479static kern_return_t
480create_vtables(KXLDKext *kext, const KXLDDict *defined_cxx_symbols,
481 const KXLDDict *defined_symbols)
b0d623f7
A
482{
483 kern_return_t rval = KERN_FAILURE;
6d2010ae
A
484 const KXLDSymtab *symtab = NULL;
485 KXLDSymtabIterator iter;
486 KXLDSym *sym = NULL;
487 KXLDSym *vtable_sym = NULL;
488 KXLDSym *meta_vtable_sym = NULL;
489 KXLDVTable *vtable = NULL;
490 KXLDVTable *meta_vtable = NULL;
b0d623f7 491 u_int i = 0;
6d2010ae 492 u_int nvtables = 0;
b0d623f7 493
6d2010ae
A
494 if (kext->vtables_created) {
495 rval = KERN_SUCCESS;
496 goto finish;
b0d623f7
A
497 }
498
6d2010ae 499 symtab = kxld_object_get_symtab(kext->kext);
b0d623f7 500
6d2010ae
A
501 if (kxld_object_is_linked(kext->kext)) {
502 /* Create a vtable object for every vtable symbol */
503 kxld_symtab_iterator_init(&iter, symtab, kxld_sym_is_vtable, FALSE);
504 nvtables = kxld_symtab_iterator_get_num_remaining(&iter);
505 } else {
506 /* We walk over the super metaclass pointer symbols because classes
507 * with them are the only ones that need patching. Then we double the
508 * number of vtables we're expecting, because every pointer will have a
509 * class vtable and a MetaClass vtable.
510 */
511 kxld_symtab_iterator_init(&iter, symtab,
512 kxld_sym_is_super_metaclass_pointer, FALSE);
513 nvtables = kxld_symtab_iterator_get_num_remaining(&iter) * 2;
514 }
b0d623f7 515
6d2010ae
A
516 rval = kxld_array_init(&kext->vtables, sizeof(KXLDVTable), nvtables);
517 require_noerr(rval, finish);
b0d623f7 518
6d2010ae
A
519 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
520 if (kxld_object_is_linked(kext->kext)) {
521 vtable_sym = sym;
522 meta_vtable_sym = NULL;
523 meta_vtable = NULL;
524 } else {
525 rval = get_vtable_syms_from_smcp(kext, defined_symbols, sym,
526 &vtable_sym, &meta_vtable_sym);
527 require_noerr(rval, finish);
528 }
b0d623f7 529
6d2010ae
A
530 vtable = kxld_array_get_item(&kext->vtables, i++);
531 rval = kxld_vtable_init(vtable, vtable_sym, kext->kext,
532 defined_cxx_symbols);
533 require_noerr(rval, finish);
b0d623f7 534
6d2010ae
A
535 /* meta_vtable_sym will be null when we don't support strict
536 * patching and can't find the metaclass vtable. If that's the
537 * case, we just reduce the expect number of vtables by 1.
538 */
539 if (!kxld_object_is_linked(kext->kext)) {
540 if (meta_vtable_sym) {
541 meta_vtable = kxld_array_get_item(&kext->vtables, i++);
542 rval = kxld_vtable_init(meta_vtable, meta_vtable_sym,
543 kext->kext, defined_cxx_symbols);
b0d623f7 544 require_noerr(rval, finish);
6d2010ae
A
545 } else {
546 kxld_array_resize(&kext->vtables, --nvtables);
547 meta_vtable = NULL;
b0d623f7 548 }
6d2010ae
A
549 }
550 }
551 require_action(i == kext->vtables.nitems, finish,
552 rval=KERN_FAILURE);
b0d623f7 553
6d2010ae 554 kext->vtables_created = TRUE;
b0d623f7
A
555 rval = KERN_SUCCESS;
556finish:
557 return rval;
558}
559
560/*******************************************************************************
561*******************************************************************************/
562static kern_return_t
6d2010ae
A
563get_vtable_syms_from_smcp(KXLDKext *kext, const KXLDDict *defined_symbols,
564 KXLDSym *super_metaclass_ptr_sym, KXLDSym **vtable_sym_out,
565 KXLDSym **meta_vtable_sym_out)
b0d623f7
A
566{
567 kern_return_t rval = KERN_FAILURE;
6d2010ae 568 const KXLDSymtab *symtab = NULL;
b0d623f7
A
569 KXLDSym *vtable_sym = NULL;
570 KXLDSym *meta_vtable_sym = NULL;
b0d623f7
A
571 char class_name[KXLD_MAX_NAME_LEN];
572 char vtable_name[KXLD_MAX_NAME_LEN];
573 char meta_vtable_name[KXLD_MAX_NAME_LEN];
6d2010ae
A
574 char *demangled_name1 = NULL;
575 char *demangled_name2 = NULL;
576 size_t demangled_length1 = 0;
577 size_t demangled_length2 = 0;
b0d623f7 578
6d2010ae
A
579 check(kext);
580 check(vtable_sym_out);
581 check(meta_vtable_sym_out);
b0d623f7 582
6d2010ae 583 require(!kxld_object_is_kernel(kext->kext), finish);
b0d623f7 584
6d2010ae 585 symtab = kxld_object_get_symtab(kext->kext);
b0d623f7 586
6d2010ae
A
587 /* Get the class name from the smc pointer */
588 rval = kxld_sym_get_class_name_from_super_metaclass_pointer(
589 super_metaclass_ptr_sym, class_name, sizeof(class_name));
590 require_noerr(rval, finish);
b0d623f7 591
6d2010ae
A
592 /* Get the vtable name from the class name */
593 rval = kxld_sym_get_vtable_name_from_class_name(class_name,
594 vtable_name, sizeof(vtable_name));
595 require_noerr(rval, finish);
b0d623f7 596
6d2010ae
A
597 /* Get the vtable symbol */
598 if (defined_symbols) {
599 vtable_sym = kxld_dict_find(defined_symbols, vtable_name);
600 } else {
601 vtable_sym = kxld_symtab_get_locally_defined_symbol_by_name(symtab,
602 vtable_name);
603 }
604 require_action(vtable_sym, finish, rval=KERN_FAILURE;
605 kxld_log(kKxldLogPatching, kKxldLogErr, kKxldLogMissingVtable,
606 vtable_name, class_name));
b0d623f7 607
6d2010ae
A
608 /* Get the meta vtable name from the class name */
609 rval = kxld_sym_get_meta_vtable_name_from_class_name(class_name,
610 meta_vtable_name, sizeof(meta_vtable_name));
611 require_noerr(rval, finish);
b0d623f7 612
6d2010ae
A
613 /* Get the meta vtable symbol */
614 if (defined_symbols) {
615 meta_vtable_sym = kxld_dict_find(defined_symbols, meta_vtable_name);
616 } else {
617 meta_vtable_sym = kxld_symtab_get_locally_defined_symbol_by_name(symtab,
618 meta_vtable_name);
619 }
620 if (!meta_vtable_sym) {
621 if (kxld_object_target_supports_strict_patching(kext->kext)) {
622 kxld_log(kKxldLogPatching, kKxldLogErr,
623 kKxldLogMissingVtable,
624 meta_vtable_name, class_name);
625 rval = KERN_FAILURE;
626 goto finish;
627 } else {
b0d623f7 628 kxld_log(kKxldLogPatching, kKxldLogErr,
6d2010ae
A
629 "Warning: " kKxldLogMissingVtable,
630 kxld_demangle(meta_vtable_name, &demangled_name1,
631 &demangled_length1),
632 kxld_demangle(class_name, &demangled_name2,
633 &demangled_length2));
b0d623f7
A
634 }
635 }
6d2010ae
A
636
637 *vtable_sym_out = vtable_sym;
638 *meta_vtable_sym_out = meta_vtable_sym;
b0d623f7
A
639 rval = KERN_SUCCESS;
640finish:
b7266188
A
641 if (demangled_name1) kxld_free(demangled_name1, demangled_length1);
642 if (demangled_name2) kxld_free(demangled_name2, demangled_length2);
643
b0d623f7
A
644 return rval;
645}
646
647/*******************************************************************************
648*******************************************************************************/
649static kern_return_t
6d2010ae
A
650resolve_symbols(KXLDKext *kext, const KXLDDict *defined_symbols,
651 const KXLDDict *obsolete_symbols)
b0d623f7
A
652{
653 kern_return_t rval = KERN_FAILURE;
6d2010ae 654 const KXLDSymtab *symtab = NULL;
b0d623f7
A
655 KXLDSymtabIterator iter;
656 KXLDSym *sym = NULL;
6d2010ae
A
657 KXLDSym *defined_sym = NULL;
658 const char *name = NULL;
659 boolean_t tests_for_weak = FALSE;
660 boolean_t error = FALSE;
b7266188
A
661 char *demangled_name = NULL;
662 size_t demangled_length = 0;
b0d623f7 663
6d2010ae
A
664 check(kext->kext);
665 check(defined_symbols);
666 check(obsolete_symbols);
b0d623f7 667
6d2010ae 668 symtab = kxld_object_get_symtab(kext->kext);
b0d623f7 669
6d2010ae
A
670 /* Check if the kext tests for weak symbols */
671 sym = kxld_symtab_get_symbol_by_name(symtab, KXLD_WEAK_TEST_SYMBOL);
672 tests_for_weak = (sym != NULL);
b0d623f7 673
6d2010ae
A
674 /* Check for duplicate symbols */
675 kxld_symtab_iterator_init(&iter, symtab, kxld_sym_is_exported, FALSE);
676 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
677 defined_sym = kxld_dict_find(defined_symbols, sym->name);
678 if (defined_sym) {
679 /* Not a problem if the symbols have the same address */
680 if (defined_sym->link_addr == sym->link_addr) {
681 continue;
682 }
b0d623f7 683
6d2010ae
A
684 if (!error) {
685 error = TRUE;
686 kxld_log(kKxldLogLinking, kKxldLogErr,
687 "The following symbols were defined more than once:");
688 }
b0d623f7 689
6d2010ae
A
690 kxld_log(kKxldLogLinking, kKxldLogErr, "\t%s: %p - %p",
691 kxld_demangle(sym->name, &demangled_name, &demangled_length),
692 (void *) (uintptr_t) sym->link_addr,
693 (void *) (uintptr_t) defined_sym->link_addr);
694 }
695 }
696 require_noerr_action(error, finish, rval=KERN_FAILURE);
b0d623f7 697
6d2010ae 698 /* Resolve undefined and indirect symbols */
b0d623f7 699
6d2010ae
A
700 /* Iterate over all unresolved symbols */
701 kxld_symtab_iterator_init(&iter, symtab,
702 kxld_sym_is_unresolved, FALSE);
703 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
b0d623f7 704
6d2010ae
A
705 /* Common symbols are not supported */
706 if (kxld_sym_is_common(sym)) {
b0d623f7 707
6d2010ae
A
708 if (!error) {
709 error = TRUE;
710 if (kxld_object_target_supports_common_symbols(kext->kext)) {
711 kxld_log(kKxldLogLinking, kKxldLogErr,
712 "The following common symbols were not resolved:");
713 } else {
714 kxld_log(kKxldLogLinking, kKxldLogErr,
715 "Common symbols are not supported in kernel extensions. "
716 "Use -fno-common to build your kext. "
717 "The following are common symbols:");
718 }
719 }
720 kxld_log(kKxldLogLinking, kKxldLogErr, "\t%s",
721 kxld_demangle(sym->name, &demangled_name, &demangled_length));
b0d623f7 722
6d2010ae 723 } else {
b0d623f7 724
6d2010ae
A
725 /* Find the address of the defined symbol */
726 if (kxld_sym_is_undefined(sym)) {
727 name = sym->name;
728 } else {
729 name = sym->alias;
730 }
731 defined_sym = kxld_dict_find(defined_symbols, name);
732
733 /* Resolve the symbol. If a definition cannot be found, then:
734 * 1) Psuedokexts log a warning and proceed
735 * 2) Actual kexts delay the error until validation in case vtable
736 * patching replaces the undefined symbol.
737 */
b0d623f7 738
6d2010ae 739 if (defined_sym) {
b0d623f7 740
6d2010ae
A
741 rval = kxld_sym_resolve(sym, defined_sym->link_addr);
742 require_noerr(rval, finish);
b0d623f7 743
6d2010ae
A
744 if (obsolete_symbols && kxld_dict_find(obsolete_symbols, name)) {
745 kxld_log(kKxldLogLinking, kKxldLogWarn,
746 "This kext uses obsolete symbol %s.",
747 kxld_demangle(name, &demangled_name, &demangled_length));
748 }
b0d623f7 749
6d2010ae
A
750 } else if (kxld_sym_is_weak(sym)) {
751 kxld_addr_t addr = 0;
b0d623f7 752
6d2010ae
A
753 /* Make sure that the kext has referenced gOSKextUnresolved.
754 */
755 require_action(tests_for_weak, finish,
756 rval=KERN_FAILURE;
757 kxld_log(kKxldLogLinking, kKxldLogErr,
758 "This kext has weak references but does not test for "
759 "them. Test for weak references with "
39236c6e 760 "OSKextSymbolIsResolved(). (found in <libkern/OSKextLib.h>)"));
b0d623f7 761
6d2010ae
A
762#if KERNEL
763 /* Get the address of the default weak address.
764 */
765 addr = (kxld_addr_t) &kext_weak_symbol_referenced;
766#else
767 /* This is run during symbol generation only, so we only
768 * need a filler value here.
769 */
770 addr = 0xF00DD00D;
771#endif /* KERNEL */
772
773 rval = kxld_sym_resolve(sym, addr);
774 require_noerr(rval, finish);
775 }
b0d623f7
A
776 }
777 }
6d2010ae 778 require_noerr_action(error, finish, rval=KERN_FAILURE);
b0d623f7
A
779
780 rval = KERN_SUCCESS;
781
782finish:
6d2010ae
A
783 if (demangled_name) kxld_free(demangled_name, demangled_length);
784
b0d623f7
A
785 return rval;
786}
b0d623f7
A
787
788/*******************************************************************************
6d2010ae
A
789* We must patch vtables to ensure binary compatibility, and to perform that
790* patching, we have to determine the vtables' inheritance relationships. The
791* MetaClass system gives us a way to do that:
792* 1) Iterate over all of the super MetaClass pointer symbols. Every class
793* that inherits from OSObject will have a pointer in its MetaClass that
794* points to the MetaClass's super MetaClass.
795* 2) Derive the name of the class from the super MetaClass pointer.
796* 3) Derive the name of the class's vtable from the name of the class
797* 4) Follow the super MetaClass pointer to get the address of the super
798* MetaClass's symbol
799* 5) Look up the super MetaClass symbol by address
800* 6) Derive the super class's name from the super MetaClass name
801* 7) Derive the super class's vtable from the super class's name
802* This procedure will allow us to find all of the OSObject-derived classes and
803* their super classes, and thus patch all of the vtables.
804*
805* We also have to take care to patch up the MetaClass's vtables. The
806* MetaClasses follow a parallel hierarchy to the classes, so once we have the
807* class name and super class name, we can also derive the MetaClass name and
808* the super MetaClass name, and thus find and patch their vtables as well.
b0d623f7 809*******************************************************************************/
b0d623f7 810
6d2010ae
A
811#define kOSMetaClassVTableName "__ZTV11OSMetaClass"
812
b0d623f7 813static kern_return_t
6d2010ae
A
814patch_vtables(KXLDKext *kext, KXLDDict *patched_vtables,
815 const KXLDDict *defined_symbols)
b0d623f7
A
816{
817 kern_return_t rval = KERN_FAILURE;
818 KXLDSymtabIterator iter;
6d2010ae
A
819 const KXLDSymtab *symtab = NULL;
820 const KXLDSym *metaclass = NULL;
821 KXLDSym *super_metaclass_pointer = NULL;
822 KXLDSym *final_sym = NULL;
823 KXLDVTable *vtable = NULL;
824 KXLDVTable *super_vtable = NULL;
825 char class_name[KXLD_MAX_NAME_LEN];
826 char super_class_name[KXLD_MAX_NAME_LEN];
827 char vtable_name[KXLD_MAX_NAME_LEN];
828 char super_vtable_name[KXLD_MAX_NAME_LEN];
829 char final_sym_name[KXLD_MAX_NAME_LEN];
830 char *demangled_name1 = NULL;
831 char *demangled_name2 = NULL;
832 size_t demangled_length1 = 0;;
833 size_t demangled_length2 = 0;
834 size_t len = 0;
835 u_int nvtables = 0;
836 u_int npatched = 0;
837 u_int nprogress = 0;
838 boolean_t failure = FALSE;
b0d623f7 839
6d2010ae
A
840 check(kext);
841 check(patched_vtables);
b0d623f7 842
6d2010ae 843 symtab = kxld_object_get_symtab(kext->kext);
b0d623f7 844
6d2010ae
A
845 rval = create_vtable_index(kext);
846 require_noerr(rval, finish);
b0d623f7 847
6d2010ae 848 /* Find each super meta class pointer symbol */
b0d623f7 849
6d2010ae
A
850 kxld_symtab_iterator_init(&iter, symtab,
851 kxld_sym_is_super_metaclass_pointer, FALSE);
852 nvtables = kxld_symtab_iterator_get_num_remaining(&iter);
b0d623f7 853
6d2010ae
A
854 while (npatched < nvtables) {
855 npatched = 0;
856 nprogress = 0;
b0d623f7 857 kxld_symtab_iterator_reset(&iter);
6d2010ae
A
858 while((super_metaclass_pointer = kxld_symtab_iterator_get_next(&iter)))
859 {
860 /* Get the class name from the smc pointer */
861 rval = kxld_sym_get_class_name_from_super_metaclass_pointer(
39037602
A
862 super_metaclass_pointer, class_name, sizeof(class_name));
863 require_noerr(rval, finish);
b0d623f7 864
6d2010ae
A
865 /* Get the vtable name from the class name */
866 rval = kxld_sym_get_vtable_name_from_class_name(class_name,
867 vtable_name, sizeof(vtable_name));
868 require_noerr(rval, finish);
b0d623f7 869
6d2010ae
A
870 /* Get the vtable and make sure it hasn't been patched */
871 vtable = kxld_dict_find(&kext->vtable_index, vtable_name);
872 require_action(vtable, finish, rval=KERN_FAILURE;
873 kxld_log(kKxldLogPatching, kKxldLogErr, kKxldLogMissingVtable,
874 vtable_name, class_name));
b0d623f7 875
6d2010ae 876 if (!vtable->is_patched) {
b0d623f7 877
6d2010ae
A
878 /* Find the SMCP's meta class symbol */
879 metaclass = get_metaclass_symbol_from_super_meta_class_pointer_symbol(
880 kext, super_metaclass_pointer);
39037602 881 require_action(metaclass, finish, rval=KERN_FAILURE);
b0d623f7 882
6d2010ae
A
883 /* Get the super class name from the super metaclass */
884 rval = kxld_sym_get_class_name_from_metaclass(metaclass,
885 super_class_name, sizeof(super_class_name));
886 require_noerr(rval, finish);
b0d623f7 887
6d2010ae
A
888 /* Get the super vtable name from the class name */
889 rval = kxld_sym_get_vtable_name_from_class_name(super_class_name,
890 super_vtable_name, sizeof(super_vtable_name));
891 require_noerr(rval, finish);
b0d623f7 892
6d2010ae
A
893 /* Get the super vtable if it's been patched */
894 super_vtable = kxld_dict_find(patched_vtables, super_vtable_name);
b0d623f7 895
6d2010ae
A
896 if (failure) {
897 const KXLDVTable *unpatched_super_vtable;
898 unpatched_super_vtable = kxld_dict_find(&kext->vtable_index,
899 super_vtable_name);
900
901 /* If the parent's vtable hasn't been patched, warn that
902 * this vtable is unpatchable because of the parent.
903 */
904 if (!super_vtable) {
905 kxld_log(kKxldLogPatching, kKxldLogErr,
906 "The %s was not patched because its parent, "
907 "the %s, was not %s.",
908 kxld_demangle(vtable_name, &demangled_name1,
909 &demangled_length1),
910 kxld_demangle(super_vtable_name, &demangled_name2,
911 &demangled_length2),
912 (unpatched_super_vtable) ? "patchable" : "found");
913 }
914 continue;
915 }
b0d623f7 916
6d2010ae 917 if (!super_vtable) continue;
b0d623f7 918
6d2010ae
A
919 /* Get the final symbol's name from the super vtable */
920 rval = kxld_sym_get_final_sym_name_from_class_name(super_class_name,
921 final_sym_name, sizeof(final_sym_name));
922 require_noerr(rval, finish);
b0d623f7 923
6d2010ae
A
924 /* Verify that the final symbol does not exist. First check
925 * all the externally defined symbols, then check locally.
926 */
927 final_sym = kxld_dict_find(defined_symbols, final_sym_name);
928 if (!final_sym) {
929 final_sym = kxld_symtab_get_locally_defined_symbol_by_name(
930 symtab, final_sym_name);
931 }
932 if (final_sym) {
933 kxld_log(kKxldLogPatching, kKxldLogErr,
934 "Class '%s' is a subclass of final class '%s'.",
935 kxld_demangle(class_name, &demangled_name1,
936 &demangled_length1),
937 kxld_demangle(super_class_name, &demangled_name2,
938 &demangled_length2));
939 continue;
940 }
b0d623f7 941
6d2010ae
A
942 /* Patch the class's vtable */
943 rval = kxld_vtable_patch(vtable, super_vtable, kext->kext);
944 if (rval) continue;
b0d623f7 945
6d2010ae
A
946 /* Add the class's vtable to the set of patched vtables */
947 rval = kxld_dict_insert(patched_vtables, vtable->name, vtable);
948 require_noerr(rval, finish);
b0d623f7 949
6d2010ae
A
950 /* Get the meta vtable name from the class name */
951 rval = kxld_sym_get_meta_vtable_name_from_class_name(class_name,
952 vtable_name, sizeof(vtable_name));
39037602 953 require_noerr(rval, finish);
b0d623f7 954
6d2010ae
A
955 /* Get the meta vtable. Whether or not it should exist has already
956 * been tested in create_vtables(), so if it doesn't exist and we're
957 * still running, we can safely skip it.
958 */
959 vtable = kxld_dict_find(&kext->vtable_index, vtable_name);
960 if (!vtable) {
961 ++nprogress;
962 ++npatched;
963 continue;
964 }
965 require_action(!vtable->is_patched, finish, rval=KERN_FAILURE);
b0d623f7 966
6d2010ae
A
967 /* There is no way to look up a metaclass vtable at runtime, but
968 * we know that every class's metaclass inherits directly from
969 * OSMetaClass, so we just hardcode that vtable name here.
970 */
971 len = strlcpy(super_vtable_name, kOSMetaClassVTableName,
972 sizeof(super_vtable_name));
973 require_action(len == const_strlen(kOSMetaClassVTableName),
974 finish, rval=KERN_FAILURE);
975
976 /* Get the super meta vtable */
977 super_vtable = kxld_dict_find(patched_vtables, super_vtable_name);
39037602 978 require_action(super_vtable && super_vtable->is_patched,
6d2010ae 979 finish, rval=KERN_FAILURE);
b0d623f7 980
6d2010ae
A
981 /* Patch the meta class's vtable */
982 rval = kxld_vtable_patch(vtable, super_vtable, kext->kext);
983 require_noerr(rval, finish);
b0d623f7 984
6d2010ae
A
985 /* Add the MetaClass's vtable to the set of patched vtables */
986 rval = kxld_dict_insert(patched_vtables, vtable->name, vtable);
987 require_noerr(rval, finish);
988
989 ++nprogress;
990 }
b0d623f7 991
6d2010ae 992 ++npatched;
b0d623f7 993 }
b0d623f7 994
6d2010ae
A
995 require_action(!failure, finish, rval=KERN_FAILURE);
996 failure = (nprogress == 0);
b0d623f7
A
997 }
998
999 rval = KERN_SUCCESS;
b0d623f7 1000finish:
6d2010ae
A
1001 if (demangled_name1) kxld_free(demangled_name1, demangled_length1);
1002 if (demangled_name2) kxld_free(demangled_name2, demangled_length2);
1003
b0d623f7
A
1004 return rval;
1005}
b0d623f7 1006
b0d623f7
A
1007/*******************************************************************************
1008*******************************************************************************/
1009static kern_return_t
6d2010ae 1010create_vtable_index(KXLDKext *kext)
b0d623f7
A
1011{
1012 kern_return_t rval = KERN_FAILURE;
6d2010ae 1013 KXLDVTable *vtable = NULL;
b0d623f7
A
1014 u_int i = 0;
1015
6d2010ae
A
1016 if (kext->vtable_index_created) {
1017 rval = KERN_SUCCESS;
1018 goto finish;
b0d623f7
A
1019 }
1020
6d2010ae
A
1021 /* Map vtable names to the vtable structures */
1022 rval = kxld_dict_init(&kext->vtable_index, kxld_dict_string_hash,
1023 kxld_dict_string_cmp, kext->vtables.nitems);
1024 require_noerr(rval, finish);
b0d623f7 1025
6d2010ae
A
1026 for (i = 0; i < kext->vtables.nitems; ++i) {
1027 vtable = kxld_array_get_item(&kext->vtables, i);
1028 rval = kxld_dict_insert(&kext->vtable_index, vtable->name, vtable);
1029 require_noerr(rval, finish);
b0d623f7
A
1030 }
1031
6d2010ae 1032 kext->vtable_index_created = TRUE;
b0d623f7 1033 rval = KERN_SUCCESS;
b0d623f7
A
1034finish:
1035 return rval;
1036}
1037
1038/*******************************************************************************
39037602 1039 *******************************************************************************/
6d2010ae
A
1040static const KXLDSym *
1041get_metaclass_symbol_from_super_meta_class_pointer_symbol(KXLDKext *kext,
39037602 1042 KXLDSym *super_metaclass_pointer_sym)
b0d623f7
A
1043{
1044 kern_return_t rval = KERN_FAILURE;
6d2010ae
A
1045 const KXLDReloc *reloc = NULL;
1046 const KXLDSect *sect = NULL;
1047 const KXLDSym *metaclass = NULL;
1048
b0d623f7 1049 check(kext);
6d2010ae 1050 check(super_metaclass_pointer_sym);
39037602 1051
6d2010ae
A
1052 /* Get the relocation entry that fills in the super metaclass pointer. */
1053 reloc = kxld_object_get_reloc_at_symbol(kext->kext,
39037602 1054 super_metaclass_pointer_sym);
6d2010ae 1055 require_action(reloc, finish, rval=KERN_FAILURE);
39037602 1056
6d2010ae
A
1057 /* Get the section of the super metaclass pointer. */
1058 sect = kxld_object_get_section_by_index(kext->kext,
39037602 1059 super_metaclass_pointer_sym->sectnum);
6d2010ae 1060 require_action(sect, finish, rval=KERN_FAILURE);
39037602 1061
6d2010ae
A
1062 /* Get the symbol that will be filled into the super metaclass pointer. */
1063 metaclass = kxld_object_get_symbol_of_reloc(kext->kext, reloc, sect);
39037602
A
1064
1065
b0d623f7 1066finish:
39037602
A
1067 if (metaclass == NULL) {
1068 kxld_log(kKxldLogLinking, kKxldLogErr,
1069 "metaclass == NULL kxld_sym %s <%s>",
1070 super_metaclass_pointer_sym->name, __func__);
1071 }
6d2010ae 1072 return metaclass;
b0d623f7 1073}
b0d623f7 1074
39037602 1075
b0d623f7
A
1076/*******************************************************************************
1077*******************************************************************************/
1078static kern_return_t
6d2010ae 1079validate_symbols(KXLDKext *kext)
b0d623f7
A
1080{
1081 kern_return_t rval = KERN_FAILURE;
6d2010ae
A
1082 KXLDSymtabIterator iter;
1083 KXLDSym *sym = NULL;
1084 u_int error = FALSE;
1085 char *demangled_name = NULL;
1086 size_t demangled_length = 0;
1087
1088 /* Check for any unresolved symbols */
1089 kxld_symtab_iterator_init(&iter, kxld_object_get_symtab(kext->kext),
1090 kxld_sym_is_unresolved, FALSE);
1091 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
1092 if (!error) {
1093 error = TRUE;
1094 kxld_log(kKxldLogLinking, kKxldLogErr,
1095 "The following symbols are unresolved for this kext:");
b0d623f7 1096 }
6d2010ae
A
1097 kxld_log(kKxldLogLinking, kKxldLogErr, "\t%s",
1098 kxld_demangle(sym->name, &demangled_name, &demangled_length));
b0d623f7 1099 }
6d2010ae 1100 require_noerr_action(error, finish, rval=KERN_FAILURE);
b0d623f7
A
1101
1102 rval = KERN_SUCCESS;
1103
1104finish:
6d2010ae 1105 if (demangled_name) kxld_free(demangled_name, demangled_length);
b0d623f7
A
1106 return rval;
1107}
1108