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
->is_resolved
= TRUE
;
153 /*******************************************************************************
154 *******************************************************************************/
156 init_predicates(KXLDSym
*sym
, u_char n_type
, u_short n_desc
)
158 kern_return_t rval
= KERN_FAILURE
;
162 /* The type field is interpreted differently for normal symbols and stabs */
163 if (n_type
& N_STAB
) {
167 /* Labeled as NO_SECT in stab.h */
184 sym
->is_absolute
= 1;
186 /* Labeled as n_sect in stab.h */
198 /* These are labeled as NO_SECT in stab.h, but they are actually
199 * section-based on OS X. We must mark them as such so they get
208 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
209 "Invalid N_STAB symbol type: %u.", n_type
);
213 /* Don't care about the C++ predicates for stabs */
216 u_char type
= n_type
& N_TYPE
;
218 /* The first set of type fields are mutually exclusive, so they can be
219 * set with a switch statement.
223 sym
->is_absolute
= 1;
229 if (sym
->base_addr
) {
232 sym
->is_undefined
= 1;
236 sym
->is_indirect
= 1;
240 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
241 "Invalid symbol type: %u.", type
);
245 /* Set the type-independent fields */
246 if ((n_type
& N_EXT
) && !(n_type
& N_PEXT
)) {
247 sym
->is_external
= 1;
250 if (n_desc
& N_DESC_DISCARDED
) {
251 sym
->is_obsolete
= 1;
254 if (n_desc
& N_WEAK_REF
) {
258 if (n_desc
& N_ARM_THUMB_DEF
) {
264 /* Set the C++-specific fields */
265 if (!strncmp(CXX_PREFIX
, sym
->name
, const_strlen(CXX_PREFIX
))) {
268 if (streq_safe(sym
->name
, METACLASS_VTABLE_PREFIX
,
269 const_strlen(METACLASS_VTABLE_PREFIX
)))
271 sym
->is_meta_vtable
= 1;
272 } else if (streq_safe(sym
->name
, VTABLE_PREFIX
,
273 const_strlen(VTABLE_PREFIX
)))
275 sym
->is_class_vtable
= 1;
276 } else if (kxld_strstr(sym
->name
, RESERVED_TOKEN
)) {
278 } else if (kxld_strstr(sym
->name
, METACLASS_TOKEN
)) {
279 sym
->is_metaclass
= 1;
280 } else if (kxld_strstr(sym
->name
, SUPER_METACLASS_POINTER_TOKEN
)) {
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;
318 /*******************************************************************************
319 *******************************************************************************/
321 kxld_sym_deinit(KXLDSym
*sym __unused
)
326 /*******************************************************************************
327 *******************************************************************************/
329 kxld_sym_destroy(KXLDSym
*sym
)
332 kxld_sym_deinit(sym
);
333 kxld_free(sym
, sizeof(*sym
));
337 /*******************************************************************************
338 *******************************************************************************/
340 kxld_sym_is_absolute(const KXLDSym
*sym
)
344 return (0 != sym
->is_absolute
);
347 /*******************************************************************************
348 *******************************************************************************/
350 kxld_sym_is_section(const KXLDSym
*sym
)
354 return (0 != sym
->is_section
);
357 /*******************************************************************************
358 *******************************************************************************/
360 kxld_sym_is_defined(const KXLDSym
*sym
)
364 return ((kxld_sym_is_absolute(sym
) || kxld_sym_is_section(sym
)) &&
365 !kxld_sym_is_replaced(sym
));
369 /*******************************************************************************
370 *******************************************************************************/
372 kxld_sym_is_defined_locally(const KXLDSym
*sym
)
376 return (kxld_sym_is_defined(sym
) && !sym
->is_resolved
);
379 /*******************************************************************************
380 *******************************************************************************/
382 kxld_sym_is_external(const KXLDSym
*sym
)
386 return (0 != sym
->is_external
);
389 /*******************************************************************************
390 *******************************************************************************/
392 kxld_sym_is_exported(const KXLDSym
*sym
)
396 return (kxld_sym_is_defined_locally(sym
) && kxld_sym_is_external(sym
));
399 /*******************************************************************************
400 *******************************************************************************/
402 kxld_sym_is_undefined(const KXLDSym
*sym
)
406 return (0 != sym
->is_undefined
);
409 /*******************************************************************************
410 *******************************************************************************/
412 kxld_sym_is_indirect(const KXLDSym
*sym
)
416 return (0 != sym
->is_indirect
);
419 /*******************************************************************************
420 *******************************************************************************/
422 kxld_sym_is_replaced(const KXLDSym
*sym
)
426 return (0 != sym
->is_replaced
);
429 /*******************************************************************************
430 *******************************************************************************/
432 kxld_sym_is_common(const KXLDSym
*sym
)
436 return (0 != sym
->is_common
);
439 /*******************************************************************************
440 *******************************************************************************/
442 kxld_sym_is_unresolved(const KXLDSym
*sym
)
444 return ((kxld_sym_is_undefined(sym
) && !kxld_sym_is_replaced(sym
)) ||
445 kxld_sym_is_indirect(sym
) || kxld_sym_is_common(sym
));
448 /*******************************************************************************
449 *******************************************************************************/
451 kxld_sym_is_obsolete(const KXLDSym
*sym
)
453 return (0 != sym
->is_obsolete
);
457 /*******************************************************************************
458 *******************************************************************************/
460 kxld_sym_is_got(const KXLDSym
*sym
)
464 return (0 != sym
->is_got
);
466 #endif /* KXLD_USER_OR_GOT */
468 /*******************************************************************************
469 *******************************************************************************/
471 kxld_sym_is_stab(const KXLDSym
*sym
)
475 return (0 != sym
->is_stab
);
478 /*******************************************************************************
479 *******************************************************************************/
481 kxld_sym_is_weak(const KXLDSym
*sym
)
485 return (0 != sym
->is_weak
);
488 /*******************************************************************************
489 *******************************************************************************/
491 kxld_sym_is_cxx(const KXLDSym
*sym
)
495 return (0 != sym
->is_cxx
);
498 /*******************************************************************************
499 *******************************************************************************/
501 kxld_sym_is_pure_virtual(const KXLDSym
*sym
)
503 return (0 != sym
->is_pure_virtual
);
506 /*******************************************************************************
507 *******************************************************************************/
509 kxld_sym_is_vtable(const KXLDSym
*sym
)
513 return kxld_sym_is_class_vtable(sym
) || kxld_sym_is_metaclass_vtable(sym
);
516 /*******************************************************************************
517 *******************************************************************************/
519 kxld_sym_is_class_vtable(const KXLDSym
*sym
)
523 return (0 != sym
->is_class_vtable
);
526 /*******************************************************************************
527 *******************************************************************************/
529 kxld_sym_is_metaclass_vtable(const KXLDSym
*sym
)
533 return (0 != sym
->is_meta_vtable
);
536 /*******************************************************************************
537 *******************************************************************************/
539 kxld_sym_is_padslot(const KXLDSym
*sym
)
543 return (0 != sym
->is_padslot
);
546 /*******************************************************************************
547 *******************************************************************************/
549 kxld_sym_is_metaclass(const KXLDSym
*sym
)
553 return (0 != sym
->is_metaclass
);
556 /*******************************************************************************
557 *******************************************************************************/
559 kxld_sym_is_super_metaclass_pointer(const KXLDSym
*sym
)
563 return (0 != sym
->is_super_metaclass_pointer
);
566 /*******************************************************************************
567 *******************************************************************************/
569 kxld_sym_name_is_pure_virtual(const char *name
)
571 return streq_safe(CXX_PURE_VIRTUAL
, name
, sizeof(CXX_PURE_VIRTUAL
));
574 /*******************************************************************************
575 *******************************************************************************/
577 kxld_sym_name_is_padslot(const char *name
)
581 return (kxld_strstr(name
, RESERVED_TOKEN
) != 0);
584 /*******************************************************************************
585 *******************************************************************************/
587 kxld_sym_get_section_offset(const KXLDSym
*sym
, const KXLDSect
*sect
)
591 return (u_int
) (sym
->base_addr
- sect
->base_addr
);
594 #if KXLD_USER_OR_COMMON
595 /*******************************************************************************
596 *******************************************************************************/
598 kxld_sym_get_common_size(const KXLDSym
*sym
)
600 return sym
->base_addr
;
603 /*******************************************************************************
604 *******************************************************************************/
606 kxld_sym_get_common_align(const KXLDSym
*sym
)
608 u_int align
= GET_COMM_ALIGN(sym
->desc
);
609 if (!align
) align
= 3;
613 #endif /* KXLD_USER_OR_COMMON */
615 /*******************************************************************************
616 *******************************************************************************/
618 kxld_sym_get_class_name_from_metaclass(const KXLDSym
*sym
,
619 char class_name
[], u_long class_name_len
)
621 kern_return_t rval
= KERN_FAILURE
;
624 require_action(kxld_sym_is_metaclass(sym
), finish
, rval
=KERN_FAILURE
);
626 rval
= extract_inner_string(sym
->name
, OSOBJ_PREFIX
, METACLASS_TOKEN
,
627 class_name
, class_name_len
);
628 require_noerr(rval
, finish
);
635 /*******************************************************************************
636 *******************************************************************************/
638 kxld_sym_get_class_name_from_super_metaclass_pointer(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_super_metaclass_pointer(sym
), finish
,
647 rval
= extract_inner_string(sym
->name
, OSOBJ_PREFIX
,
648 SUPER_METACLASS_POINTER_TOKEN
, class_name
, class_name_len
);
649 require_noerr(rval
, finish
);
656 /*******************************************************************************
657 *******************************************************************************/
659 kxld_sym_get_class_name_from_vtable(const KXLDSym
*sym
,
660 char class_name
[], u_long class_name_len
)
662 kern_return_t rval
= KERN_FAILURE
;
665 require_action(kxld_sym_is_class_vtable(sym
), finish
, rval
=KERN_FAILURE
);
667 rval
= kxld_sym_get_class_name_from_vtable_name(sym
->name
,
668 class_name
, class_name_len
);
669 require_noerr(rval
, finish
);
677 /*******************************************************************************
678 *******************************************************************************/
680 kxld_sym_get_class_name_from_vtable_name(const char *vtable_name
,
681 char class_name
[], u_long class_name_len
)
683 kern_return_t rval
= KERN_FAILURE
;
687 rval
= extract_inner_string(vtable_name
, VTABLE_PREFIX
, NULL
,
688 class_name
, class_name_len
);
689 require_noerr(rval
, finish
);
696 /*******************************************************************************
697 *******************************************************************************/
699 kxld_sym_get_vtable_name_from_class_name(const char *class_name
,
700 char vtable_name
[], u_long vtable_name_len
)
702 kern_return_t rval
= KERN_FAILURE
;
708 outlen
= strlcpy(vtable_name
, VTABLE_PREFIX
, vtable_name_len
);
709 require_action(outlen
< vtable_name_len
, finish
,
712 outlen
= strlcat(vtable_name
, class_name
, vtable_name_len
);
713 require_action(outlen
< vtable_name_len
, finish
,
721 /*******************************************************************************
722 *******************************************************************************/
724 kxld_sym_get_meta_vtable_name_from_class_name(const char *class_name
,
725 char meta_vtable_name
[], u_long meta_vtable_name_len
)
727 kern_return_t rval
= KERN_FAILURE
;
731 check(meta_vtable_name
);
733 outlen
= strlcpy(meta_vtable_name
, METACLASS_VTABLE_PREFIX
,
734 meta_vtable_name_len
);
735 require_action(outlen
< meta_vtable_name_len
, finish
,
738 outlen
= strlcat(meta_vtable_name
, class_name
, meta_vtable_name_len
);
739 require_action(outlen
< meta_vtable_name_len
, finish
,
742 outlen
= strlcat(meta_vtable_name
, METACLASS_VTABLE_SUFFIX
,
743 meta_vtable_name_len
);
744 require_action(outlen
< meta_vtable_name_len
, finish
,
752 /*******************************************************************************
753 *******************************************************************************/
755 kxld_sym_get_final_sym_name_from_class_name(const char *class_name
,
756 char final_sym_name
[], u_long final_sym_name_len
)
758 kern_return_t rval
= KERN_FAILURE
;
762 check(final_sym_name
);
764 outlen
= strlcpy(final_sym_name
, OSOBJ_PREFIX
, final_sym_name_len
);
765 require_action(outlen
< final_sym_name_len
, finish
,
768 outlen
= strlcat(final_sym_name
, class_name
, final_sym_name_len
);
769 require_action(outlen
< final_sym_name_len
, finish
,
772 outlen
= strlcat(final_sym_name
, FINAL_CLASS_TOKEN
, final_sym_name_len
);
773 require_action(outlen
< final_sym_name_len
, finish
,
782 /*******************************************************************************
783 *******************************************************************************/
785 kxld_sym_get_function_prefix_from_class_name(const char *class_name
,
786 char function_prefix
[], u_long function_prefix_len
)
792 check(function_prefix
);
794 outlen
= strlcpy(function_prefix
, OSOBJ_PREFIX
, function_prefix_len
);
795 require(outlen
< function_prefix_len
, finish
);
797 outlen
= strlcat(function_prefix
, class_name
, function_prefix_len
);
798 require(outlen
< function_prefix_len
, finish
);
805 /*******************************************************************************
806 *******************************************************************************/
808 extract_inner_string(const char *str
, const char *prefix
, const char *suffix
,
809 char *buf
, u_long len
)
811 kern_return_t rval
= KERN_FAILURE
;
812 u_long prelen
= 0, suflen
= 0, striplen
= 0;
817 prelen
= (prefix
) ? strlen(prefix
) : 0;
818 suflen
= (suffix
) ? strlen(suffix
) : 0;
819 striplen
= strlen(str
) - prelen
- suflen
;
821 require_action(striplen
< len
, finish
, rval
=KERN_FAILURE
);
823 strncpy(buf
, str
+ prelen
, striplen
);
824 buf
[striplen
] = '\0';
832 /*******************************************************************************
833 *******************************************************************************/
835 kxld_sym_set_got(KXLDSym
*sym
)
839 #endif /* KXLD_USER_OR_GOT */
841 /*******************************************************************************
842 *******************************************************************************/
844 kxld_sym_relocate(KXLDSym
*sym
, const KXLDSect
*sect
)
846 if (kxld_sym_is_section(sym
)) {
847 sym
->link_addr
= sym
->base_addr
- sect
->base_addr
+ sect
->link_addr
;
848 sym
->relocated_sectnum
= sect
->sectnum
;
852 #if KXLD_USER_OR_ILP32
853 /*******************************************************************************
854 *******************************************************************************/
856 kxld_sym_export_macho_32(const KXLDSym
*sym
, u_char
*_nl
, char *strtab
,
857 u_long
*stroff
, u_long strsize
)
859 kern_return_t rval
= KERN_FAILURE
;
860 struct nlist
*nl
= (struct nlist
*) ((void *) _nl
);
869 bytes
= strlen(sym
->name
) + 1;
870 require_action((u_long
)bytes
<= strsize
- *stroff
, finish
,
871 rval
= KERN_FAILURE
);
873 nl
->n_type
= sym
->type
;
874 nl
->n_sect
= (kxld_sym_is_section(sym
)) ? sym
->relocated_sectnum
+ 1 : 0;
875 nl
->n_desc
= sym
->desc
;
876 nl
->n_un
.n_strx
= (uint32_t) *stroff
;
877 nl
->n_value
= (uint32_t) sym
->link_addr
;
879 nl
->n_value
&= ~0x1U
;
882 str
= (char *) (strtab
+ *stroff
);
883 strlcpy(str
, sym
->name
, strsize
- *stroff
);
891 #endif /* KXLD_USER_OR_ILP32 */
893 #if KXLD_USER_OR_LP64
894 /*******************************************************************************
895 *******************************************************************************/
897 kxld_sym_export_macho_64(const KXLDSym
*sym
, u_char
*_nl
, char *strtab
,
898 u_long
*stroff
, u_long strsize
)
900 kern_return_t rval
= KERN_FAILURE
;
901 struct nlist_64
*nl
= (struct nlist_64
*) ((void *) _nl
);
910 bytes
= strlen(sym
->name
) + 1;
911 require_action((u_long
)bytes
<= strsize
- *stroff
, finish
,
912 rval
= KERN_FAILURE
);
914 nl
->n_type
= sym
->type
;
915 nl
->n_sect
= (kxld_sym_is_section(sym
)) ? sym
->relocated_sectnum
+ 1 : 0;
916 nl
->n_desc
= sym
->desc
;
917 nl
->n_un
.n_strx
= (uint32_t) *stroff
;
918 nl
->n_value
= (uint64_t) sym
->link_addr
;
920 nl
->n_value
&= ~0x1ULL
;
923 str
= (char *) (strtab
+ *stroff
);
925 strlcpy(str
, sym
->name
, strsize
- *stroff
);
934 #endif /* KXLD_USER_OR_LP64 */
936 /*******************************************************************************
937 *******************************************************************************/
939 kxld_sym_resolve(KXLDSym
*sym
, kxld_addr_t addr
)
941 kern_return_t rval
= KERN_FAILURE
;
945 require_action(kxld_sym_is_undefined(sym
) || kxld_sym_is_indirect(sym
),
946 finish
, rval
=KERN_FAILURE
);
948 /* Set the n_list data types */
950 sym
->link_addr
= addr
;
951 sym
->type
= N_ABS
| N_EXT
;
952 sym
->sectnum
= NO_SECT
;
954 /* Set the predicate bits for an externally resolved symbol. */
956 sym
->is_external
= TRUE
;
957 sym
->is_absolute
= TRUE
;
958 sym
->is_resolved
= TRUE
;
960 /* Clear the predicate bits for types that can be resolved */
962 sym
->is_undefined
= FALSE
;
963 sym
->is_indirect
= FALSE
;
972 #if KXLD_USER_OR_COMMON
973 /*******************************************************************************
974 *******************************************************************************/
976 kxld_sym_resolve_common(KXLDSym
*sym
, u_int sectnum
, kxld_addr_t base_addr
)
978 kern_return_t rval
= KERN_FAILURE
;
982 require_action(kxld_sym_is_common(sym
), finish
,
985 sym
->base_addr
= base_addr
;
986 sym
->link_addr
= base_addr
;
987 sym
->type
= N_SECT
| N_EXT
;
988 sym
->sectnum
= sectnum
;
991 sym
->is_absolute
= FALSE
;
992 sym
->is_section
= TRUE
;
993 sym
->is_undefined
= FALSE
;
994 sym
->is_indirect
= FALSE
;
995 sym
->is_common
= FALSE
;
996 sym
->is_external
= TRUE
;
1004 #endif /* KXLD_USER_OR_COMMON */
1006 /*******************************************************************************
1007 *******************************************************************************/
1009 kxld_sym_delete(KXLDSym
*sym
)
1013 bzero(sym
, sizeof(*sym
));
1014 sym
->is_replaced
= TRUE
;
1018 /*******************************************************************************
1019 *******************************************************************************/
1021 kxld_sym_patch(KXLDSym
*sym
)
1025 sym
->is_replaced
= TRUE
;
1028 /*******************************************************************************
1029 *******************************************************************************/
1031 kxld_sym_mark_private(KXLDSym
*sym
)
1035 sym
->type
|= N_PEXT
;
1036 sym
->is_external
= FALSE
;