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

Last change on this file since 361 was 361, checked in by dai_9181, 16 years ago

Catchのオーバーロードを実装中

File size: 6.8 KB
RevLine 
[257]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 }
[355]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 }
[257]37}
38
[357]39// Catchアドレス スケジュール
40void Linker::ResolveCatchAddressSchedules( long codeSectionBaseOffset )
41{
42 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
43 {
44 if( schedule.GetType() == Schedule::CatchAddress )
45 {
[359]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 }
[357]54 }
55 }
[361]56
57 BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
58 {
59 if( schedule.GetType() == Schedule::CatchAddress )
60 {
61 if( nativeCode.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 }
[357]78}
79
[257]80// DLL関数スケジュール
[258]81void Linker::ResolveDllProcSchedules( long codeSectionBaseOffset, long importSectionBaseOffset, long lookupSize, long hintSize )
[257]82{
83 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
84 {
85 if( schedule.GetType() == Schedule::DllProc )
86 {
[263]87#ifdef _AMD64_
[257]88 nativeCode.Overwrite(
89 schedule.GetOffset(),
90 static_cast<long>( importSectionBaseOffset + schedule.GetDllProc().GetLookupAddress()
91 - ( codeSectionBaseOffset + schedule.GetOffset() + sizeof(long) ) )
92 );
93#else
[258]94 nativeCode.Overwrite(
95 schedule.GetOffset(),
96 static_cast<long>( imageBase + importSectionBaseOffset + lookupSize + hintSize
97 + schedule.GetDllProc().GetLookupAddress() )
98 );
[257]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{
[288]139 int allInitVarSize = compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize();
[273]140
[257]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(),
[273]149 static_cast<long>( allInitVarSize + (nativeCode.GetLong( schedule.GetOffset() ) & 0x7FFFFFFF) + imageBase + rwSectionBaseOffset )
[257]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
[282]163void Linker::ResolveVtblSchedule( long dataSectionBaseOffset )
164{
165 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
166 {
167 if( schedule.GetType() == Schedule::Vtbl )
168 {
[342]169 LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
[282]170
171 nativeCode.Overwrite(
172 schedule.GetOffset(),
[342]173 static_cast<long>( vtblMasterListOffset + imageBase + dataSectionBaseOffset )
[282]174 );
175 }
176 }
[355]177
178 BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
179 {
180 if( schedule.GetType() == Schedule::Vtbl )
181 {
182 LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
183
184#ifdef _WIN64
185 dataTable.OverwriteInt64(
186 schedule.GetOffset(),
187 vtblMasterListOffset + imageBase + dataSectionBaseOffset
188 );
189#else
190 dataTable.Overwrite(
191 schedule.GetOffset(),
192 vtblMasterListOffset + imageBase + dataSectionBaseOffset
193 );
194#endif
195 }
196 }
[282]197}
198
[355]199void Linker::ResolveTypeInfoSchedule( long dataSectionBaseOffset )
200{
201 BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
202 {
203 if( schedule.GetType() == Schedule::TypeInfo )
204 {
205 LONG_PTR typeInfoDataTableOffset = schedule.GetClass().GetTypeInfoDataTableOffset();
206
207#ifdef _WIN64
208 dataTable.OverwriteInt64(
209 schedule.GetOffset(),
210 typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
211 );
212#else
213 dataTable.Overwrite(
214 schedule.GetOffset(),
215 typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
216 );
217#endif
218 }
219 }
220}
221
[273]222void Linker::Link( ObjectModule &masterObjectModule )
[257]223{
[263]224 // nativeCodeは初期状態でなければならない
225 if( nativeCode.GetSize() > 0 )
226 {
227 SetError();
228 }
229
[287]230 nativeCode.PutEx( masterObjectModule.globalNativeCode );
[257]231
232 masterObjectModule.meta.GetUserProcs().Iterator_Reset();
233 while( masterObjectModule.meta.GetUserProcs().Iterator_HasNext() )
234 {
235 const UserProc *pUserProc = masterObjectModule.meta.GetUserProcs().Iterator_GetNext();
236
[276]237 if( pUserProc->GetNativeCode().GetSize() > 0 )
[257]238 {
239 pUserProc->SetBeginOpAddress( nativeCode.GetSize() );
240
[287]241 nativeCode.PutEx( pUserProc->GetNativeCode() );
[257]242
243 pUserProc->SetEndOpAddress( nativeCode.GetSize() );
244 }
245 }
246}
[355]247
248void Linker::SetDataTable( DataTable &dataTable )
249{
250 this->dataTable.Add( dataTable );
251}
Note: See TracBrowser for help on using the repository browser.