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

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

例外処理機構実装中…

File size: 6.1 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
58// DLL関数スケジュール
59void Linker::ResolveDllProcSchedules( long codeSectionBaseOffset, long importSectionBaseOffset, long lookupSize, long hintSize )
60{
61 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
62 {
63 if( schedule.GetType() == Schedule::DllProc )
64 {
65#ifdef _AMD64_
66 nativeCode.Overwrite(
67 schedule.GetOffset(),
68 static_cast<long>( importSectionBaseOffset + schedule.GetDllProc().GetLookupAddress()
69 - ( codeSectionBaseOffset + schedule.GetOffset() + sizeof(long) ) )
70 );
71#else
72 nativeCode.Overwrite(
73 schedule.GetOffset(),
74 static_cast<long>( imageBase + importSectionBaseOffset + lookupSize + hintSize
75 + schedule.GetDllProc().GetLookupAddress() )
76 );
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{
117 int allInitVarSize = compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize();
118
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(),
127 static_cast<long>( allInitVarSize + (nativeCode.GetLong( schedule.GetOffset() ) & 0x7FFFFFFF) + imageBase + rwSectionBaseOffset )
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
141void Linker::ResolveVtblSchedule( long dataSectionBaseOffset )
142{
143 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
144 {
145 if( schedule.GetType() == Schedule::Vtbl )
146 {
147 LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
148
149 nativeCode.Overwrite(
150 schedule.GetOffset(),
151 static_cast<long>( vtblMasterListOffset + imageBase + dataSectionBaseOffset )
152 );
153 }
154 }
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 }
175}
176
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
200void Linker::Link( ObjectModule &masterObjectModule )
201{
202 // nativeCodeは初期状態でなければならない
203 if( nativeCode.GetSize() > 0 )
204 {
205 SetError();
206 }
207
208 nativeCode.PutEx( masterObjectModule.globalNativeCode );
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
215 if( pUserProc->GetNativeCode().GetSize() > 0 )
216 {
217 pUserProc->SetBeginOpAddress( nativeCode.GetSize() );
218
219 nativeCode.PutEx( pUserProc->GetNativeCode() );
220
221 pUserProc->SetEndOpAddress( nativeCode.GetSize() );
222 }
223 }
224}
225
226void Linker::SetDataTable( DataTable &dataTable )
227{
228 this->dataTable.Add( dataTable );
229}
Note: See TracBrowser for help on using the repository browser.