]> git.saurik.com Git - apple/ld64.git/blob - src/ld/passes/stubs/stub_x86_64_classic.hpp
ld64-123.2.tar.gz
[apple/ld64.git] / src / ld / passes / stubs / stub_x86_64_classic.hpp
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2009 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
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
12 * file.
13 *
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.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25
26 // already in ld::passes::stubs namespace
27 namespace x86_64 {
28 namespace classic {
29
30
31
32
33 class StubHelperAtom : public ld::Atom {
34 public:
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)),
40 _stubTo(stubTo),
41 _fixup1(3, ld::Fixup::k1of1, ld::Fixup::kindStoreTargetAddressX86PCRel32, &lazyPointer),
42 _fixup2(8, ld::Fixup::k1of1, ld::Fixup::kindStoreTargetAddressX86BranchPCRel32,
43 forLazyDylib ? pass.internal()->lazyBindingHelper : pass.internal()->classicBindingHelper)
44 { pass.addAtom(*this); }
45
46 virtual const ld::File* file() const { return _stubTo.file(); }
47 virtual bool translationUnitSource(const char** dir, const char** ) const
48 { return false; }
49 virtual const char* name() const { return _stubTo.name(); }
50 virtual uint64_t size() const { return 12; }
51 virtual uint64_t objectAddress() const { return 0; }
52 virtual void copyRawContent(uint8_t buffer[]) const {
53 buffer[0] = 0x4C; // lea foo$lazy_ptr(%rip),%r11
54 buffer[1] = 0x8D;
55 buffer[2] = 0x1D;
56 buffer[3] = 0x00;
57 buffer[4] = 0x00;
58 buffer[5] = 0x00;
59 buffer[6] = 0x00;
60 buffer[7] = 0xE9; // jmp dyld_stub_binding_helper
61 buffer[8] = 0x00;
62 buffer[9] = 0x00;
63 buffer[10] = 0x00;
64 buffer[11] = 0x00;
65 }
66 virtual void setScope(Scope) { }
67 virtual ld::Fixup::iterator fixupsBegin() const { return &_fixup1; }
68 virtual ld::Fixup::iterator fixupsEnd() const { return &((ld::Fixup*)&_fixup2)[1]; }
69
70 private:
71 const ld::Atom& _stubTo;
72 mutable ld::Fixup _fixup1;
73 mutable ld::Fixup _fixup2;
74
75 static ld::Section _s_section;
76 };
77
78 ld::Section StubHelperAtom::_s_section("__TEXT", "__stub_helper", ld::Section::typeStubHelper);
79
80
81
82 class LazyPointerAtom : public ld::Atom {
83 public:
84 LazyPointerAtom(ld::passes::stubs::Pass& pass, const ld::Atom& stubTo,
85 bool forLazyDylib, bool weakImport)
86 : ld::Atom( forLazyDylib ? _s_sectionLazy : _s_section,
87 ld::Atom::definitionRegular, ld::Atom::combineNever,
88 ld::Atom::scopeTranslationUnit,
89 forLazyDylib ? ld::Atom::typeLazyDylibPointer : ld::Atom::typeLazyPointer,
90 symbolTableNotIn, false, false, false, ld::Atom::Alignment(3)),
91 _stubTo(stubTo),
92 _helper(pass, stubTo, *this, forLazyDylib),
93 _fixup1(0, ld::Fixup::k1of1, ld::Fixup::kindStoreTargetAddressLittleEndian64, &_helper),
94 _fixup2(0, ld::Fixup::k1of1, ld::Fixup::kindLazyTarget, &stubTo)
95 { _fixup2.weakImport = weakImport; pass.addAtom(*this); }
96
97 virtual const ld::File* file() const { return _stubTo.file(); }
98 virtual bool translationUnitSource(const char** dir, const char** ) const
99 { return false; }
100 virtual const char* name() const { return _stubTo.name(); }
101 virtual uint64_t size() const { return 8; }
102 virtual uint64_t objectAddress() const { return 0; }
103 virtual void copyRawContent(uint8_t buffer[]) const { }
104 virtual void setScope(Scope) { }
105 virtual ld::Fixup::iterator fixupsBegin() const { return &_fixup1; }
106 virtual ld::Fixup::iterator fixupsEnd() const { return &((ld::Fixup*)&_fixup2)[1]; }
107
108 private:
109 const ld::Atom& _stubTo;
110 StubHelperAtom _helper;
111 mutable ld::Fixup _fixup1;
112 mutable ld::Fixup _fixup2;
113
114 static ld::Section _s_section;
115 static ld::Section _s_sectionLazy;
116 };
117
118 ld::Section LazyPointerAtom::_s_section("__DATA", "__la_symbol_ptr", ld::Section::typeLazyPointer);
119 ld::Section LazyPointerAtom::_s_sectionLazy("__DATA", "__ld_symbol_ptr", ld::Section::typeLazyDylibPointer);
120
121
122
123 class StubAtom : public ld::Atom {
124 public:
125 StubAtom(ld::passes::stubs::Pass& pass, const ld::Atom& stubTo,
126 bool forLazyDylib, bool weakImport)
127 : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
128 ld::Atom::scopeLinkageUnit, ld::Atom::typeStub,
129 symbolTableNotIn, false, false, false, ld::Atom::Alignment(1)),
130 _stubTo(stubTo),
131 _lazyPointer(pass, stubTo, forLazyDylib, weakImport),
132 _fixup(2, ld::Fixup::k1of1, ld::Fixup::kindStoreTargetAddressX86PCRel32, &_lazyPointer) { pass.addAtom(*this); }
133
134 virtual const ld::File* file() const { return _stubTo.file(); }
135 virtual bool translationUnitSource(const char** dir, const char** ) const
136 { return false; }
137 virtual const char* name() const { return _stubTo.name(); }
138 virtual uint64_t size() const { return 6; }
139 virtual uint64_t objectAddress() const { return 0; }
140 virtual void copyRawContent(uint8_t buffer[]) const {
141 buffer[0] = 0xFF; // jmp *foo$lazy_pointer(%rip)
142 buffer[1] = 0x25;
143 buffer[2] = 0x00;
144 buffer[3] = 0x00;
145 buffer[4] = 0x00;
146 buffer[5] = 0x00;
147 }
148 virtual void setScope(Scope) { }
149 virtual ld::Fixup::iterator fixupsBegin() const { return &_fixup; }
150 virtual ld::Fixup::iterator fixupsEnd() const { return &((ld::Fixup*)&_fixup)[1]; }
151
152 private:
153 const ld::Atom& _stubTo;
154 LazyPointerAtom _lazyPointer;
155 mutable ld::Fixup _fixup;
156
157 static ld::Section _s_section;
158 };
159
160 ld::Section StubAtom::_s_section("__TEXT", "__stubs", ld::Section::typeStub);
161
162
163 } // namespace classic
164 } // namespace x86_64
165