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

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

例外処理機構実装中...

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