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

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

静的領域に初期オブジェクトを配置可能にした

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