]> git.saurik.com Git - apple/xnu.git/blame - libkern/kxld/kxld_kext.c
xnu-7195.50.7.100.1.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@
0a7de745 5 *
b0d623f7
A
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.
0a7de745 14 *
b0d623f7
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
0a7de745 17 *
b0d623f7
A
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.
0a7de745 25 *
b0d623f7
A
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 {
0a7de745
A
70 KXLDObject *kext;
71 KXLDObject *interface;
72 KXLDArray vtables;
73 KXLDDict vtable_index;
74 boolean_t vtables_created;
75 boolean_t vtable_index_created;
b0d623f7
A
76};
77
78/*******************************************************************************
79* Prototypes
80*******************************************************************************/
81
6d2010ae 82static kern_return_t export_symbols_through_interface(
0a7de745
A
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);
6d2010ae 87static kern_return_t export_symbols(const KXLDObject *kext,
0a7de745 88 KXLDDict *defined_symbols_by_name,
6d2010ae
A
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);
0a7de745
A
93static kern_return_t get_vtable_syms_from_smcp(KXLDKext *kext,
94 const KXLDDict *defined_symbols, KXLDSym *super_metaclass_ptr_sym,
6d2010ae
A
95 KXLDSym **vtable_sym_out, KXLDSym **meta_vtable_sym_out);
96
0a7de745 97static kern_return_t resolve_symbols(KXLDKext *kext,
6d2010ae
A
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 103static const KXLDSym *get_metaclass_symbol_from_super_meta_class_pointer_symbol(
0a7de745 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{
0a7de745 113 return sizeof(KXLDKext);
b0d623f7
A
114}
115
116/*******************************************************************************
117*******************************************************************************/
118kern_return_t
0a7de745 119kxld_kext_init(KXLDKext *kext, KXLDObject *kext_object,
6d2010ae 120 KXLDObject *interface_object)
b0d623f7 121{
0a7de745 122 kern_return_t rval = KERN_FAILURE;
b0d623f7 123
0a7de745
A
124 check(kext);
125 check(kext_object);
b0d623f7 126
0a7de745 127 kext->kext = kext_object;
b0d623f7 128
0a7de745
A
129 if (interface_object) {
130 kext->interface = interface_object;
b0d623f7 131
0a7de745
A
132 rval = kxld_object_index_symbols_by_name(kext->kext);
133 require_noerr(rval, finish);
134 }
135
136 rval = KERN_SUCCESS;
6d2010ae 137finish:
0a7de745 138 return rval;
6d2010ae 139}
b0d623f7 140
6d2010ae
A
141/*******************************************************************************
142*******************************************************************************/
143void
144kxld_kext_clear(KXLDKext *kext)
145{
0a7de745
A
146 KXLDVTable *vtable = NULL;
147 u_int i;
148
149 check(kext);
150
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);
157
158 kext->kext = NULL;
159 kext->interface = NULL;
160 kext->vtables_created = FALSE;
161 kext->vtable_index_created = FALSE;
6d2010ae 162}
b0d623f7 163
b0d623f7 164
6d2010ae
A
165/*******************************************************************************
166*******************************************************************************/
0a7de745 167void
6d2010ae
A
168kxld_kext_deinit(KXLDKext *kext)
169{
0a7de745
A
170 KXLDVTable *vtable = NULL;
171 u_int i;
b0d623f7 172
0a7de745 173 check(kext);
b0d623f7 174
0a7de745
A
175 for (i = 0; i < kext->vtables.maxitems; ++i) {
176 vtable = kxld_array_get_slot(&kext->vtables, i);
177 kxld_vtable_deinit(vtable);
178 }
179 kxld_array_deinit(&kext->vtables);
180 kxld_dict_deinit(&kext->vtable_index);
b0d623f7 181
0a7de745 182 bzero(kext, sizeof(*kext));
6d2010ae 183}
b0d623f7 184
6d2010ae
A
185/*******************************************************************************
186*******************************************************************************/
0a7de745
A
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 192{
0a7de745
A
193 kern_return_t rval = KERN_FAILURE;
194
195 check(kext);
196
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);
205 require_noerr(rval, finish);
206 }
207
208 rval = KERN_SUCCESS;
b0d623f7 209finish:
0a7de745 210 return rval;
b0d623f7
A
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{
0a7de745
A
220 kern_return_t rval = KERN_FAILURE;
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;
226
227 check(kext);
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 }
247
248 rval = kxld_dict_insert(defined_symbols_by_name,
249 kext_sym->name, kext_sym);
250 require_noerr(rval, finish);
251 }
252
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 }
266
267 rval = kxld_dict_insert(defined_symbols_by_name,
268 interface_sym->name, kext_sym);
269 require_noerr(rval, finish);
270 }
271 }
272
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 }
283
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 }
293 }
294
295 rval = KERN_SUCCESS;
b0d623f7 296finish:
0a7de745 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 305{
0a7de745
A
306 kern_return_t rval = KERN_FAILURE;
307 KXLDSymtabIterator iter;
308 KXLDSym *sym = NULL;
309
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);
316 }
317
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 }
323 }
324
325 rval = KERN_SUCCESS;
b0d623f7 326finish:
0a7de745 327 return rval;
b0d623f7
A
328}
329
330/*******************************************************************************
331*******************************************************************************/
0a7de745 332kern_return_t
6d2010ae
A
333kxld_kext_export_vtables(KXLDKext *kext, const KXLDDict *defined_cxx_symbols,
334 const KXLDDict *defined_symbols, KXLDDict *vtables)
b0d623f7 335{
0a7de745
A
336 kern_return_t rval = KERN_FAILURE;
337 KXLDVTable *vtable = NULL;
338 u_int i = 0;
339
340 check(kext);
341 check(defined_symbols);
342 check(defined_cxx_symbols);
343 check(vtables);
344
345 rval = create_vtables(kext, defined_cxx_symbols, defined_symbols);
346 require_noerr(rval, finish);
347
348 for (i = 0; i < kext->vtables.nitems; ++i) {
349 vtable = kxld_array_get_item(&kext->vtables, i);
350
351 rval = kxld_dict_insert(vtables, vtable->name, vtable);
352 require_noerr(rval, finish);
353 }
354
355 rval = KERN_SUCCESS;
6d2010ae 356finish:
0a7de745 357 return rval;
b0d623f7
A
358}
359
39037602 360/*******************************************************************************
0a7de745 361*******************************************************************************/
39037602
A
362void
363kxld_kext_get_vmsize_for_seg_by_name(const KXLDKext *kext,
0a7de745
A
364 const char *segname,
365 u_long *vmsize)
39037602 366{
0a7de745 367 (void) kxld_object_get_vmsize_for_seg_by_name(kext->kext, segname, vmsize);
39037602
A
368}
369
b0d623f7
A
370/*******************************************************************************
371*******************************************************************************/
0a7de745
A
372void
373kxld_kext_get_vmsize(const KXLDKext *kext,
6d2010ae 374 u_long *header_size, u_long *vmsize)
b0d623f7 375{
0a7de745 376 (void) kxld_object_get_vmsize(kext->kext, header_size, vmsize);
b0d623f7 377}
316670eb
A
378
379/*******************************************************************************
0a7de745 380*******************************************************************************/
39037602 381void
316670eb
A
382kxld_kext_set_linked_object_size(KXLDKext *kext, u_long vmsize)
383{
0a7de745 384 (void) kxld_object_set_linked_object_size(kext->kext, vmsize);
316670eb
A
385}
386
b0d623f7
A
387/*******************************************************************************
388*******************************************************************************/
0a7de745
A
389kern_return_t
390kxld_kext_export_linked_object(const KXLDKext *kext,
391 void *linked_object,
392 kxld_addr_t *kmod_info)
b0d623f7 393{
0a7de745
A
394 kern_return_t rval = KERN_FAILURE;
395 const KXLDSym *kmodsym = NULL;
b0d623f7 396
0a7de745
A
397 kmodsym = kxld_symtab_get_locally_defined_symbol_by_name(
398 kxld_object_get_symtab(kext->kext), KXLD_KMOD_INFO_SYMBOL);
39037602 399
0a7de745
A
400 require_action(kmodsym, finish, rval = KERN_FAILURE;
401 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogNoKmodInfo));
39037602 402
0a7de745 403 *kmod_info = kmodsym->link_addr;
6d2010ae 404
0a7de745 405 rval = kxld_object_export_linked_object(kext->kext, linked_object);
6d2010ae 406finish:
0a7de745 407 return rval;
b0d623f7
A
408}
409
410/*******************************************************************************
411*******************************************************************************/
6d2010ae 412kern_return_t
39037602 413kxld_kext_relocate(KXLDKext *kext,
0a7de745
A
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 419{
0a7de745
A
420 kern_return_t rval = KERN_FAILURE;
421
422 check(kext);
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.
433 */
434 rval = kxld_object_index_cxx_symbols_by_value(kext->kext);
435 require_noerr(rval, finish);
436
437 rval = kxld_object_index_symbols_by_name(kext->kext);
438 require_noerr(rval, finish);
439
440 rval = kxld_object_relocate(kext->kext, link_address);
441 require_noerr(rval, finish);
442
443 rval = resolve_symbols(kext, defined_symbols, obsolete_symbols);
444 require_noerr(rval, finish);
445
446 rval = create_vtables(kext, defined_cxx_symbols, /* defined_symbols */ NULL);
447 require_noerr(rval, finish);
448
449 if (isSplitKext == FALSE) {
450 rval = patch_vtables(kext, patched_vtables, defined_symbols);
451 require_noerr(rval, finish);
452 }
453
454 rval = validate_symbols(kext);
455 require_noerr(rval, finish);
456
457 rval = kxld_object_process_relocations(kext->kext, patched_vtables);
458 require_noerr(rval, finish);
459
460 rval = KERN_SUCCESS;
b0d623f7 461finish:
0a7de745 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.
0a7de745 475*
6d2010ae
A
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*******************************************************************************/
0a7de745 479static kern_return_t
6d2010ae
A
480create_vtables(KXLDKext *kext, const KXLDDict *defined_cxx_symbols,
481 const KXLDDict *defined_symbols)
b0d623f7 482{
0a7de745
A
483 kern_return_t rval = KERN_FAILURE;
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;
491 u_int i = 0;
492 u_int nvtables = 0;
493
494 if (kext->vtables_created) {
495 rval = KERN_SUCCESS;
496 goto finish;
497 }
498
499 symtab = kxld_object_get_symtab(kext->kext);
500
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 }
515
516 rval = kxld_array_init(&kext->vtables, sizeof(KXLDVTable), nvtables);
517 require_noerr(rval, finish);
518
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 }
529
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);
534
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);
544 require_noerr(rval, finish);
545 } else {
546 kxld_array_resize(&kext->vtables, --nvtables);
547 meta_vtable = NULL;
548 }
549 }
550 }
551 require_action(i == kext->vtables.nitems, finish,
552 rval = KERN_FAILURE);
553
554 kext->vtables_created = TRUE;
555 rval = KERN_SUCCESS;
b0d623f7 556finish:
0a7de745 557 return rval;
b0d623f7
A
558}
559
560/*******************************************************************************
561*******************************************************************************/
562static kern_return_t
6d2010ae 563get_vtable_syms_from_smcp(KXLDKext *kext, const KXLDDict *defined_symbols,
0a7de745 564 KXLDSym *super_metaclass_ptr_sym, KXLDSym **vtable_sym_out,
6d2010ae 565 KXLDSym **meta_vtable_sym_out)
b0d623f7 566{
0a7de745
A
567 kern_return_t rval = KERN_FAILURE;
568 const KXLDSymtab *symtab = NULL;
569 KXLDSym *vtable_sym = NULL;
570 KXLDSym *meta_vtable_sym = NULL;
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];
574 char *demangled_name1 = NULL;
575 char *demangled_name2 = NULL;
576 size_t demangled_length1 = 0;
577 size_t demangled_length2 = 0;
578
579 check(kext);
580 check(vtable_sym_out);
581 check(meta_vtable_sym_out);
582
583 require(!kxld_object_is_kernel(kext->kext), finish);
584
585 symtab = kxld_object_get_symtab(kext->kext);
586
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);
591
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);
596
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));
607
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);
612
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 {
628 kxld_log(kKxldLogPatching, kKxldLogErr,
629 "Warning: " kKxldLogMissingVtable,
630 kxld_demangle(meta_vtable_name, &demangled_name1,
631 &demangled_length1),
632 kxld_demangle(class_name, &demangled_name2,
633 &demangled_length2));
634 }
635 }
636
637 *vtable_sym_out = vtable_sym;
638 *meta_vtable_sym_out = meta_vtable_sym;
639 rval = KERN_SUCCESS;
b0d623f7 640finish:
0a7de745
A
641 if (demangled_name1) {
642 kxld_free(demangled_name1, demangled_length1);
643 }
644 if (demangled_name2) {
645 kxld_free(demangled_name2, demangled_length2);
646 }
647
648 return rval;
b0d623f7
A
649}
650
651/*******************************************************************************
652*******************************************************************************/
653static kern_return_t
0a7de745 654resolve_symbols(KXLDKext *kext, const KXLDDict *defined_symbols,
6d2010ae 655 const KXLDDict *obsolete_symbols)
b0d623f7 656{
0a7de745
A
657 kern_return_t rval = KERN_FAILURE;
658 const KXLDSymtab *symtab = NULL;
659 KXLDSymtabIterator iter;
660 KXLDSym *sym = NULL;
661 KXLDSym *defined_sym = NULL;
662 const char *name = NULL;
663 boolean_t tests_for_weak = FALSE;
664 boolean_t error = FALSE;
665 char *demangled_name = NULL;
666 size_t demangled_length = 0;
667
668 check(kext->kext);
669 check(defined_symbols);
670 check(obsolete_symbols);
671
672 symtab = kxld_object_get_symtab(kext->kext);
673
674 /* Check if the kext tests for weak symbols */
675 sym = kxld_symtab_get_symbol_by_name(symtab, KXLD_WEAK_TEST_SYMBOL);
676 tests_for_weak = (sym != NULL);
677
678 /* Check for duplicate symbols */
679 kxld_symtab_iterator_init(&iter, symtab, kxld_sym_is_exported, FALSE);
680 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
681 defined_sym = kxld_dict_find(defined_symbols, sym->name);
682 if (defined_sym) {
683 /* Not a problem if the symbols have the same address */
684 if (defined_sym->link_addr == sym->link_addr) {
685 continue;
686 }
687
688 if (!error) {
689 error = TRUE;
690 kxld_log(kKxldLogLinking, kKxldLogErr,
691 "The following symbols were defined more than once:");
692 }
693
694 kxld_log(kKxldLogLinking, kKxldLogErr, "\t%s: %p - %p",
695 kxld_demangle(sym->name, &demangled_name, &demangled_length),
696 (void *) (uintptr_t) sym->link_addr,
697 (void *) (uintptr_t) defined_sym->link_addr);
698 }
699 }
700 require_noerr_action(error, finish, rval = KERN_FAILURE);
701
702 /* Resolve undefined and indirect symbols */
703
704 /* Iterate over all unresolved symbols */
705 kxld_symtab_iterator_init(&iter, symtab,
706 kxld_sym_is_unresolved, FALSE);
707 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
708 /* Common symbols are not supported */
709 if (kxld_sym_is_common(sym)) {
710 if (!error) {
711 error = TRUE;
712 if (kxld_object_target_supports_common_symbols(kext->kext)) {
713 kxld_log(kKxldLogLinking, kKxldLogErr,
714 "The following common symbols were not resolved:");
715 } else {
716 kxld_log(kKxldLogLinking, kKxldLogErr,
717 "Common symbols are not supported in kernel extensions. "
718 "Use -fno-common to build your kext. "
719 "The following are common symbols:");
720 }
721 }
722 kxld_log(kKxldLogLinking, kKxldLogErr, "\t%s",
723 kxld_demangle(sym->name, &demangled_name, &demangled_length));
724 } else {
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 */
738
739 if (defined_sym) {
740 rval = kxld_sym_resolve(sym, defined_sym->link_addr);
741 require_noerr(rval, finish);
742
743 if (obsolete_symbols && kxld_dict_find(obsolete_symbols, name)) {
744 kxld_log(kKxldLogLinking, kKxldLogWarn,
745 "This kext uses obsolete symbol %s.",
746 kxld_demangle(name, &demangled_name, &demangled_length));
747 }
748 } else if (kxld_sym_is_weak(sym)) {
749 kxld_addr_t addr = 0;
750
751 /* Make sure that the kext has referenced gOSKextUnresolved.
752 */
753 require_action(tests_for_weak, finish,
754 rval = KERN_FAILURE;
755 kxld_log(kKxldLogLinking, kKxldLogErr,
756 "This kext has weak references but does not test for "
757 "them. Test for weak references with "
758 "OSKextSymbolIsResolved(). (found in <libkern/OSKextLib.h>)"));
b0d623f7 759
6d2010ae 760#if KERNEL
0a7de745
A
761 /* Get the address of the default weak address.
762 */
763 addr = (kxld_addr_t) &kext_weak_symbol_referenced;
764#else
765 /* This is run during symbol generation only, so we only
766 * need a filler value here.
767 */
768 addr = 0xF00DD00D;
6d2010ae
A
769#endif /* KERNEL */
770
0a7de745
A
771 rval = kxld_sym_resolve(sym, addr);
772 require_noerr(rval, finish);
773 }
774 }
775 }
776 require_noerr_action(error, finish, rval = KERN_FAILURE);
b0d623f7 777
0a7de745 778 rval = KERN_SUCCESS;
b0d623f7
A
779
780finish:
0a7de745
A
781 if (demangled_name) {
782 kxld_free(demangled_name, demangled_length);
783 }
6d2010ae 784
0a7de745 785 return rval;
b0d623f7 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
0a7de745 814patch_vtables(KXLDKext *kext, KXLDDict *patched_vtables,
6d2010ae 815 const KXLDDict *defined_symbols)
b0d623f7 816{
0a7de745
A
817 kern_return_t rval = KERN_FAILURE;
818 KXLDSymtabIterator iter;
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;
839
840 check(kext);
841 check(patched_vtables);
842
843 symtab = kxld_object_get_symtab(kext->kext);
844
845 rval = create_vtable_index(kext);
846 require_noerr(rval, finish);
847
848 /* Find each super meta class pointer symbol */
849
850 kxld_symtab_iterator_init(&iter, symtab,
851 kxld_sym_is_super_metaclass_pointer, FALSE);
852 nvtables = kxld_symtab_iterator_get_num_remaining(&iter);
853
854 while (npatched < nvtables) {
855 npatched = 0;
856 nprogress = 0;
857 kxld_symtab_iterator_reset(&iter);
858 while ((super_metaclass_pointer = kxld_symtab_iterator_get_next(&iter))) {
859 /* Get the class name from the smc pointer */
860 rval = kxld_sym_get_class_name_from_super_metaclass_pointer(
861 super_metaclass_pointer, class_name, sizeof(class_name));
862 require_noerr(rval, finish);
863
864 /* Get the vtable name from the class name */
865 rval = kxld_sym_get_vtable_name_from_class_name(class_name,
866 vtable_name, sizeof(vtable_name));
867 require_noerr(rval, finish);
868
869 /* Get the vtable and make sure it hasn't been patched */
870 vtable = kxld_dict_find(&kext->vtable_index, vtable_name);
871 require_action(vtable, finish, rval = KERN_FAILURE;
872 kxld_log(kKxldLogPatching, kKxldLogErr, kKxldLogMissingVtable,
873 vtable_name, class_name));
874
875 if (!vtable->is_patched) {
876 /* Find the SMCP's meta class symbol */
877 metaclass = get_metaclass_symbol_from_super_meta_class_pointer_symbol(
878 kext, super_metaclass_pointer);
879 require_action(metaclass, finish, rval = KERN_FAILURE);
880
881 /* Get the super class name from the super metaclass */
882 rval = kxld_sym_get_class_name_from_metaclass(metaclass,
883 super_class_name, sizeof(super_class_name));
884 require_noerr(rval, finish);
885
886 /* Get the super vtable name from the class name */
887 rval = kxld_sym_get_vtable_name_from_class_name(super_class_name,
888 super_vtable_name, sizeof(super_vtable_name));
889 require_noerr(rval, finish);
890
891 /* Get the super vtable if it's been patched */
892 super_vtable = kxld_dict_find(patched_vtables, super_vtable_name);
893
894 if (failure) {
895 const KXLDVTable *unpatched_super_vtable;
896 unpatched_super_vtable = kxld_dict_find(&kext->vtable_index,
897 super_vtable_name);
898
899 /* If the parent's vtable hasn't been patched, warn that
900 * this vtable is unpatchable because of the parent.
901 */
902 if (!super_vtable) {
903 kxld_log(kKxldLogPatching, kKxldLogErr,
904 "The %s was not patched because its parent, "
905 "the %s, was not %s.",
906 kxld_demangle(vtable_name, &demangled_name1,
907 &demangled_length1),
908 kxld_demangle(super_vtable_name, &demangled_name2,
909 &demangled_length2),
910 (unpatched_super_vtable) ? "patchable" : "found");
911 }
912 continue;
913 }
914
915 if (!super_vtable) {
916 continue;
917 }
918
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);
923
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 }
941
942 /* Patch the class's vtable */
943 rval = kxld_vtable_patch(vtable, super_vtable, kext->kext);
944 if (rval) {
945 continue;
946 }
947
948 /* Add the class's vtable to the set of patched vtables */
949 rval = kxld_dict_insert(patched_vtables, vtable->name, vtable);
950 require_noerr(rval, finish);
951
952 /* Get the meta vtable name from the class name */
953 rval = kxld_sym_get_meta_vtable_name_from_class_name(class_name,
954 vtable_name, sizeof(vtable_name));
955 require_noerr(rval, finish);
956
957 /* Get the meta vtable. Whether or not it should exist has already
958 * been tested in create_vtables(), so if it doesn't exist and we're
959 * still running, we can safely skip it.
960 */
961 vtable = kxld_dict_find(&kext->vtable_index, vtable_name);
962 if (!vtable) {
963 ++nprogress;
964 ++npatched;
965 continue;
966 }
967 require_action(!vtable->is_patched, finish, rval = KERN_FAILURE);
968
969 /* There is no way to look up a metaclass vtable at runtime, but
970 * we know that every class's metaclass inherits directly from
971 * OSMetaClass, so we just hardcode that vtable name here.
972 */
973 len = strlcpy(super_vtable_name, kOSMetaClassVTableName,
974 sizeof(super_vtable_name));
975 require_action(len == const_strlen(kOSMetaClassVTableName),
976 finish, rval = KERN_FAILURE);
977
978 /* Get the super meta vtable */
979 super_vtable = kxld_dict_find(patched_vtables, super_vtable_name);
980 require_action(super_vtable && super_vtable->is_patched,
981 finish, rval = KERN_FAILURE);
982
983 /* Patch the meta class's vtable */
984 rval = kxld_vtable_patch(vtable, super_vtable, kext->kext);
985 require_noerr(rval, finish);
986
987 /* Add the MetaClass's vtable to the set of patched vtables */
988 rval = kxld_dict_insert(patched_vtables, vtable->name, vtable);
989 require_noerr(rval, finish);
990
991 ++nprogress;
992 }
993
994 ++npatched;
995 }
996
997 require_action(!failure, finish, rval = KERN_FAILURE);
998 failure = (nprogress == 0);
999 }
1000
1001 rval = KERN_SUCCESS;
b0d623f7 1002finish:
0a7de745
A
1003 if (demangled_name1) {
1004 kxld_free(demangled_name1, demangled_length1);
1005 }
1006 if (demangled_name2) {
1007 kxld_free(demangled_name2, demangled_length2);
1008 }
1009
1010 return rval;
b0d623f7 1011}
b0d623f7 1012
b0d623f7
A
1013/*******************************************************************************
1014*******************************************************************************/
1015static kern_return_t
6d2010ae 1016create_vtable_index(KXLDKext *kext)
b0d623f7 1017{
0a7de745
A
1018 kern_return_t rval = KERN_FAILURE;
1019 KXLDVTable *vtable = NULL;
1020 u_int i = 0;
1021
1022 if (kext->vtable_index_created) {
1023 rval = KERN_SUCCESS;
1024 goto finish;
1025 }
1026
1027 /* Map vtable names to the vtable structures */
1028 rval = kxld_dict_init(&kext->vtable_index, kxld_dict_string_hash,
1029 kxld_dict_string_cmp, kext->vtables.nitems);
1030 require_noerr(rval, finish);
1031
1032 for (i = 0; i < kext->vtables.nitems; ++i) {
1033 vtable = kxld_array_get_item(&kext->vtables, i);
1034 rval = kxld_dict_insert(&kext->vtable_index, vtable->name, vtable);
1035 require_noerr(rval, finish);
1036 }
1037
1038 kext->vtable_index_created = TRUE;
1039 rval = KERN_SUCCESS;
b0d623f7 1040finish:
0a7de745 1041 return rval;
b0d623f7
A
1042}
1043
1044/*******************************************************************************
0a7de745 1045*******************************************************************************/
6d2010ae
A
1046static const KXLDSym *
1047get_metaclass_symbol_from_super_meta_class_pointer_symbol(KXLDKext *kext,
0a7de745 1048 KXLDSym *super_metaclass_pointer_sym)
b0d623f7 1049{
0a7de745
A
1050 kern_return_t rval = KERN_FAILURE;
1051 const KXLDReloc *reloc = NULL;
1052 const KXLDSect *sect = NULL;
1053 const KXLDSym *metaclass = NULL;
1054
1055 check(kext);
1056 check(super_metaclass_pointer_sym);
1057
1058 /* Get the relocation entry that fills in the super metaclass pointer. */
1059 reloc = kxld_object_get_reloc_at_symbol(kext->kext,
1060 super_metaclass_pointer_sym);
1061 require_action(reloc, finish, rval = KERN_FAILURE);
1062
1063 /* Get the section of the super metaclass pointer. */
1064 sect = kxld_object_get_section_by_index(kext->kext,
1065 super_metaclass_pointer_sym->sectnum);
1066 require_action(sect, finish, rval = KERN_FAILURE);
1067
1068 /* Get the symbol that will be filled into the super metaclass pointer. */
1069 metaclass = kxld_object_get_symbol_of_reloc(kext->kext, reloc, sect);
1070
1071
b0d623f7 1072finish:
0a7de745
A
1073 if (metaclass == NULL) {
1074 kxld_log(kKxldLogLinking, kKxldLogErr,
1075 "metaclass == NULL kxld_sym %s <%s>",
1076 super_metaclass_pointer_sym->name, __func__);
1077 }
1078 return metaclass;
b0d623f7 1079}
b0d623f7 1080
39037602 1081
b0d623f7
A
1082/*******************************************************************************
1083*******************************************************************************/
1084static kern_return_t
6d2010ae 1085validate_symbols(KXLDKext *kext)
b0d623f7 1086{
0a7de745
A
1087 kern_return_t rval = KERN_FAILURE;
1088 KXLDSymtabIterator iter;
1089 KXLDSym *sym = NULL;
1090 u_int error = FALSE;
1091 char *demangled_name = NULL;
1092 size_t demangled_length = 0;
1093
1094 /* Check for any unresolved symbols */
1095 kxld_symtab_iterator_init(&iter, kxld_object_get_symtab(kext->kext),
1096 kxld_sym_is_unresolved, FALSE);
1097 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
1098 if (!error) {
1099 error = TRUE;
1100 kxld_log(kKxldLogLinking, kKxldLogErr,
1101 "The following symbols are unresolved for this kext:");
1102 }
1103 kxld_log(kKxldLogLinking, kKxldLogErr, "\t%s",
1104 kxld_demangle(sym->name, &demangled_name, &demangled_length));
1105 }
1106 require_noerr_action(error, finish, rval = KERN_FAILURE);
1107
1108 rval = KERN_SUCCESS;
b0d623f7
A
1109
1110finish:
0a7de745
A
1111 if (demangled_name) {
1112 kxld_free(demangled_name, demangled_length);
1113 }
1114 return rval;
b0d623f7 1115}