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 if (!strcmp("__ZN15OSMetaClassBase25_RESERVEDOSMetaClassBase3Ev", sym
->name
)) {
118 sym
->name
= (char *)(uintptr_t) "__ZN15OSMetaClassBase8DispatchE5IORPC";
121 rval
= init_predicates(sym
, src
->n_type
, src
->n_desc
);
122 require_noerr(rval
, finish
);
124 (void) init_sym_sectnum(sym
, src
->n_sect
);
126 if (kxld_sym_is_indirect(sym
)) {
127 sym
->alias
= strtab
+ src
->n_value
;
135 #endif /* KXLD_USER_OR_LP64 */
137 /*******************************************************************************
138 *******************************************************************************/
140 kxld_sym_init_absolute(KXLDSym
*sym
, char *name
, kxld_addr_t link_addr
)
145 bzero(sym
, sizeof(*sym
));
148 sym
->link_addr
= link_addr
;
149 sym
->type
= N_ABS
| N_EXT
;
150 sym
->sectnum
= NO_SECT
;
152 init_predicates(sym
, N_ABS
| N_EXT
, 0);
153 sym
->is_resolved
= TRUE
;
156 /*******************************************************************************
157 *******************************************************************************/
159 init_predicates(KXLDSym
*sym
, u_char n_type
, u_short n_desc
)
161 kern_return_t rval
= KERN_FAILURE
;
165 /* The type field is interpreted differently for normal symbols and stabs */
166 if (n_type
& N_STAB
) {
170 /* Labeled as NO_SECT in stab.h */
187 sym
->is_absolute
= 1;
189 /* Labeled as n_sect in stab.h */
201 /* These are labeled as NO_SECT in stab.h, but they are actually
202 * section-based on OS X. We must mark them as such so they get
211 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
212 "Invalid N_STAB symbol type: %u.", n_type
);
216 /* Don't care about the C++ predicates for stabs */
218 u_char type
= n_type
& N_TYPE
;
220 /* The first set of type fields are mutually exclusive, so they can be
221 * set with a switch statement.
225 sym
->is_absolute
= 1;
231 if (sym
->base_addr
) {
234 sym
->is_undefined
= 1;
238 sym
->is_indirect
= 1;
242 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
243 "Invalid symbol type: %u.", type
);
247 /* Set the type-independent fields */
248 if ((n_type
& N_EXT
) && !(n_type
& N_PEXT
)) {
249 sym
->is_external
= 1;
252 if (n_desc
& N_DESC_DISCARDED
) {
253 sym
->is_obsolete
= 1;
256 if (n_desc
& N_WEAK_REF
) {
260 if (n_desc
& N_ARM_THUMB_DEF
) {
266 /* Set the C++-specific fields */
267 if (!strncmp(CXX_PREFIX
, sym
->name
, const_strlen(CXX_PREFIX
))) {
270 if (streq_safe(sym
->name
, METACLASS_VTABLE_PREFIX
,
271 const_strlen(METACLASS_VTABLE_PREFIX
))) {
272 sym
->is_meta_vtable
= 1;
273 } else if (streq_safe(sym
->name
, VTABLE_PREFIX
,
274 const_strlen(VTABLE_PREFIX
))) {
275 sym
->is_class_vtable
= 1;
276 } else if (strnstr(sym
->name
, RESERVED_TOKEN
, strlen(sym
->name
))) {
278 } else if (strnstr(sym
->name
, METACLASS_TOKEN
, strlen(sym
->name
))) {
279 sym
->is_metaclass
= 1;
280 } else if (strnstr(sym
->name
, SUPER_METACLASS_POINTER_TOKEN
, strlen(sym
->name
))) {
281 sym
->is_super_metaclass_pointer
= 1;
283 } else if (kxld_sym_name_is_pure_virtual(sym
->name
)) {
285 sym
->is_pure_virtual
= 1;
295 /*******************************************************************************
296 *******************************************************************************/
298 init_sym_sectnum(KXLDSym
*sym
, u_int n_sect
)
300 /* The n_sect field is set to 0 when the symbol is not section-based, and
301 * the number of the section in which the symbol exists otherwise.
302 * Sometimes, symbols can be labeled as section-based, so we make sure that
303 * they have a valid section number, and set them as absolute if they don't.
306 if (kxld_sym_is_section(sym
)) {
308 /* Convert the section number to an index into the section index */
309 sym
->sectnum
= n_sect
- 1;
311 sym
->is_absolute
= 1;
317 /*******************************************************************************
318 *******************************************************************************/
320 kxld_sym_deinit(KXLDSym
*sym __unused
)
325 /*******************************************************************************
326 *******************************************************************************/
328 kxld_sym_destroy(KXLDSym
*sym
)
331 kxld_sym_deinit(sym
);
332 kxld_free(sym
, sizeof(*sym
));
336 /*******************************************************************************
337 *******************************************************************************/
339 kxld_sym_is_absolute(const KXLDSym
*sym
)
343 return 0 != sym
->is_absolute
;
346 /*******************************************************************************
347 *******************************************************************************/
349 kxld_sym_is_section(const KXLDSym
*sym
)
353 return 0 != sym
->is_section
;
356 /*******************************************************************************
357 *******************************************************************************/
359 kxld_sym_is_defined(const KXLDSym
*sym
)
363 return (kxld_sym_is_absolute(sym
) || kxld_sym_is_section(sym
)) &&
364 !kxld_sym_is_replaced(sym
);
368 /*******************************************************************************
369 *******************************************************************************/
371 kxld_sym_is_defined_locally(const KXLDSym
*sym
)
375 return kxld_sym_is_defined(sym
) && !sym
->is_resolved
;
378 /*******************************************************************************
379 *******************************************************************************/
381 kxld_sym_is_external(const KXLDSym
*sym
)
385 return 0 != sym
->is_external
;
388 /*******************************************************************************
389 *******************************************************************************/
391 kxld_sym_is_exported(const KXLDSym
*sym
)
395 return kxld_sym_is_defined_locally(sym
) && kxld_sym_is_external(sym
);
398 /*******************************************************************************
399 *******************************************************************************/
401 kxld_sym_is_undefined(const KXLDSym
*sym
)
405 return 0 != sym
->is_undefined
;
408 /*******************************************************************************
409 *******************************************************************************/
411 kxld_sym_is_indirect(const KXLDSym
*sym
)
415 return 0 != sym
->is_indirect
;
418 /*******************************************************************************
419 *******************************************************************************/
421 kxld_sym_is_replaced(const KXLDSym
*sym
)
425 return 0 != sym
->is_replaced
;
428 /*******************************************************************************
429 *******************************************************************************/
431 kxld_sym_is_common(const KXLDSym
*sym
)
435 return 0 != sym
->is_common
;
438 /*******************************************************************************
439 *******************************************************************************/
441 kxld_sym_is_unresolved(const KXLDSym
*sym
)
443 return (kxld_sym_is_undefined(sym
) && !kxld_sym_is_replaced(sym
)) ||
444 kxld_sym_is_indirect(sym
) || kxld_sym_is_common(sym
);
447 /*******************************************************************************
448 *******************************************************************************/
450 kxld_sym_is_obsolete(const KXLDSym
*sym
)
452 return 0 != sym
->is_obsolete
;
456 /*******************************************************************************
457 *******************************************************************************/
459 kxld_sym_is_got(const KXLDSym
*sym
)
463 return 0 != sym
->is_got
;
465 #endif /* KXLD_USER_OR_GOT */
467 /*******************************************************************************
468 *******************************************************************************/
470 kxld_sym_is_stab(const KXLDSym
*sym
)
474 return 0 != sym
->is_stab
;
477 /*******************************************************************************
478 *******************************************************************************/
480 kxld_sym_is_weak(const KXLDSym
*sym
)
484 return 0 != sym
->is_weak
;
487 /*******************************************************************************
488 *******************************************************************************/
490 kxld_sym_is_cxx(const KXLDSym
*sym
)
494 return 0 != sym
->is_cxx
;
497 /*******************************************************************************
498 *******************************************************************************/
500 kxld_sym_is_pure_virtual(const KXLDSym
*sym
)
502 return 0 != sym
->is_pure_virtual
;
505 /*******************************************************************************
506 *******************************************************************************/
508 kxld_sym_is_vtable(const KXLDSym
*sym
)
512 return kxld_sym_is_class_vtable(sym
) || kxld_sym_is_metaclass_vtable(sym
);
515 /*******************************************************************************
516 *******************************************************************************/
518 kxld_sym_is_class_vtable(const KXLDSym
*sym
)
522 return 0 != sym
->is_class_vtable
;
525 /*******************************************************************************
526 *******************************************************************************/
528 kxld_sym_is_metaclass_vtable(const KXLDSym
*sym
)
532 return 0 != sym
->is_meta_vtable
;
535 /*******************************************************************************
536 *******************************************************************************/
538 kxld_sym_is_padslot(const KXLDSym
*sym
)
542 return 0 != sym
->is_padslot
;
545 /*******************************************************************************
546 *******************************************************************************/
548 kxld_sym_is_metaclass(const KXLDSym
*sym
)
552 return 0 != sym
->is_metaclass
;
555 /*******************************************************************************
556 *******************************************************************************/
558 kxld_sym_is_super_metaclass_pointer(const KXLDSym
*sym
)
562 return 0 != sym
->is_super_metaclass_pointer
;
565 /*******************************************************************************
566 *******************************************************************************/
568 kxld_sym_name_is_pure_virtual(const char *name
)
570 return streq_safe(CXX_PURE_VIRTUAL
, name
, sizeof(CXX_PURE_VIRTUAL
));
573 /*******************************************************************************
574 *******************************************************************************/
576 kxld_sym_name_is_padslot(const char *name
)
580 return strnstr(name
, RESERVED_TOKEN
, strlen(name
)) != 0;
583 /*******************************************************************************
584 *******************************************************************************/
586 kxld_sym_get_section_offset(const KXLDSym
*sym
, const KXLDSect
*sect
)
590 return (u_int
) (sym
->base_addr
- sect
->base_addr
);
593 #if KXLD_USER_OR_COMMON
594 /*******************************************************************************
595 *******************************************************************************/
597 kxld_sym_get_common_size(const KXLDSym
*sym
)
599 return sym
->base_addr
;
602 /*******************************************************************************
603 *******************************************************************************/
605 kxld_sym_get_common_align(const KXLDSym
*sym
)
607 u_int align
= GET_COMM_ALIGN(sym
->desc
);
614 #endif /* KXLD_USER_OR_COMMON */
616 /*******************************************************************************
617 *******************************************************************************/
619 kxld_sym_get_class_name_from_metaclass(const KXLDSym
*sym
,
620 char class_name
[], u_long class_name_len
)
622 kern_return_t rval
= KERN_FAILURE
;
625 require_action(kxld_sym_is_metaclass(sym
), finish
, rval
= KERN_FAILURE
);
627 rval
= extract_inner_string(sym
->name
, OSOBJ_PREFIX
, METACLASS_TOKEN
,
628 class_name
, class_name_len
);
629 require_noerr(rval
, finish
);
636 /*******************************************************************************
637 *******************************************************************************/
639 kxld_sym_get_class_name_from_super_metaclass_pointer(const KXLDSym
*sym
,
640 char class_name
[], u_long class_name_len
)
642 kern_return_t rval
= KERN_FAILURE
;
645 require_action(kxld_sym_is_super_metaclass_pointer(sym
), finish
,
646 rval
= KERN_FAILURE
);
648 rval
= extract_inner_string(sym
->name
, OSOBJ_PREFIX
,
649 SUPER_METACLASS_POINTER_TOKEN
, class_name
, class_name_len
);
650 require_noerr(rval
, finish
);
657 /*******************************************************************************
658 *******************************************************************************/
660 kxld_sym_get_class_name_from_vtable(const KXLDSym
*sym
,
661 char class_name
[], u_long class_name_len
)
663 kern_return_t rval
= KERN_FAILURE
;
666 require_action(kxld_sym_is_class_vtable(sym
), finish
, rval
= KERN_FAILURE
);
668 rval
= kxld_sym_get_class_name_from_vtable_name(sym
->name
,
669 class_name
, class_name_len
);
670 require_noerr(rval
, finish
);
678 /*******************************************************************************
679 *******************************************************************************/
681 kxld_sym_get_class_name_from_vtable_name(const char *vtable_name
,
682 char class_name
[], u_long class_name_len
)
684 kern_return_t rval
= KERN_FAILURE
;
688 rval
= extract_inner_string(vtable_name
, VTABLE_PREFIX
, NULL
,
689 class_name
, class_name_len
);
690 require_noerr(rval
, finish
);
697 /*******************************************************************************
698 *******************************************************************************/
700 kxld_sym_get_vtable_name_from_class_name(const char *class_name
,
701 char vtable_name
[], u_long vtable_name_len
)
703 kern_return_t rval
= KERN_FAILURE
;
709 outlen
= strlcpy(vtable_name
, VTABLE_PREFIX
, vtable_name_len
);
710 require_action(outlen
< vtable_name_len
, finish
,
711 rval
= KERN_FAILURE
);
713 outlen
= strlcat(vtable_name
, class_name
, vtable_name_len
);
714 require_action(outlen
< vtable_name_len
, finish
,
715 rval
= KERN_FAILURE
);
722 /*******************************************************************************
723 *******************************************************************************/
725 kxld_sym_get_meta_vtable_name_from_class_name(const char *class_name
,
726 char meta_vtable_name
[], u_long meta_vtable_name_len
)
728 kern_return_t rval
= KERN_FAILURE
;
732 check(meta_vtable_name
);
734 outlen
= strlcpy(meta_vtable_name
, METACLASS_VTABLE_PREFIX
,
735 meta_vtable_name_len
);
736 require_action(outlen
< meta_vtable_name_len
, finish
,
737 rval
= KERN_FAILURE
);
739 outlen
= strlcat(meta_vtable_name
, class_name
, meta_vtable_name_len
);
740 require_action(outlen
< meta_vtable_name_len
, finish
,
741 rval
= KERN_FAILURE
);
743 outlen
= strlcat(meta_vtable_name
, METACLASS_VTABLE_SUFFIX
,
744 meta_vtable_name_len
);
745 require_action(outlen
< meta_vtable_name_len
, finish
,
746 rval
= KERN_FAILURE
);
753 /*******************************************************************************
754 *******************************************************************************/
756 kxld_sym_get_final_sym_name_from_class_name(const char *class_name
,
757 char final_sym_name
[], u_long final_sym_name_len
)
759 kern_return_t rval
= KERN_FAILURE
;
763 check(final_sym_name
);
765 outlen
= strlcpy(final_sym_name
, OSOBJ_PREFIX
, final_sym_name_len
);
766 require_action(outlen
< final_sym_name_len
, finish
,
767 rval
= KERN_FAILURE
);
769 outlen
= strlcat(final_sym_name
, class_name
, final_sym_name_len
);
770 require_action(outlen
< final_sym_name_len
, finish
,
771 rval
= KERN_FAILURE
);
773 outlen
= strlcat(final_sym_name
, FINAL_CLASS_TOKEN
, final_sym_name_len
);
774 require_action(outlen
< final_sym_name_len
, finish
,
775 rval
= KERN_FAILURE
);
783 /*******************************************************************************
784 *******************************************************************************/
786 kxld_sym_get_function_prefix_from_class_name(const char *class_name
,
787 char function_prefix
[], u_long function_prefix_len
)
793 check(function_prefix
);
795 outlen
= strlcpy(function_prefix
, OSOBJ_PREFIX
, function_prefix_len
);
796 require(outlen
< function_prefix_len
, finish
);
798 outlen
= strlcat(function_prefix
, class_name
, function_prefix_len
);
799 require(outlen
< function_prefix_len
, finish
);
806 /*******************************************************************************
807 *******************************************************************************/
809 extract_inner_string(const char *str
, const char *prefix
, const char *suffix
,
810 char *buf
, u_long len
)
812 kern_return_t rval
= KERN_FAILURE
;
813 u_long prelen
= 0, suflen
= 0, striplen
= 0;
818 prelen
= (prefix
) ? strlen(prefix
) : 0;
819 suflen
= (suffix
) ? strlen(suffix
) : 0;
820 striplen
= strlen(str
) - prelen
- suflen
;
822 require_action(striplen
< len
, finish
, rval
= KERN_FAILURE
);
824 strncpy(buf
, str
+ prelen
, striplen
);
825 buf
[striplen
] = '\0';
833 /*******************************************************************************
834 *******************************************************************************/
836 kxld_sym_set_got(KXLDSym
*sym
)
840 #endif /* KXLD_USER_OR_GOT */
842 /*******************************************************************************
843 *******************************************************************************/
845 kxld_sym_relocate(KXLDSym
*sym
, const KXLDSect
*sect
)
847 if (kxld_sym_is_section(sym
)) {
848 sym
->link_addr
= sym
->base_addr
- sect
->base_addr
+ sect
->link_addr
;
849 sym
->relocated_sectnum
= sect
->sectnum
;
853 #if KXLD_USER_OR_ILP32
854 /*******************************************************************************
855 *******************************************************************************/
857 kxld_sym_export_macho_32(const KXLDSym
*sym
, u_char
*_nl
, char *strtab
,
858 u_long
*stroff
, u_long strsize
)
860 kern_return_t rval
= KERN_FAILURE
;
861 struct nlist
*nl
= (struct nlist
*) ((void *) _nl
);
870 bytes
= strlen(sym
->name
) + 1;
871 require_action((u_long
)bytes
<= strsize
- *stroff
, finish
,
872 rval
= KERN_FAILURE
);
874 nl
->n_type
= sym
->type
;
875 nl
->n_sect
= (kxld_sym_is_section(sym
)) ? sym
->relocated_sectnum
+ 1 : 0;
876 nl
->n_desc
= sym
->desc
;
877 nl
->n_un
.n_strx
= (uint32_t) *stroff
;
878 nl
->n_value
= (uint32_t) sym
->link_addr
;
880 nl
->n_value
&= ~0x1U
;
883 str
= (char *) (strtab
+ *stroff
);
884 strlcpy(str
, sym
->name
, strsize
- *stroff
);
892 #endif /* KXLD_USER_OR_ILP32 */
894 #if KXLD_USER_OR_LP64
895 /*******************************************************************************
896 *******************************************************************************/
898 kxld_sym_export_macho_64(const KXLDSym
*sym
, u_char
*_nl
, char *strtab
,
899 u_long
*stroff
, u_long strsize
)
901 kern_return_t rval
= KERN_FAILURE
;
902 struct nlist_64
*nl
= (struct nlist_64
*) ((void *) _nl
);
911 bytes
= strlen(sym
->name
) + 1;
912 require_action((u_long
)bytes
<= strsize
- *stroff
, finish
,
913 rval
= KERN_FAILURE
);
915 nl
->n_type
= sym
->type
;
916 nl
->n_sect
= (kxld_sym_is_section(sym
)) ? sym
->relocated_sectnum
+ 1 : 0;
917 nl
->n_desc
= sym
->desc
;
918 nl
->n_un
.n_strx
= (uint32_t) *stroff
;
919 nl
->n_value
= (uint64_t) sym
->link_addr
;
921 nl
->n_value
&= ~0x1ULL
;
924 str
= (char *) (strtab
+ *stroff
);
926 strlcpy(str
, sym
->name
, strsize
- *stroff
);
935 #endif /* KXLD_USER_OR_LP64 */
937 /*******************************************************************************
938 *******************************************************************************/
940 kxld_sym_resolve(KXLDSym
*sym
, kxld_addr_t addr
)
942 kern_return_t rval
= KERN_FAILURE
;
946 require_action(kxld_sym_is_undefined(sym
) || kxld_sym_is_indirect(sym
),
947 finish
, rval
= KERN_FAILURE
);
949 /* Set the n_list data types */
951 sym
->link_addr
= addr
;
952 sym
->type
= N_ABS
| N_EXT
;
953 sym
->sectnum
= NO_SECT
;
955 /* Set the predicate bits for an externally resolved symbol. */
957 sym
->is_external
= TRUE
;
958 sym
->is_absolute
= TRUE
;
959 sym
->is_resolved
= TRUE
;
961 /* Clear the predicate bits for types that can be resolved */
963 sym
->is_undefined
= FALSE
;
964 sym
->is_indirect
= FALSE
;
973 #if KXLD_USER_OR_COMMON
974 /*******************************************************************************
975 *******************************************************************************/
977 kxld_sym_resolve_common(KXLDSym
*sym
, u_int sectnum
, kxld_addr_t base_addr
)
979 kern_return_t rval
= KERN_FAILURE
;
983 require_action(kxld_sym_is_common(sym
), finish
,
984 rval
= KERN_FAILURE
);
986 sym
->base_addr
= base_addr
;
987 sym
->link_addr
= base_addr
;
988 sym
->type
= N_SECT
| N_EXT
;
989 sym
->sectnum
= sectnum
;
992 sym
->is_absolute
= FALSE
;
993 sym
->is_section
= TRUE
;
994 sym
->is_undefined
= FALSE
;
995 sym
->is_indirect
= FALSE
;
996 sym
->is_common
= FALSE
;
997 sym
->is_external
= TRUE
;
1005 #endif /* KXLD_USER_OR_COMMON */
1007 /*******************************************************************************
1008 *******************************************************************************/
1010 kxld_sym_delete(KXLDSym
*sym
)
1014 bzero(sym
, sizeof(*sym
));
1015 sym
->is_replaced
= TRUE
;
1019 /*******************************************************************************
1020 *******************************************************************************/
1022 kxld_sym_patch(KXLDSym
*sym
)
1026 sym
->is_replaced
= TRUE
;
1029 /*******************************************************************************
1030 *******************************************************************************/
1032 kxld_sym_mark_private(KXLDSym
*sym
)
1036 sym
->type
|= N_PEXT
;
1037 sym
->is_external
= FALSE
;