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@
26 // already in ld::passes::stubs namespace
33 class StubHelperAtom : public ld::Atom {
35 StubHelperAtom(ld::passes::stubs::Pass& pass, const ld::Atom& stubTo,
36 const ld::Atom& lazyPointer, bool forLazyDylib)
37 : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
38 ld::Atom::scopeLinkageUnit, ld::Atom::typeStubHelper,
39 symbolTableNotIn, false, false, false, ld::Atom::Alignment(2)),
41 _fixup1(1, ld::Fixup::k1of1, ld::Fixup::kindStoreTargetAddressLittleEndian32, &lazyPointer),
42 _fixup2(6, ld::Fixup::k1of1, ld::Fixup::kindStoreTargetAddressX86BranchPCRel32,
43 forLazyDylib ? pass.internal()->lazyBindingHelper : pass.internal()->classicBindingHelper)
44 { pass.addAtom(*this); }
46 virtual const ld::File* file() const { return _stubTo.file(); }
47 virtual const char* name() const { return _stubTo.name(); }
48 virtual uint64_t size() const { return 10; }
49 virtual uint64_t objectAddress() const { return 0; }
50 virtual void copyRawContent(uint8_t buffer[]) const {
51 buffer[0] = 0x68; // pushl $foo$lazy_ptr
56 buffer[5] = 0xE9; // jmp dyld_stub_binding_helper
62 virtual void setScope(Scope) { }
63 virtual ld::Fixup::iterator fixupsBegin() const { return &_fixup1; }
64 virtual ld::Fixup::iterator fixupsEnd() const { return &((ld::Fixup*)&_fixup2)[1]; }
67 const ld::Atom& _stubTo;
68 mutable ld::Fixup _fixup1;
69 mutable ld::Fixup _fixup2;
71 static ld::Section _s_section;
74 ld::Section StubHelperAtom::_s_section("__TEXT", "__stub_helper", ld::Section::typeStubHelper);
78 class LazyPointerAtom : public ld::Atom {
80 LazyPointerAtom(ld::passes::stubs::Pass& pass, const ld::Atom& stubTo,
81 bool forLazyDylib, bool weakImport)
82 : ld::Atom( forLazyDylib ? _s_sectionLazy : _s_section,
83 ld::Atom::definitionRegular, ld::Atom::combineNever,
84 ld::Atom::scopeTranslationUnit,
85 forLazyDylib ? ld::Atom::typeLazyDylibPointer : ld::Atom::typeLazyPointer,
86 symbolTableNotIn, false, false, false, ld::Atom::Alignment(2)),
88 _helper(pass, stubTo, *this, forLazyDylib),
89 _fixup1(0, ld::Fixup::k1of1, ld::Fixup::kindStoreTargetAddressLittleEndian32, &_helper),
90 _fixup2(0, ld::Fixup::k1of1, ld::Fixup::kindLazyTarget, &stubTo)
91 { _fixup2.weakImport = weakImport; pass.addAtom(*this); }
93 virtual const ld::File* file() const { return _stubTo.file(); }
94 virtual const char* name() const { return _stubTo.name(); }
95 virtual uint64_t size() const { return 4; }
96 virtual uint64_t objectAddress() const { return 0; }
97 virtual void copyRawContent(uint8_t buffer[]) const { }
98 virtual void setScope(Scope) { }
99 virtual ld::Fixup::iterator fixupsBegin() const { return &_fixup1; }
100 virtual ld::Fixup::iterator fixupsEnd() const { return &((ld::Fixup*)&_fixup2)[1]; }
103 const ld::Atom& _stubTo;
104 StubHelperAtom _helper;
105 mutable ld::Fixup _fixup1;
106 mutable ld::Fixup _fixup2;
108 static ld::Section _s_section;
109 static ld::Section _s_sectionLazy;
112 ld::Section LazyPointerAtom::_s_section("__DATA", "__la_symbol_ptr", ld::Section::typeLazyPointer);
113 ld::Section LazyPointerAtom::_s_sectionLazy("__DATA", "__ld_symbol_ptr", ld::Section::typeLazyDylibPointer);
117 class StubAtom : public ld::Atom {
119 StubAtom(ld::passes::stubs::Pass& pass, const ld::Atom& stubTo,
120 bool forLazyDylib, bool weakImport)
121 : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
122 ld::Atom::scopeLinkageUnit, ld::Atom::typeStub,
123 symbolTableNotIn, false, false, false, ld::Atom::Alignment(1)),
125 _lazyPointer(pass, stubTo, forLazyDylib, weakImport),
126 _fixup(2, ld::Fixup::k1of1, ld::Fixup::kindStoreTargetAddressLittleEndian32, &_lazyPointer) { pass.addAtom(*this); }
128 virtual const ld::File* file() const { return _stubTo.file(); }
129 virtual const char* name() const { return _stubTo.name(); }
130 virtual uint64_t size() const { return 6; }
131 virtual uint64_t objectAddress() const { return 0; }
132 virtual void copyRawContent(uint8_t buffer[]) const {
133 buffer[0] = 0xFF; // jmp *foo$lazy_pointer(%rip)
140 virtual void setScope(Scope) { }
141 virtual ld::Fixup::iterator fixupsBegin() const { return &_fixup; }
142 virtual ld::Fixup::iterator fixupsEnd() const { return &((ld::Fixup*)&_fixup)[1]; }
145 const ld::Atom& _stubTo;
146 LazyPointerAtom _lazyPointer;
147 mutable ld::Fixup _fixup;
149 static ld::Section _s_section;
152 ld::Section StubAtom::_s_section("__TEXT", "__symbol_stub", ld::Section::typeStub);
155 } // namespace classic