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