1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2010 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
22 * @APPLE_LICENSE_HEADER_END@
30 #include <mach/machine.h>
46 bool operator()(ld::dylib::File
* dylib
) const {
47 return dylib
->willRemoved();
52 void doPass(const Options
& opts
, ld::Internal
& state
)
54 // const bool log = false;
56 // clear "willRemoved" bit on all dylibs
57 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
58 ld::dylib::File
* aDylib
= *it
;
59 aDylib
->setWillBeRemoved(false);
61 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
62 ld::dylib::File
* aDylib
= *it
;
63 // set "willRemoved" bit on implicit dylibs that did not provide any exports
64 if ( aDylib
->implicitlyLinked() && !aDylib
->explicitlyLinked() && !aDylib
->providedExportAtom() )
65 aDylib
->setWillBeRemoved(true);
66 // set "willRemoved" bit on dead strippable explicit dylibs that did not provide any exports
67 if ( aDylib
->explicitlyLinked() && aDylib
->deadStrippable() && !aDylib
->providedExportAtom() )
68 aDylib
->setWillBeRemoved(true);
69 // set "willRemoved" bit on any unused explicit when -dead_strip_dylibs is used
70 if ( opts
.deadStripDylibs() && !aDylib
->providedExportAtom() )
71 aDylib
->setWillBeRemoved(true);
73 // remove unused dylibs
74 state
.dylibs
.erase(std::remove_if(state
.dylibs
.begin(), state
.dylibs
.end(), WillBeUsed()), state
.dylibs
.end());
77 // <rdar://problem/9441273> automatically weak-import dylibs when all symbols from it are weak-imported
78 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
79 ld::Internal::FinalSection
* sect
= *sit
;
80 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
81 const ld::Atom
* atom
= *ait
;
82 const ld::Atom
* target
= NULL
;
83 bool targetIsWeakImport
= false;
84 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
85 if ( fit
->firstInCluster() )
87 switch ( fit
->binding
) {
88 case ld::Fixup::bindingsIndirectlyBound
:
89 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
90 targetIsWeakImport
= fit
->weakImport
;
92 case ld::Fixup::bindingDirectlyBound
:
93 target
= fit
->u
.target
;
94 targetIsWeakImport
= fit
->weakImport
;
99 if ( (target
!= NULL
) && (target
->definition() == ld::Atom::definitionProxy
) ) {
100 if ( targetIsWeakImport
&& !opts
.allowWeakImports() )
101 throwf("weak import of symbol '%s' not supported because of option: -no_weak_imports", target
->name());
102 ld::Atom::WeakImportState curWI
= target
->weakImportState();
103 if ( curWI
== ld::Atom::weakImportUnset
) {
104 // first use of this proxy, set weak-import based on this usage
105 (const_cast<ld::Atom
*>(target
))->setWeakImportState(targetIsWeakImport
);
108 // proxy already has weak-importness set, check for weakness mismatch
109 bool curIsWeakImport
= (curWI
== ld::Atom::weakImportTrue
);
110 if ( curIsWeakImport
!= targetIsWeakImport
) {
112 switch ( opts
.weakReferenceMismatchTreatment() ) {
113 case Options::kWeakReferenceMismatchError
:
114 throwf("mismatching weak references for symbol: %s", target
->name());
115 case Options::kWeakReferenceMismatchWeak
:
116 (const_cast<ld::Atom
*>(target
))->setWeakImportState(true);
118 case Options::kWeakReferenceMismatchNonWeak
:
119 (const_cast<ld::Atom
*>(target
))->setWeakImportState(false);
132 } // namespace dylibs
133 } // namespace passes