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@
30 #include <sys/types.h>
31 #include <mach-o/nlist.h>
32 #include <mach-o/stab.h>
34 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
35 #include <AssertMacros.h>
37 #include "kxld_sect.h"
39 #include "kxld_util.h"
41 #define CXX_PREFIX "__Z"
42 #define VTABLE_PREFIX CXX_PREFIX "TV"
43 #define OSOBJ_PREFIX CXX_PREFIX "N"
44 #define RESERVED_TOKEN "_RESERVED"
45 #define METACLASS_TOKEN "10gMetaClassE"
46 #define SUPER_METACLASS_POINTER_TOKEN "10superClassE"
47 #define METACLASS_VTABLE_PREFIX VTABLE_PREFIX "N"
48 #define METACLASS_VTABLE_SUFFIX "9MetaClassE"
49 #define CXX_PURE_VIRTUAL "___cxa_pure_virtual"
50 #define FINAL_CLASS_TOKEN "14__OSFinalClassEv"
52 /*******************************************************************************
54 *******************************************************************************/
56 static kern_return_t
init_predicates(KXLDSym
*sym
, u_char n_type
, u_short n_desc
)
57 __attribute__((nonnull
));
58 static void init_sym_sectnum(KXLDSym
*sym
, u_int n_sect
)
59 __attribute__((nonnull
));
60 static kern_return_t
extract_inner_string(const char *str
, const char *prefix
,
61 const char *suffix
, char *buf
, u_long len
);
63 #if KXLD_USER_OR_ILP32
64 /*******************************************************************************
65 *******************************************************************************/
67 kxld_sym_init_from_macho32(KXLDSym
*sym
, char *strtab
, const struct nlist
*src
)
69 kern_return_t rval
= KERN_FAILURE
;
75 bzero(sym
, sizeof(*sym
));
76 sym
->name
= strtab
+ src
->n_un
.n_strx
;
77 sym
->type
= src
->n_type
;
78 sym
->desc
= src
->n_desc
;
79 sym
->base_addr
= src
->n_value
;
80 sym
->link_addr
= sym
->base_addr
;
82 rval
= init_predicates(sym
, src
->n_type
, src
->n_desc
);
83 require_noerr(rval
, finish
);
85 (void) init_sym_sectnum(sym
, src
->n_sect
);
87 if (kxld_sym_is_indirect(sym
)) {
88 sym
->alias
= strtab
+ src
->n_value
;
96 #endif /* KXLD_USER_OR_ILP32 */
99 /*******************************************************************************
100 *******************************************************************************/
102 kxld_sym_init_from_macho64(KXLDSym
*sym
, char *strtab
, const struct nlist_64
*src
)
104 kern_return_t rval
= KERN_FAILURE
;
110 bzero(sym
, sizeof(*sym
));
111 sym
->name
= strtab
+ src
->n_un
.n_strx
;
112 sym
->type
= src
->n_type
;
113 sym
->desc
= src
->n_desc
;
114 sym
->base_addr
= src
->n_value
;
115 sym
->link_addr
= sym
->base_addr
;
117 rval
= init_predicates(sym
, src
->n_type
, src
->n_desc
);
118 require_noerr(rval
, finish
);
120 (void) init_sym_sectnum(sym
, src
->n_sect
);
122 if (kxld_sym_is_indirect(sym
)) {
123 sym
->alias
= strtab
+ src
->n_value
;
131 #endif /* KXLD_USER_OR_LP64 */
133 /*******************************************************************************
134 *******************************************************************************/
136 kxld_sym_init_absolute(KXLDSym
*sym
, char *name
, kxld_addr_t link_addr
)
141 bzero(sym
, sizeof(*sym
));
144 sym
->link_addr
= link_addr
;
145 sym
->type
= N_ABS
| N_EXT
;
146 sym
->sectnum
= NO_SECT
;
148 init_predicates(sym
, N_ABS
| N_EXT
, 0);
149 sym
->predicates
.is_resolved
= TRUE
;
152 /*******************************************************************************
153 *******************************************************************************/
155 init_predicates(KXLDSym
*sym
, u_char n_type
, u_short n_desc
)
157 kern_return_t rval
= KERN_FAILURE
;
161 /* The type field is interpreted differently for normal symbols and stabs */
162 if (n_type
& N_STAB
) {
163 sym
->predicates
.is_stab
= 1;
166 /* Labeled as NO_SECT in stab.h */
183 sym
->predicates
.is_absolute
= 1;
185 /* Labeled as n_sect in stab.h */
197 /* These are labeled as NO_SECT in stab.h, but they are actually
198 * section-based on OS X. We must mark them as such so they get
203 sym
->predicates
.is_section
= 1;
207 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
208 "Invalid N_STAB symbol type: %u.", n_type
);
212 /* Don't care about the C++ predicates for stabs */
215 u_char type
= n_type
& N_TYPE
;
217 /* Set the type-independent fields */
218 if ((n_type
& N_EXT
) && !(n_type
& N_PEXT
)) {
219 sym
->predicates
.is_external
= 1;
222 if (n_desc
& N_DESC_DISCARDED
) {
223 sym
->predicates
.is_obsolete
= 1;
226 if (n_desc
& N_WEAK_REF
) {
227 sym
->predicates
.is_weak
= 1;
230 if (n_desc
& N_ARM_THUMB_DEF
) {
231 sym
->predicates
.is_thumb
= 1;
234 /* The first set of type fields are mutually exclusive, so they can be
235 * set with a switch statement.
239 sym
->predicates
.is_absolute
= 1;
242 sym
->predicates
.is_section
= 1;
245 if (sym
->base_addr
) {
246 sym
->predicates
.is_common
= 1;
248 sym
->predicates
.is_undefined
= 1;
252 sym
->predicates
.is_indirect
= 1;
256 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
257 "Invalid symbol type: %u.", type
);
261 /* Set the C++-specific fields */
262 if ((0 == strncmp(CXX_PREFIX
, sym
->name
, const_strlen(CXX_PREFIX
)))) {
263 sym
->predicates
.is_cxx
= 1;
265 if (0 == strncmp(sym
->name
, METACLASS_VTABLE_PREFIX
,
266 const_strlen(METACLASS_VTABLE_PREFIX
)))
268 sym
->predicates
.is_meta_vtable
= 1;
269 } else if (0 == strncmp(sym
->name
, VTABLE_PREFIX
,
270 const_strlen(VTABLE_PREFIX
)))
272 sym
->predicates
.is_class_vtable
= 1;
273 } else if (kxld_strstr(sym
->name
, RESERVED_TOKEN
)) {
274 sym
->predicates
.is_padslot
= 1;
275 } else if (kxld_strstr(sym
->name
, METACLASS_TOKEN
)) {
276 sym
->predicates
.is_metaclass
= 1;
277 } else if (kxld_strstr(sym
->name
, SUPER_METACLASS_POINTER_TOKEN
)) {
278 sym
->predicates
.is_super_metaclass_pointer
= 1;
280 } else if (streq_safe(CXX_PURE_VIRTUAL
, sym
->name
, sizeof(CXX_PURE_VIRTUAL
))) {
281 sym
->predicates
.is_cxx
= 1;
282 sym
->predicates
.is_pure_virtual
= 1;
292 /*******************************************************************************
293 *******************************************************************************/
295 init_sym_sectnum(KXLDSym
*sym
, u_int n_sect
)
297 /* The n_sect field is set to 0 when the symbol is not section-based, and
298 * the number of the section in which the symbol exists otherwise.
299 * Sometimes, symbols can be labeled as section-based, so we make sure that
300 * they have a valid section number, and set them as absolute if they don't.
303 if (kxld_sym_is_section(sym
)) {
305 /* Convert the section number to an index into the section index */
306 sym
->sectnum
= n_sect
- 1;
308 sym
->predicates
.is_absolute
= 1;
309 sym
->predicates
.is_section
= 0;
315 /*******************************************************************************
316 *******************************************************************************/
318 kxld_sym_deinit(KXLDSym
*sym __unused
)
323 /*******************************************************************************
324 *******************************************************************************/
326 kxld_sym_destroy(KXLDSym
*sym
)
329 kxld_sym_deinit(sym
);
330 kxld_free(sym
, sizeof(*sym
));
334 /*******************************************************************************
335 *******************************************************************************/
337 kxld_sym_is_absolute(const KXLDSym
*sym
)
341 return (0 != sym
->predicates
.is_absolute
);
344 /*******************************************************************************
345 *******************************************************************************/
347 kxld_sym_is_section(const KXLDSym
*sym
)
351 return (0 != sym
->predicates
.is_section
);
354 /*******************************************************************************
355 *******************************************************************************/
357 kxld_sym_is_defined(const KXLDSym
*sym
)
361 return ((kxld_sym_is_absolute(sym
) || kxld_sym_is_section(sym
)) &&
362 !sym
->predicates
.is_replaced
);
366 /*******************************************************************************
367 *******************************************************************************/
369 kxld_sym_is_defined_locally(const KXLDSym
*sym
)
373 return (kxld_sym_is_defined(sym
) && !sym
->predicates
.is_resolved
);
376 /*******************************************************************************
377 *******************************************************************************/
379 kxld_sym_is_external(const KXLDSym
*sym
)
383 return (0 != sym
->predicates
.is_external
);
386 /*******************************************************************************
387 *******************************************************************************/
389 kxld_sym_is_exported(const KXLDSym
*sym
)
393 return (kxld_sym_is_defined_locally(sym
) && kxld_sym_is_external(sym
));
396 /*******************************************************************************
397 *******************************************************************************/
399 kxld_sym_is_undefined(const KXLDSym
*sym
)
403 return (0 != sym
->predicates
.is_undefined
);
406 /*******************************************************************************
407 *******************************************************************************/
409 kxld_sym_is_indirect(const KXLDSym
*sym
)
413 return (0 != sym
->predicates
.is_indirect
);
416 /*******************************************************************************
417 *******************************************************************************/
419 kxld_sym_is_common(const KXLDSym
*sym
)
423 return (0 != sym
->predicates
.is_common
);
426 /*******************************************************************************
427 *******************************************************************************/
429 kxld_sym_is_unresolved(const KXLDSym
*sym
)
431 return ((kxld_sym_is_undefined(sym
) && !sym
->predicates
.is_replaced
) ||
432 kxld_sym_is_indirect(sym
) || kxld_sym_is_common(sym
));
435 /*******************************************************************************
436 *******************************************************************************/
438 kxld_sym_is_obsolete(const KXLDSym
*sym
)
440 return (0 != sym
->predicates
.is_obsolete
);
444 /*******************************************************************************
445 *******************************************************************************/
447 kxld_sym_is_got(const KXLDSym
*sym
)
451 return (0 != sym
->predicates
.is_got
);
453 #endif /* KXLD_USER_OR_GOT */
455 /*******************************************************************************
456 *******************************************************************************/
458 kxld_sym_is_stab(const KXLDSym
*sym
)
462 return (0 != sym
->predicates
.is_stab
);
465 /*******************************************************************************
466 *******************************************************************************/
468 kxld_sym_is_weak(const KXLDSym
*sym
)
472 return (0 != sym
->predicates
.is_weak
);
475 /*******************************************************************************
476 *******************************************************************************/
478 kxld_sym_is_cxx(const KXLDSym
*sym
)
482 return (0 != sym
->predicates
.is_cxx
);
485 /*******************************************************************************
486 *******************************************************************************/
488 kxld_sym_is_pure_virtual(const KXLDSym
*sym
)
490 return (0 != sym
->predicates
.is_pure_virtual
);
493 /*******************************************************************************
494 *******************************************************************************/
496 kxld_sym_is_vtable(const KXLDSym
*sym
)
500 return kxld_sym_is_class_vtable(sym
) || kxld_sym_is_metaclass_vtable(sym
);
503 /*******************************************************************************
504 *******************************************************************************/
506 kxld_sym_is_class_vtable(const KXLDSym
*sym
)
510 return (0 != sym
->predicates
.is_class_vtable
);
513 /*******************************************************************************
514 *******************************************************************************/
516 kxld_sym_is_metaclass_vtable(const KXLDSym
*sym
)
520 return (0 != sym
->predicates
.is_meta_vtable
);
523 /*******************************************************************************
524 *******************************************************************************/
526 kxld_sym_is_padslot(const KXLDSym
*sym
)
530 return (0 != sym
->predicates
.is_padslot
);
533 /*******************************************************************************
534 *******************************************************************************/
536 kxld_sym_is_metaclass(const KXLDSym
*sym
)
540 return (0 != sym
->predicates
.is_metaclass
);
543 /*******************************************************************************
544 *******************************************************************************/
546 kxld_sym_is_super_metaclass_pointer(const KXLDSym
*sym
)
550 return (0 != sym
->predicates
.is_super_metaclass_pointer
);
553 /*******************************************************************************
554 *******************************************************************************/
556 kxld_sym_name_is_padslot(const char *name
)
560 return (kxld_strstr(name
, RESERVED_TOKEN
) != 0);
563 /*******************************************************************************
564 *******************************************************************************/
566 kxld_sym_get_section_offset(const KXLDSym
*sym
, const KXLDSect
*sect
)
570 return (u_int
) (sym
->base_addr
- sect
->base_addr
);
573 #if KXLD_USER_OR_COMMON
574 /*******************************************************************************
575 *******************************************************************************/
577 kxld_sym_get_common_size(const KXLDSym
*sym
)
579 return sym
->base_addr
;
582 /*******************************************************************************
583 *******************************************************************************/
585 kxld_sym_get_common_align(const KXLDSym
*sym
)
587 u_int align
= GET_COMM_ALIGN(sym
->desc
);
588 if (!align
) align
= 3;
592 #endif /* KXLD_USER_OR_COMMON */
594 /*******************************************************************************
595 *******************************************************************************/
597 kxld_sym_get_class_name_from_metaclass(const KXLDSym
*sym
,
598 char class_name
[], u_long class_name_len
)
600 kern_return_t rval
= KERN_FAILURE
;
603 require_action(kxld_sym_is_metaclass(sym
), finish
, rval
=KERN_FAILURE
);
605 rval
= extract_inner_string(sym
->name
, OSOBJ_PREFIX
, METACLASS_TOKEN
,
606 class_name
, class_name_len
);
607 require_noerr(rval
, finish
);
614 /*******************************************************************************
615 *******************************************************************************/
617 kxld_sym_get_class_name_from_super_metaclass_pointer(const KXLDSym
*sym
,
618 char class_name
[], u_long class_name_len
)
620 kern_return_t rval
= KERN_FAILURE
;
623 require_action(kxld_sym_is_super_metaclass_pointer(sym
), finish
,
626 rval
= extract_inner_string(sym
->name
, OSOBJ_PREFIX
,
627 SUPER_METACLASS_POINTER_TOKEN
, class_name
, class_name_len
);
628 require_noerr(rval
, finish
);
635 /*******************************************************************************
636 *******************************************************************************/
638 kxld_sym_get_class_name_from_vtable(const KXLDSym
*sym
,
639 char class_name
[], u_long class_name_len
)
641 kern_return_t rval
= KERN_FAILURE
;
644 require_action(kxld_sym_is_class_vtable(sym
), finish
, rval
=KERN_FAILURE
);
646 rval
= kxld_sym_get_class_name_from_vtable_name(sym
->name
,
647 class_name
, class_name_len
);
648 require_noerr(rval
, finish
);
656 /*******************************************************************************
657 *******************************************************************************/
659 kxld_sym_get_class_name_from_vtable_name(const char *vtable_name
,
660 char class_name
[], u_long class_name_len
)
662 kern_return_t rval
= KERN_FAILURE
;
666 rval
= extract_inner_string(vtable_name
, VTABLE_PREFIX
, NULL
,
667 class_name
, class_name_len
);
668 require_noerr(rval
, finish
);
675 /*******************************************************************************
676 *******************************************************************************/
678 kxld_sym_get_vtable_name_from_class_name(const char *class_name
,
679 char vtable_name
[], u_long vtable_name_len
)
681 kern_return_t rval
= KERN_FAILURE
;
687 outlen
= strlcpy(vtable_name
, VTABLE_PREFIX
, vtable_name_len
);
688 require_action(outlen
< vtable_name_len
, finish
,
691 outlen
= strlcat(vtable_name
, class_name
, vtable_name_len
);
692 require_action(outlen
< vtable_name_len
, finish
,
700 /*******************************************************************************
701 *******************************************************************************/
703 kxld_sym_get_meta_vtable_name_from_class_name(const char *class_name
,
704 char meta_vtable_name
[], u_long meta_vtable_name_len
)
706 kern_return_t rval
= KERN_FAILURE
;
710 check(meta_vtable_name
);
712 outlen
= strlcpy(meta_vtable_name
, METACLASS_VTABLE_PREFIX
,
713 meta_vtable_name_len
);
714 require_action(outlen
< meta_vtable_name_len
, finish
,
717 outlen
= strlcat(meta_vtable_name
, class_name
, meta_vtable_name_len
);
718 require_action(outlen
< meta_vtable_name_len
, finish
,
721 outlen
= strlcat(meta_vtable_name
, METACLASS_VTABLE_SUFFIX
,
722 meta_vtable_name_len
);
723 require_action(outlen
< meta_vtable_name_len
, finish
,
731 /*******************************************************************************
732 *******************************************************************************/
734 kxld_sym_get_final_sym_name_from_class_name(const char *class_name
,
735 char final_sym_name
[], u_long final_sym_name_len
)
737 kern_return_t rval
= KERN_FAILURE
;
741 check(final_sym_name
);
743 outlen
= strlcpy(final_sym_name
, OSOBJ_PREFIX
, final_sym_name_len
);
744 require_action(outlen
< final_sym_name_len
, finish
,
747 outlen
= strlcat(final_sym_name
, class_name
, final_sym_name_len
);
748 require_action(outlen
< final_sym_name_len
, finish
,
751 outlen
= strlcat(final_sym_name
, FINAL_CLASS_TOKEN
, final_sym_name_len
);
752 require_action(outlen
< final_sym_name_len
, finish
,
761 /*******************************************************************************
762 *******************************************************************************/
764 kxld_sym_get_function_prefix_from_class_name(const char *class_name
,
765 char function_prefix
[], u_long function_prefix_len
)
771 check(function_prefix
);
773 outlen
= strlcpy(function_prefix
, OSOBJ_PREFIX
, function_prefix_len
);
774 require(outlen
< function_prefix_len
, finish
);
776 outlen
= strlcat(function_prefix
, class_name
, function_prefix_len
);
777 require(outlen
< function_prefix_len
, finish
);
784 /*******************************************************************************
785 *******************************************************************************/
787 extract_inner_string(const char *str
, const char *prefix
, const char *suffix
,
788 char *buf
, u_long len
)
790 kern_return_t rval
= KERN_FAILURE
;
791 u_long prelen
= 0, suflen
= 0, striplen
= 0;
796 prelen
= (prefix
) ? strlen(prefix
) : 0;
797 suflen
= (suffix
) ? strlen(suffix
) : 0;
798 striplen
= strlen(str
) - prelen
- suflen
;
800 require_action(striplen
< len
, finish
, rval
=KERN_FAILURE
);
802 strncpy(buf
, str
+ prelen
, striplen
);
803 buf
[striplen
] = '\0';
811 /*******************************************************************************
812 *******************************************************************************/
814 kxld_sym_set_got(KXLDSym
*sym
)
816 sym
->predicates
.is_got
= 1;
818 #endif /* KXLD_USER_OR_GOT */
820 /*******************************************************************************
821 *******************************************************************************/
823 kxld_sym_relocate(KXLDSym
*sym
, const KXLDSect
*sect
)
825 if (kxld_sym_is_section(sym
)) {
826 sym
->link_addr
= sym
->base_addr
- sect
->base_addr
+ sect
->link_addr
;
827 sym
->relocated_sectnum
= sect
->sectnum
;
831 #if KXLD_USER_OR_ILP32
832 /*******************************************************************************
833 *******************************************************************************/
835 kxld_sym_export_macho_32(const KXLDSym
*sym
, u_char
*_nl
, char *strtab
,
836 u_long
*stroff
, u_long strsize
, boolean_t is_link_state
)
838 kern_return_t rval
= KERN_FAILURE
;
839 struct nlist
*nl
= (struct nlist
*) _nl
;
848 bytes
= strlen(sym
->name
) + 1;
849 require_action((u_long
)bytes
<= strsize
- *stroff
, finish
,
850 rval
= KERN_FAILURE
);
853 nl
->n_type
= N_ABS
| N_EXT
;
854 nl
->n_sect
= NO_SECT
;
857 nl
->n_type
= sym
->type
;
858 nl
->n_sect
= (kxld_sym_is_section(sym
)) ? sym
->relocated_sectnum
+ 1 : 0;
859 nl
->n_desc
= sym
->desc
;
861 nl
->n_un
.n_strx
= (uint32_t) *stroff
;
862 nl
->n_value
= (uint32_t) sym
->link_addr
;
864 str
= (char *) (strtab
+ *stroff
);
865 strlcpy(str
, sym
->name
, strsize
- *stroff
);
873 #endif /* KXLD_USER_OR_ILP32 */
875 #if KXLD_USER_OR_LP64
876 /*******************************************************************************
877 *******************************************************************************/
879 kxld_sym_export_macho_64(const KXLDSym
*sym
, u_char
*_nl
, char *strtab
,
880 u_long
*stroff
, u_long strsize
, boolean_t is_link_state
)
882 kern_return_t rval
= KERN_FAILURE
;
883 struct nlist_64
*nl
= (struct nlist_64
*) _nl
;
892 bytes
= strlen(sym
->name
) + 1;
893 require_action((u_long
)bytes
<= strsize
- *stroff
, finish
,
894 rval
= KERN_FAILURE
);
897 nl
->n_type
= N_ABS
| N_EXT
;
898 nl
->n_sect
= NO_SECT
;
901 nl
->n_type
= sym
->type
;
902 nl
->n_sect
= (kxld_sym_is_section(sym
)) ? sym
->relocated_sectnum
+ 1 : 0;
903 nl
->n_desc
= sym
->desc
;
905 nl
->n_un
.n_strx
= (uint32_t) *stroff
;
906 nl
->n_value
= (uint64_t) sym
->link_addr
;
908 str
= (char *) (strtab
+ *stroff
);
909 strlcpy(str
, sym
->name
, strsize
- *stroff
);
917 #endif /* KXLD_USER_OR_LP64 */
919 /*******************************************************************************
920 *******************************************************************************/
922 kxld_sym_resolve(KXLDSym
*sym
, kxld_addr_t addr
, boolean_t export_sym
)
924 kern_return_t rval
= KERN_FAILURE
;
928 require_action(kxld_sym_is_undefined(sym
) || kxld_sym_is_indirect(sym
),
929 finish
, rval
=KERN_FAILURE
);
931 /* Set the n_list data types */
933 sym
->link_addr
= addr
;
934 sym
->type
= N_ABS
| N_EXT
;
935 sym
->sectnum
= NO_SECT
;
937 /* Set the predicate bits for an externally resolved symbol. We re-export
938 * indirect symbols and any symbols that the caller wants re-exported (for
939 * example, symbols from a pseudo-kext). */
941 sym
->predicates
.is_external
= TRUE
;
942 sym
->predicates
.is_absolute
= TRUE
;
943 sym
->predicates
.is_resolved
= !(kxld_sym_is_indirect(sym
) || export_sym
);
945 /* Clear the predicate bits for types that can be resolved */
947 sym
->predicates
.is_undefined
= FALSE
;
948 sym
->predicates
.is_indirect
= FALSE
;
957 #if KXLD_USER_OR_COMMON
958 /*******************************************************************************
959 *******************************************************************************/
961 kxld_sym_resolve_common(KXLDSym
*sym
, u_int sectnum
, kxld_addr_t base_addr
)
963 kern_return_t rval
= KERN_FAILURE
;
967 require_action(kxld_sym_is_common(sym
), finish
,
970 sym
->base_addr
= base_addr
;
971 sym
->link_addr
= base_addr
;
972 sym
->type
= N_SECT
| N_EXT
;
973 sym
->sectnum
= sectnum
;
976 sym
->predicates
.is_absolute
= FALSE
;
977 sym
->predicates
.is_section
= TRUE
;
978 sym
->predicates
.is_undefined
= FALSE
;
979 sym
->predicates
.is_indirect
= FALSE
;
980 sym
->predicates
.is_common
= FALSE
;
981 sym
->predicates
.is_external
= TRUE
;
989 #endif /* KXLD_USER_OR_COMMON */
991 /*******************************************************************************
992 *******************************************************************************/
994 kxld_sym_delete(KXLDSym
*sym
)
998 bzero(sym
, sizeof(*sym
));
999 sym
->predicates
.is_replaced
= TRUE
;
1003 /*******************************************************************************
1004 *******************************************************************************/
1006 kxld_sym_patch(KXLDSym
*sym
)
1010 sym
->predicates
.is_replaced
= TRUE
;
1013 /*******************************************************************************
1014 *******************************************************************************/
1016 kxld_sym_mark_private(KXLDSym
*sym
)
1020 sym
->type
|= N_PEXT
;
1021 sym
->predicates
.is_external
= FALSE
;