source: dev/trunk/abdev/BasicCompiler_Common/src/Linker.cpp@ 420

Last change on this file since 420 was 414, checked in by dai_9181, 17 years ago

データテーブルの再配置ロジックにミスがあったため、修正。

File size: 7.7 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5
6// データテーブルスケジュール
7void Linker::ResolveDataTableSchedules( long dataSectionBaseOffset )
8{
9 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
10 {
11 if( schedule.GetType() == Schedule::DataTable )
12 {
13 nativeCode.Overwrite(
14 schedule.GetOffset(),
15 static_cast<long>( nativeCode.GetLong( schedule.GetOffset() ) + imageBase + dataSectionBaseOffset )
16 );
17 }
18 }
19
20 BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
21 {
22 if( schedule.GetType() == Schedule::DataTable )
23 {
24#ifdef _WIN64
25 dataTable.OverwriteInt64(
26 schedule.GetOffset(),
27 dataTable.GetInt64( schedule.GetOffset() ) + imageBase + dataSectionBaseOffset
28 );
29#else
30 dataTable.Overwrite(
31 schedule.GetOffset(),
32 dataTable.GetLong( schedule.GetOffset() ) + imageBase + dataSectionBaseOffset
33 );
34#endif
35 }
36 }
37}
38
39// Catchアドレス スケジュール
40void Linker::ResolveCatchAddressSchedules( long codeSectionBaseOffset )
41{
42 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
43 {
44 if( schedule.GetType() == Schedule::CatchAddress )
45 {
46 if( nativeCode.GetLong( schedule.GetOffset() ) != 0 )
47 {
48 // 置き換える値が0の場合を除く
49 nativeCode.Overwrite(
50 schedule.GetOffset(),
51 static_cast<long>( nativeCode.GetLong( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset )
52 );
53 }
54 }
55 }
56
57 BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
58 {
59 if( schedule.GetType() == Schedule::CatchAddress )
60 {
61 if( dataTable.GetLong( schedule.GetOffset() ) != 0 )
62 {
63 // 置き換える値が0の場合を除く
64#ifdef _WIN64
65 dataTable.OverwriteInt64(
66 schedule.GetOffset(),
67 dataTable.GetInt64( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset
68 );
69#else
70 dataTable.Overwrite(
71 schedule.GetOffset(),
72 dataTable.GetLong( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset
73 );
74#endif
75 }
76 }
77 }
78}
79
80// DLL関数スケジュール
81void Linker::ResolveDllProcSchedules( long codeSectionBaseOffset, long importSectionBaseOffset, long lookupSize, long hintSize )
82{
83 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
84 {
85 if( schedule.GetType() == Schedule::DllProc )
86 {
87#ifdef _AMD64_
88 nativeCode.Overwrite(
89 schedule.GetOffset(),
90 static_cast<long>( importSectionBaseOffset + schedule.GetDllProc().GetLookupAddress()
91 - ( codeSectionBaseOffset + schedule.GetOffset() + sizeof(long) ) )
92 );
93#else
94 nativeCode.Overwrite(
95 schedule.GetOffset(),
96 static_cast<long>( imageBase + importSectionBaseOffset + lookupSize + hintSize
97 + schedule.GetDllProc().GetLookupAddress() )
98 );
99#endif
100 }
101 }
102}
103
104// ユーザ定義関数スケジュール
105void Linker::ResolveUserProcSchedules( long codeSectionBaseOffset )
106{
107 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
108 {
109 if( schedule.GetType() == Schedule::UserProc
110 || schedule.GetType() == Schedule::AddressOf )
111 {
112 if( schedule.GetUserProc().GetBeginOpAddress() == 0
113 && schedule.GetUserProc().GetEndOpAddress() == 0 )
114 {
115 SetError();
116 }
117
118 if( schedule.GetType() == Schedule::UserProc )
119 {
120 nativeCode.Overwrite(
121 schedule.GetOffset(),
122 static_cast<long>( schedule.GetUserProc().GetBeginOpAddress() - ( schedule.GetOffset() + sizeof(long) ) )
123 );
124 }
125 else if( schedule.GetType() == Schedule::AddressOf )
126 {
127 nativeCode.Overwrite(
128 schedule.GetOffset(),
129 static_cast<long>( schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset )
130 );
131 }
132 }
133 }
134}
135
136// グローバル変数スケジュール
137void Linker::ResolveGlobalVarSchedules( long rwSectionBaseOffset )
138{
139 int allInitVarSize = compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize();
140
141 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
142 {
143 if( schedule.GetType() == Schedule::GlobalVar )
144 {
145 if( nativeCode.GetLong( schedule.GetOffset() ) & 0x80000000 )
146 {
147 nativeCode.Overwrite(
148 schedule.GetOffset(),
149 static_cast<long>( allInitVarSize + (nativeCode.GetLong( schedule.GetOffset() ) & 0x7FFFFFFF) + imageBase + rwSectionBaseOffset )
150 );
151 }
152 else
153 {
154 nativeCode.Overwrite(
155 schedule.GetOffset(),
156 static_cast<long>( nativeCode.GetLong( schedule.GetOffset() ) + imageBase + rwSectionBaseOffset )
157 );
158 }
159 }
160 }
161}
162
163void Linker::ResolveVtblSchedule( long dataSectionBaseOffset )
164{
165 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
166 {
167 if( schedule.GetType() == Schedule::ComVtbl )
168 {
169 LONG_PTR vtblOffset = schedule.GetClass().GetComVtblOffset();
170
171 nativeCode.Overwrite(
172 schedule.GetOffset(),
173 static_cast<long>( vtblOffset + imageBase + dataSectionBaseOffset )
174 );
175 }
176
177 if( schedule.GetType() == Schedule::Vtbl )
178 {
179 LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
180
181 nativeCode.Overwrite(
182 schedule.GetOffset(),
183 static_cast<long>( vtblMasterListOffset + imageBase + dataSectionBaseOffset )
184 );
185 }
186 }
187
188 BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
189 {
190 if( schedule.GetType() == Schedule::ComVtbl )
191 {
192 LONG_PTR vtblOffset = schedule.GetClass().GetComVtblOffset();
193
194#ifdef _WIN64
195 dataTable.OverwriteInt64(
196 schedule.GetOffset(),
197 vtblOffset + imageBase + dataSectionBaseOffset
198 );
199#else
200 dataTable.Overwrite(
201 schedule.GetOffset(),
202 vtblOffset + imageBase + dataSectionBaseOffset
203 );
204#endif
205 }
206
207 if( schedule.GetType() == Schedule::Vtbl )
208 {
209 LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
210
211#ifdef _WIN64
212 dataTable.OverwriteInt64(
213 schedule.GetOffset(),
214 vtblMasterListOffset + imageBase + dataSectionBaseOffset
215 );
216#else
217 dataTable.Overwrite(
218 schedule.GetOffset(),
219 vtblMasterListOffset + imageBase + dataSectionBaseOffset
220 );
221#endif
222 }
223 }
224}
225
226void Linker::ResolveTypeInfoSchedule( long dataSectionBaseOffset )
227{
228 BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
229 {
230 if( schedule.GetType() == Schedule::TypeInfo )
231 {
232 LONG_PTR typeInfoDataTableOffset = schedule.GetClass().GetTypeInfoDataTableOffset();
233
234#ifdef _WIN64
235 dataTable.OverwriteInt64(
236 schedule.GetOffset(),
237 typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
238 );
239#else
240 dataTable.Overwrite(
241 schedule.GetOffset(),
242 typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
243 );
244#endif
245 }
246 }
247}
248
249void Linker::Link( ObjectModule &masterObjectModule )
250{
251 // nativeCodeは初期状態でなければならない
252 if( nativeCode.GetSize() > 0 )
253 {
254 SetError();
255 }
256
257 nativeCode.PutEx( masterObjectModule.globalNativeCode );
258
259 masterObjectModule.meta.GetUserProcs().Iterator_Reset();
260 while( masterObjectModule.meta.GetUserProcs().Iterator_HasNext() )
261 {
262 const UserProc *pUserProc = masterObjectModule.meta.GetUserProcs().Iterator_GetNext();
263
264 if( pUserProc->GetNativeCode().GetSize() > 0 )
265 {
266 // 関数の開始位置(コードセクションからのオフセット)
267 int beginCodePos = nativeCode.GetSize();
268
269 // コードセクションに関数のネイティブコードを追加
270 nativeCode.PutEx( pUserProc->GetNativeCode() );
271
272 // 関数の終了位置(コードセクションからのオフセット)
273 int endCodePos = nativeCode.GetSize();
274
275 // コードセクション内の関数の範囲を設定
276 pUserProc->SetBeginOpAddress( beginCodePos );
277 pUserProc->SetEndOpAddress( endCodePos );
278 }
279 }
280}
281
282void Linker::SetDataTable( DataTable &dataTable )
283{
284 this->dataTable.Add( dataTable );
285}
Note: See TracBrowser for help on using the repository browser.