]>
git.saurik.com Git - apple/ld64.git/blob - src/ld/passes/huge.cpp
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2009 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>
44 bool operator()(const ld::Atom
* atom
) const {
45 return (atom
== NULL
);
49 void doPass(const Options
& opts
, ld::Internal
& state
)
51 const bool log
= false;
53 // only make make __huge section in final linked images
54 if ( opts
.outputKind() == Options::kObjectFile
)
57 // only make make __huge section for x86_64
58 if ( opts
.architecture() != CPU_TYPE_X86_64
)
61 // only needed if some (non-linkedit) atoms have an addresss >2GB from base address
62 state
.usingHugeSections
= false;
64 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
65 ld::Internal::FinalSection
* sect
= *sit
;
66 if ( sect
->type() == ld::Section::typePageZero
)
68 if ( sect
->type() == ld::Section::typeStack
)
70 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
71 const ld::Atom
* atom
= *ait
;
72 if ( (address
> 0x7FFFFFFFLL
) && !sect
->isSectionHidden() ) {
73 state
.usingHugeSections
= true;
74 if (log
) fprintf(stderr
, "atom: %s is >2GB (0x%09llX), so enabling huge mode\n", atom
->name(), address
);
77 address
+= atom
->size();
79 if ( state
.usingHugeSections
)
82 if ( !state
.usingHugeSections
)
85 // move all zero fill atoms that >1MB in size to a new __huge section
86 ld::Internal::FinalSection
* hugeSection
= state
.getFinalSection(*new ld::Section("__DATA", "__huge", ld::Section::typeZeroFill
));
87 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
88 ld::Internal::FinalSection
* sect
= *sit
;
89 if ( sect
== hugeSection
)
91 if ( sect
->type() == ld::Section::typeZeroFill
) {
92 bool movedSome
= false;
93 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
94 const ld::Atom
* atom
= *ait
;
95 if ( atom
->size() > 1024*1024 ) {
96 hugeSection
->atoms
.push_back(atom
);
97 if (log
) fprintf(stderr
, "moved to __huge: %s, size=%llu\n", atom
->name(), atom
->size());
98 *ait
= NULL
; // change atom to NULL for later bulk removal
103 sect
->atoms
.erase(std::remove_if(sect
->atoms
.begin(), sect
->atoms
.end(), NullAtom()), sect
->atoms
.end());
112 } // namespace passes