]>
git.saurik.com Git - apple/ld64.git/blob - src/ld/passes/huge.cpp
693976cef69b27c15a3b60e6944b62cf3d5a75d7
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>
45 bool operator()(const ld::Atom
* atom
) const {
46 return (atom
== NULL
);
50 void doPass(const Options
& opts
, ld::Internal
& state
)
52 const bool log
= false;
54 // only make make __huge section in final linked images
55 if ( opts
.outputKind() == Options::kObjectFile
)
58 // only make make __huge section for x86_64
59 if ( opts
.architecture() != CPU_TYPE_X86_64
)
62 // only needed if some (non-linkedit) atoms have an addresss >2GB from base address
63 state
.usingHugeSections
= false;
65 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
66 ld::Internal::FinalSection
* sect
= *sit
;
67 if ( sect
->type() == ld::Section::typePageZero
)
69 if ( sect
->type() == ld::Section::typeStack
)
71 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
72 const ld::Atom
* atom
= *ait
;
73 if ( (address
> 0x7FFFFFFFLL
) && !sect
->isSectionHidden() ) {
74 state
.usingHugeSections
= true;
75 if (log
) fprintf(stderr
, "atom: %s is >2GB (0x%09llX), so enabling huge mode\n", atom
->name(), address
);
78 address
+= atom
->size();
80 if ( state
.usingHugeSections
)
83 if ( !state
.usingHugeSections
)
86 // move all zero fill atoms that >1MB in size to a new __huge section
87 ld::Internal::FinalSection
* hugeSection
= state
.getFinalSection(*new ld::Section("__DATA", "__huge", ld::Section::typeZeroFill
));
88 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
89 ld::Internal::FinalSection
* sect
= *sit
;
90 if ( sect
== hugeSection
)
92 if ( sect
->type() == ld::Section::typeZeroFill
) {
93 bool movedSome
= false;
94 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
95 const ld::Atom
* atom
= *ait
;
96 if ( atom
->size() > 1024*1024 ) {
97 hugeSection
->atoms
.push_back(atom
);
98 state
.atomToSection
[atom
] = hugeSection
;
99 if (log
) fprintf(stderr
, "moved to __huge: %s, size=%llu\n", atom
->name(), atom
->size());
100 *ait
= NULL
; // change atom to NULL for later bulk removal
105 sect
->atoms
.erase(std::remove_if(sect
->atoms
.begin(), sect
->atoms
.end(), NullAtom()), sect
->atoms
.end());
114 } // namespace passes