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>
45 bool operator()(ld::dylib::File
* dylib
) const {
46 return dylib
->willRemoved();
51 void doPass(const Options
& opts
, ld::Internal
& state
)
53 // const bool log = false;
55 // clear "willRemoved" bit on all dylibs
56 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
57 ld::dylib::File
* aDylib
= *it
;
58 aDylib
->setWillBeRemoved(false);
60 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
61 ld::dylib::File
* aDylib
= *it
;
62 // set "willRemoved" bit on implicit dylibs that did not provide any exports
63 if ( aDylib
->implicitlyLinked() && !aDylib
->explicitlyLinked() && !aDylib
->providedExportAtom() )
64 aDylib
->setWillBeRemoved(true);
65 // set "willRemoved" bit on dead strippable explicit dylibs that did not provide any exports
66 if ( aDylib
->explicitlyLinked() && aDylib
->deadStrippable() && !aDylib
->providedExportAtom() )
67 aDylib
->setWillBeRemoved(true);
68 // set "willRemoved" bit on any unused explicit when -dead_strip_dylibs is used
69 if ( opts
.deadStripDylibs() && !aDylib
->providedExportAtom() )
70 aDylib
->setWillBeRemoved(true);
72 // remove unused dylibs
73 state
.dylibs
.erase(std::remove_if(state
.dylibs
.begin(), state
.dylibs
.end(), WillBeUsed()), state
.dylibs
.end());
76 // <rdar://problem/9441273> automatically weak-import dylibs when all symbols from it are weak-imported
77 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
78 ld::Internal::FinalSection
* sect
= *sit
;
79 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
80 const ld::Atom
* atom
= *ait
;
81 const ld::Atom
* target
= NULL
;
82 bool targetIsWeakImport
= false;
83 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
84 if ( fit
->firstInCluster() )
86 switch ( fit
->binding
) {
87 case ld::Fixup::bindingsIndirectlyBound
:
88 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
89 targetIsWeakImport
= fit
->weakImport
;
91 case ld::Fixup::bindingDirectlyBound
:
92 target
= fit
->u
.target
;
93 targetIsWeakImport
= fit
->weakImport
;
98 if ( (target
!= NULL
) && (target
->definition() == ld::Atom::definitionProxy
) ) {
99 ld::Atom::WeakImportState curWI
= target
->weakImportState();
100 if ( curWI
== ld::Atom::weakImportUnset
) {
101 // first use of this proxy, set weak-import based on this usage
102 (const_cast<ld::Atom
*>(target
))->setWeakImportState(targetIsWeakImport
);
105 // proxy already has weak-importness set, check for weakness mismatch
106 bool curIsWeakImport
= (curWI
== ld::Atom::weakImportTrue
);
107 if ( curIsWeakImport
!= targetIsWeakImport
) {
109 switch ( opts
.weakReferenceMismatchTreatment() ) {
110 case Options::kWeakReferenceMismatchError
:
111 throwf("mismatching weak references for symbol: %s", target
->name());
112 case Options::kWeakReferenceMismatchWeak
:
113 (const_cast<ld::Atom
*>(target
))->setWeakImportState(true);
115 case Options::kWeakReferenceMismatchNonWeak
:
116 (const_cast<ld::Atom
*>(target
))->setWeakImportState(false);
129 } // namespace dylibs
130 } // namespace passes