2 * Copyright (c) 2008 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <mach-o/loader.h>
30 #include <mach-o/nlist.h>
31 #include <sys/queue.h>
32 #include <sys/types.h>
34 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
35 #include <AssertMacros.h>
37 #include "kxld_array.h"
38 #include "kxld_dict.h"
39 #include "kxld_sect.h"
41 #include "kxld_symtab.h"
42 #include "kxld_util.h"
50 boolean_t cxx_index_initialized
;
51 boolean_t name_index_initialized
;
54 /*******************************************************************************
56 *******************************************************************************/
58 static kern_return_t
init_macho(KXLDSymtab
*symtab
, struct symtab_command
*src
,
59 u_char
*macho
, KXLDSeg
* kernel_linkedit_seg
,
61 __attribute__((nonnull(1, 2)));
63 #if KXLD_USER_OR_ILP32
64 static kern_return_t
init_syms_32(KXLDSymtab
*symtab
, u_char
*macho
, u_long offset
,
68 static kern_return_t
init_syms_64(KXLDSymtab
*symtab
, u_char
*macho
, u_long offset
,
72 static void restrict_private_symbols(KXLDSymtab
*symtab
)
73 __attribute__((nonnull
));
74 static boolean_t
sym_is_defined_cxx(const KXLDSym
*sym
);
75 static boolean_t
sym_is_name_indexed(const KXLDSym
*sym
);
77 /*******************************************************************************
78 *******************************************************************************/
82 return sizeof(KXLDSymtab
);
85 #if KXLD_USER_OR_ILP32
86 /*******************************************************************************
87 *******************************************************************************/
89 kxld_symtab_init_from_macho_32(KXLDSymtab
*symtab
, struct symtab_command
*src
,
90 u_char
*macho
, KXLDSeg
* kernel_linkedit_seg
)
92 return init_macho(symtab
, src
, macho
, kernel_linkedit_seg
,
93 /* is_32_bit */ TRUE
);
95 #endif /* KXLD_USER_ILP32 */
98 /*******************************************************************************
99 *******************************************************************************/
101 kxld_symtab_init_from_macho_64(KXLDSymtab
*symtab
, struct symtab_command
*src
,
102 u_char
*macho
, KXLDSeg
* kernel_linkedit_seg
)
104 return init_macho(symtab
, src
, macho
, kernel_linkedit_seg
,
105 /* is_32_bit */ FALSE
);
107 #endif /* KXLD_USER_OR_LP64 */
109 /*******************************************************************************
110 *******************************************************************************/
112 init_macho(KXLDSymtab
*symtab
, struct symtab_command
*src
,
113 u_char
*macho
, KXLDSeg
* kernel_linkedit_seg
,
114 boolean_t is_32_bit __unused
)
116 kern_return_t rval
= KERN_FAILURE
;
118 u_char
* macho_or_linkedit
= macho
;
124 /* Initialize the symbol array */
126 rval
= kxld_array_init(&symtab
->syms
, sizeof(KXLDSym
), src
->nsyms
);
127 require_noerr(rval
, finish
);
129 /* Initialize the string table */
131 if (kernel_linkedit_seg
) {
132 /* If initing the kernel file in memory, we can't trust
133 * the symtab offsets directly, because the kernel file has been mapped
134 * into memory and the mach-o offsets are disk-based.
136 * The symoff is an offset relative to the linkedit segment
137 * so we just subtract the fileoffset of the linkedit segment
138 * to get its relative start.
140 * The strings table is an actual pointer, so we calculate that from
141 * the linkedit's vmaddr.
143 * Further, the init_syms_... functions need an adjusted base
144 * pointer instead of the beginning of the macho, so we substitute
145 * the base of the linkedit segment.
148 symoff
= (u_long
)(src
->symoff
- kernel_linkedit_seg
->fileoff
);
149 symtab
->strings
= (char *)(uintptr_t)kernel_linkedit_seg
->base_addr
+
150 src
->stroff
- kernel_linkedit_seg
->fileoff
;
151 macho_or_linkedit
= (u_char
*)(uintptr_t)kernel_linkedit_seg
->base_addr
;
153 symoff
= (u_long
)src
->symoff
;
154 symtab
->strings
= (char *) (macho
+ src
->stroff
);
157 symtab
->strsize
= src
->strsize
;
159 /* Initialize the symbols */
161 KXLD_3264_FUNC(is_32_bit
, rval
,
162 init_syms_32
, init_syms_64
,
163 symtab
, macho_or_linkedit
, symoff
, src
->nsyms
);
164 require_noerr(rval
, finish
);
166 /* Some symbols must be forced private for compatibility */
167 (void) restrict_private_symbols(symtab
);
169 /* Save the output */
177 #if KXLD_USER_OR_ILP32
178 /*******************************************************************************
179 * In the running kernel, 'macho' is actually the start of the linkedit segment.
180 *******************************************************************************/
182 init_syms_32(KXLDSymtab
*symtab
, u_char
*macho
, u_long offset
, u_int nsyms
)
184 kern_return_t rval
= KERN_FAILURE
;
187 struct nlist
*src_syms
= (struct nlist
*) ((void *) (macho
+ offset
));
189 for (i
= 0; i
< nsyms
; ++i
) {
190 sym
= kxld_array_get_item(&symtab
->syms
, i
);
191 require_action(sym
, finish
, rval
= KERN_FAILURE
);
193 rval
= kxld_sym_init_from_macho32(sym
, symtab
->strings
, &src_syms
[i
]);
194 require_noerr(rval
, finish
);
202 #endif /* KXLD_USER_OR_ILP32 */
204 #if KXLD_USER_OR_LP64
205 /*******************************************************************************
206 * In the running kernel, 'macho' is actually the start of the linkedit segment.
207 *******************************************************************************/
209 init_syms_64(KXLDSymtab
*symtab
, u_char
*macho
, u_long offset
, u_int nsyms
)
211 kern_return_t rval
= KERN_FAILURE
;
214 struct nlist_64
*src_syms
= (struct nlist_64
*) ((void *) (macho
+ offset
));
216 for (i
= 0; i
< nsyms
; ++i
) {
217 sym
= kxld_array_get_item(&symtab
->syms
, i
);
218 require_action(sym
, finish
, rval
= KERN_FAILURE
);
220 rval
= kxld_sym_init_from_macho64(sym
, symtab
->strings
, &src_syms
[i
]);
221 require_noerr(rval
, finish
);
229 #endif /* KXLD_USER_OR_LP64 */
231 /*******************************************************************************
232 * Temporary workaround for PR-6668105
233 * new, new[], delete, and delete[] may be overridden globally in a kext.
234 * We should do this with some sort of weak symbols, but we'll use a whitelist
235 * for now to minimize risk.
236 *******************************************************************************/
238 restrict_private_symbols(KXLDSymtab
*symtab
)
240 const char *private_symbols
[] = {
241 KXLD_KMOD_INFO_SYMBOL
,
242 KXLD_OPERATOR_NEW_SYMBOL
,
243 KXLD_OPERATOR_NEW_ARRAY_SYMBOL
,
244 KXLD_OPERATOR_DELETE_SYMBOL
,
245 KXLD_OPERATOR_DELETE_ARRAY_SYMBOL
247 KXLDSymtabIterator iter
;
249 const char *name
= NULL
;
252 kxld_symtab_iterator_init(&iter
, symtab
, kxld_sym_is_exported
, FALSE
);
253 while ((sym
= kxld_symtab_iterator_get_next(&iter
))) {
254 for (i
= 0; i
< const_array_len(private_symbols
); ++i
) {
255 name
= private_symbols
[i
];
256 if (!streq(sym
->name
, name
)) {
260 kxld_sym_mark_private(sym
);
266 /*******************************************************************************
267 *******************************************************************************/
269 kxld_symtab_iterator_init(KXLDSymtabIterator
*iter
, const KXLDSymtab
*symtab
,
270 KXLDSymPredicateTest test
, boolean_t negate
)
276 iter
->symtab
= symtab
;
279 iter
->negate
= negate
;
282 /*******************************************************************************
283 *******************************************************************************/
285 kxld_symtab_clear(KXLDSymtab
*symtab
)
289 kxld_array_clear(&symtab
->syms
);
290 kxld_dict_clear(&symtab
->cxx_index
);
291 kxld_dict_clear(&symtab
->name_index
);
292 symtab
->strings
= NULL
;
294 symtab
->cxx_index_initialized
= 0;
295 symtab
->name_index_initialized
= 0;
298 /*******************************************************************************
299 *******************************************************************************/
301 kxld_symtab_deinit(KXLDSymtab
*symtab
)
305 kxld_array_deinit(&symtab
->syms
);
306 kxld_dict_deinit(&symtab
->cxx_index
);
307 kxld_dict_deinit(&symtab
->name_index
);
308 bzero(symtab
, sizeof(*symtab
));
311 /*******************************************************************************
312 *******************************************************************************/
314 kxld_symtab_get_num_symbols(const KXLDSymtab
*symtab
)
318 return symtab
->syms
.nitems
;
321 /*******************************************************************************
322 *******************************************************************************/
324 kxld_symtab_get_symbol_by_index(const KXLDSymtab
*symtab
, u_int idx
)
328 return kxld_array_get_item(&symtab
->syms
, idx
);
331 /*******************************************************************************
332 *******************************************************************************/
334 kxld_symtab_get_symbol_by_name(const KXLDSymtab
*symtab
, const char *name
)
339 for (i
= 0; i
< symtab
->syms
.nitems
; ++i
) {
340 sym
= kxld_array_get_item(&symtab
->syms
, i
);
342 if (streq(sym
->name
, name
)) {
350 /*******************************************************************************
351 *******************************************************************************/
353 kxld_symtab_get_locally_defined_symbol_by_name(const KXLDSymtab
*symtab
,
359 return kxld_dict_find(&symtab
->name_index
, name
);
362 /*******************************************************************************
363 *******************************************************************************/
365 kxld_symtab_get_cxx_symbol_by_value(const KXLDSymtab
*symtab
, kxld_addr_t value
)
369 return kxld_dict_find(&symtab
->cxx_index
, &value
);
372 /*******************************************************************************
373 *******************************************************************************/
375 kxld_symtab_get_sym_index(const KXLDSymtab
*symtab
, const KXLDSym
*sym
,
378 kern_return_t rval
= KERN_FAILURE
;
380 rval
= kxld_array_get_index(&symtab
->syms
, sym
, symindex
);
381 require_noerr(rval
, finish
);
389 /*******************************************************************************
390 *******************************************************************************/
392 kxld_symtab_get_macho_header_size(void)
394 return sizeof(struct symtab_command
);
397 /*******************************************************************************
398 *******************************************************************************/
400 kxld_symtab_get_macho_data_size(const KXLDSymtab
*symtab
, boolean_t is_32_bit
)
402 KXLDSymtabIterator iter
;
404 u_long size
= 1; /* strtab start padding */
409 kxld_symtab_iterator_init(&iter
, symtab
,
410 kxld_sym_is_defined_locally
, FALSE
);
412 while ((sym
= kxld_symtab_iterator_get_next(&iter
))) {
413 size
+= strlen(sym
->name
) + 1;
418 size
+= nsyms
* sizeof(struct nlist
);
420 size
+= nsyms
* sizeof(struct nlist_64
);
423 size
= (size
+ 7) & ~7;
428 /*******************************************************************************
429 *******************************************************************************/
431 kxld_symtab_export_macho(const KXLDSymtab
*symtab
, u_char
*buf
,
432 u_long
*header_offset
, u_long header_size
,
433 u_long
*data_offset
, u_long data_size
,
436 kern_return_t rval
= KERN_FAILURE
;
437 KXLDSymtabIterator iter
;
439 struct symtab_command
*symtabhdr
= NULL
;
441 u_long nlistsize
= 0;
443 u_long stroff
= 1; /* strtab start padding */
447 check(header_offset
);
450 require_action(sizeof(*symtabhdr
) <= header_size
- *header_offset
,
451 finish
, rval
= KERN_FAILURE
);
452 symtabhdr
= (struct symtab_command
*) ((void *) (buf
+ *header_offset
));
453 *header_offset
+= sizeof(*symtabhdr
);
455 /* Initialize the symbol table header */
457 // note - this assumes LC_SYMTAB is always before the LC_DYSYMTAB in the
458 // macho header we are processing.
459 symtabhdr
->cmd
= LC_SYMTAB
;
460 symtabhdr
->cmdsize
= (uint32_t) sizeof(*symtabhdr
);
461 symtabhdr
->symoff
= (uint32_t) *data_offset
;
462 symtabhdr
->strsize
= 1; /* strtab start padding */
464 /* Find the size of the symbol and string tables */
466 kxld_symtab_iterator_init(&iter
, symtab
,
467 kxld_sym_is_defined_locally
, FALSE
);
469 while ((sym
= kxld_symtab_iterator_get_next(&iter
))) {
471 symtabhdr
->strsize
+= (uint32_t) (strlen(sym
->name
) + 1);
475 nlistsize
= sizeof(struct nlist
);
477 nlistsize
= sizeof(struct nlist_64
);
480 symtabhdr
->stroff
= (uint32_t) (symtabhdr
->symoff
+
481 (symtabhdr
->nsyms
* nlistsize
));
482 require_action(symtabhdr
->stroff
+ symtabhdr
->strsize
<= data_size
, finish
,
483 rval
= KERN_FAILURE
);
485 /* Get pointers to the symbol and string tables */
486 nl
= buf
+ symtabhdr
->symoff
;
487 strtab
= (char *) (buf
+ symtabhdr
->stroff
);
489 /* Copy over the symbols */
491 kxld_symtab_iterator_reset(&iter
);
492 while ((sym
= kxld_symtab_iterator_get_next(&iter
))) {
493 KXLD_3264_FUNC(is_32_bit
, rval
,
494 kxld_sym_export_macho_32
, kxld_sym_export_macho_64
,
495 sym
, nl
, strtab
, &stroff
, symtabhdr
->strsize
);
496 require_noerr(rval
, finish
);
502 /* Update the data offset */
503 *data_offset
+= (symtabhdr
->nsyms
* nlistsize
) + stroff
;
505 *data_offset
= (*data_offset
+ 7) & ~7;
506 // at this point data_offset will be the offset just past the
507 // symbols and strings in the __LINKEDIT data
510 #if SPLIT_KEXTS_DEBUG
512 kxld_log(kKxldLogLinking
, kKxldLogErr
,
513 " %p to %p (size %lu) symtabhdr <%s>",
515 (void *) ((u_char
*)symtabhdr
+ sizeof(*symtabhdr
)),
519 kxld_log(kKxldLogLinking
, kKxldLogErr
,
520 " symtabhdr %p cmdsize %u symoff %u nsyms %u stroff %u strsize %u <%s>",
537 /*******************************************************************************
538 *******************************************************************************/
540 kxld_symtab_iterator_get_num_remaining(const KXLDSymtabIterator
*iter
)
547 for (idx
= iter
->idx
; idx
< iter
->symtab
->syms
.nitems
; ++idx
) {
548 count
+= iter
->test(kxld_array_get_item(&iter
->symtab
->syms
, idx
));
554 /*******************************************************************************
555 *******************************************************************************/
557 kxld_symtab_index_cxx_symbols_by_value(KXLDSymtab
*symtab
)
559 kern_return_t rval
= KERN_FAILURE
;
560 KXLDSymtabIterator iter
;
566 if (symtab
->cxx_index_initialized
) {
571 /* Count the number of C++ symbols */
572 kxld_symtab_iterator_init(&iter
, symtab
, sym_is_defined_cxx
, FALSE
);
573 nsyms
= kxld_symtab_iterator_get_num_remaining(&iter
);
575 /* Create the dictionary */
576 rval
= kxld_dict_init(&symtab
->cxx_index
, kxld_dict_kxldaddr_hash
,
577 kxld_dict_kxldaddr_cmp
, nsyms
);
578 require_noerr(rval
, finish
);
580 /* Insert the non-stab symbols */
581 while ((sym
= kxld_symtab_iterator_get_next(&iter
))) {
582 rval
= kxld_dict_insert(&symtab
->cxx_index
, &sym
->base_addr
, sym
);
583 require_noerr(rval
, finish
);
587 symtab
->cxx_index_initialized
= TRUE
;
593 /*******************************************************************************
594 *******************************************************************************/
596 sym_is_defined_cxx(const KXLDSym
*sym
)
598 return kxld_sym_is_defined_locally(sym
) && kxld_sym_is_cxx(sym
);
601 /*******************************************************************************
602 *******************************************************************************/
604 kxld_symtab_index_symbols_by_name(KXLDSymtab
*symtab
)
606 kern_return_t rval
= KERN_FAILURE
;
607 KXLDSymtabIterator iter
;
613 if (symtab
->name_index_initialized
) {
618 /* Count the number of symbols we need to index by name */
619 kxld_symtab_iterator_init(&iter
, symtab
, sym_is_name_indexed
, FALSE
);
620 nsyms
= kxld_symtab_iterator_get_num_remaining(&iter
);
622 /* Create the dictionary */
623 rval
= kxld_dict_init(&symtab
->name_index
, kxld_dict_string_hash
,
624 kxld_dict_string_cmp
, nsyms
);
625 require_noerr(rval
, finish
);
627 /* Insert the non-stab symbols */
628 while ((sym
= kxld_symtab_iterator_get_next(&iter
))) {
629 rval
= kxld_dict_insert(&symtab
->name_index
, sym
->name
, sym
);
630 require_noerr(rval
, finish
);
633 symtab
->name_index_initialized
= TRUE
;
639 /*******************************************************************************
640 *******************************************************************************/
642 sym_is_name_indexed(const KXLDSym
*sym
)
644 return kxld_sym_is_defined_locally(sym
) && !kxld_sym_is_stab(sym
);
647 /*******************************************************************************
648 *******************************************************************************/
650 kxld_symtab_relocate(KXLDSymtab
*symtab
, const KXLDArray
*sectarray
)
652 kern_return_t rval
= KERN_FAILURE
;
653 KXLDSymtabIterator iter
;
655 const KXLDSect
*sect
= NULL
;
660 kxld_symtab_iterator_init(&iter
, symtab
, kxld_sym_is_section
, FALSE
);
662 while ((sym
= kxld_symtab_iterator_get_next(&iter
))) {
663 sect
= kxld_array_get_item(sectarray
, sym
->sectnum
);
664 require_action(sect
, finish
, rval
= KERN_FAILURE
);
665 kxld_sym_relocate(sym
, sect
);
675 /*******************************************************************************
676 * This extends the symbol table and initializes the new symbol. We insert the
677 * symbol into the name index, but we don't bother with the c++ value index
678 * because it is based on the base_addr of the symbol, and the base_addr of
679 * all synthesized symbols will be 0.
680 *******************************************************************************/
682 kxld_symtab_add_symbol(KXLDSymtab
*symtab
, char *name
, kxld_addr_t link_addr
,
685 kern_return_t rval
= KERN_FAILURE
;
687 u_int symindex
= symtab
->syms
.nitems
;
689 rval
= kxld_array_resize(&symtab
->syms
, symindex
+ 1);
690 require_noerr(rval
, finish
);
692 sym
= kxld_array_get_item(&symtab
->syms
, symindex
);
693 kxld_sym_init_absolute(sym
, name
, link_addr
);
695 rval
= kxld_dict_insert(&symtab
->name_index
, sym
->name
, sym
);
696 require_noerr(rval
, finish
);
705 /*******************************************************************************
706 *******************************************************************************/
708 kxld_symtab_iterator_get_next(KXLDSymtabIterator
*iter
)
712 boolean_t cmp
= FALSE
;
716 for (; iter
->idx
< iter
->symtab
->syms
.nitems
; ++iter
->idx
) {
717 tmp
= kxld_array_get_item(&iter
->symtab
->syms
, iter
->idx
);
718 cmp
= iter
->test(tmp
);
734 /*******************************************************************************
735 *******************************************************************************/
737 kxld_symtab_iterator_reset(KXLDSymtabIterator
*iter
)