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

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

例外処理機構実装中…

File size: 6.1 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 }
56}
57
[257]58// DLL関数スケジュール
[258]59void Linker::ResolveDllProcSchedules( long codeSectionBaseOffset, long importSectionBaseOffset, long lookupSize, long hintSize )
[257]60{
61 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
62 {
63 if( schedule.GetType() == Schedule::DllProc )
64 {
[263]65#ifdef _AMD64_
[257]66 nativeCode.Overwrite(
67 schedule.GetOffset(),
68 static_cast<long>( importSectionBaseOffset + schedule.GetDllProc().GetLookupAddress()
69 - ( codeSectionBaseOffset + schedule.GetOffset() + sizeof(long) ) )
70 );
71#else
[258]72 nativeCode.Overwrite(
73 schedule.GetOffset(),
74 static_cast<long>( imageBase + importSectionBaseOffset + lookupSize + hintSize
75 + schedule.GetDllProc().GetLookupAddress() )
76 );
[257]77#endif
78 }
79 }
80}
81
82// ユーザ定義関数スケジュール
83void Linker::ResolveUserProcSchedules( long codeSectionBaseOffset )
84{
85 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
86 {
87 if( schedule.GetType() == Schedule::UserProc
88 || schedule.GetType() == Schedule::AddressOf )
89 {
90 if( schedule.GetUserProc().GetBeginOpAddress() == 0
91 && schedule.GetUserProc().GetEndOpAddress() == 0 )
92 {
93 SetError();
94 }
95
96 if( schedule.GetType() == Schedule::UserProc )
97 {
98 nativeCode.Overwrite(
99 schedule.GetOffset(),
100 static_cast<long>( schedule.GetUserProc().GetBeginOpAddress() - ( schedule.GetOffset() + sizeof(long) ) )
101 );
102 }
103 else if( schedule.GetType() == Schedule::AddressOf )
104 {
105 nativeCode.Overwrite(
106 schedule.GetOffset(),
107 static_cast<long>( schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset )
108 );
109 }
110 }
111 }
112}
113
114// グローバル変数スケジュール
115void Linker::ResolveGlobalVarSchedules( long rwSectionBaseOffset )
116{
[288]117 int allInitVarSize = compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize();
[273]118
[257]119 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
120 {
121 if( schedule.GetType() == Schedule::GlobalVar )
122 {
123 if( nativeCode.GetLong( schedule.GetOffset() ) & 0x80000000 )
124 {
125 nativeCode.Overwrite(
126 schedule.GetOffset(),
[273]127 static_cast<long>( allInitVarSize + (nativeCode.GetLong( schedule.GetOffset() ) & 0x7FFFFFFF) + imageBase + rwSectionBaseOffset )
[257]128 );
129 }
130 else
131 {
132 nativeCode.Overwrite(
133 schedule.GetOffset(),
134 static_cast<long>( nativeCode.GetLong( schedule.GetOffset() ) + imageBase + rwSectionBaseOffset )
135 );
136 }
137 }
138 }
139}
140
[282]141void Linker::ResolveVtblSchedule( long dataSectionBaseOffset )
142{
143 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
144 {
145 if( schedule.GetType() == Schedule::Vtbl )
146 {
[342]147 LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
[282]148
149 nativeCode.Overwrite(
150 schedule.GetOffset(),
[342]151 static_cast<long>( vtblMasterListOffset + imageBase + dataSectionBaseOffset )
[282]152 );
153 }
154 }
[355]155
156 BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
157 {
158 if( schedule.GetType() == Schedule::Vtbl )
159 {
160 LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
161
162#ifdef _WIN64
163 dataTable.OverwriteInt64(
164 schedule.GetOffset(),
165 vtblMasterListOffset + imageBase + dataSectionBaseOffset
166 );
167#else
168 dataTable.Overwrite(
169 schedule.GetOffset(),
170 vtblMasterListOffset + imageBase + dataSectionBaseOffset
171 );
172#endif
173 }
174 }
[282]175}
176
[355]177void Linker::ResolveTypeInfoSchedule( long dataSectionBaseOffset )
178{
179 BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
180 {
181 if( schedule.GetType() == Schedule::TypeInfo )
182 {
183 LONG_PTR typeInfoDataTableOffset = schedule.GetClass().GetTypeInfoDataTableOffset();
184
185#ifdef _WIN64
186 dataTable.OverwriteInt64(
187 schedule.GetOffset(),
188 typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
189 );
190#else
191 dataTable.Overwrite(
192 schedule.GetOffset(),
193 typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
194 );
195#endif
196 }
197 }
198}
199
[273]200void Linker::Link( ObjectModule &masterObjectModule )
[257]201{
[263]202 // nativeCodeは初期状態でなければならない
203 if( nativeCode.GetSize() > 0 )
204 {
205 SetError();
206 }
207
[287]208 nativeCode.PutEx( masterObjectModule.globalNativeCode );
[257]209
210 masterObjectModule.meta.GetUserProcs().Iterator_Reset();
211 while( masterObjectModule.meta.GetUserProcs().Iterator_HasNext() )
212 {
213 const UserProc *pUserProc = masterObjectModule.meta.GetUserProcs().Iterator_GetNext();
214
[276]215 if( pUserProc->GetNativeCode().GetSize() > 0 )
[257]216 {
217 pUserProc->SetBeginOpAddress( nativeCode.GetSize() );
218
[287]219 nativeCode.PutEx( pUserProc->GetNativeCode() );
[257]220
221 pUserProc->SetEndOpAddress( nativeCode.GetSize() );
222 }
223 }
224}
[355]225
226void Linker::SetDataTable( DataTable &dataTable )
227{
228 this->dataTable.Add( dataTable );
229}
Note: See TracBrowser for help on using the repository browser.