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

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

デバッガ変数リストのローカル変数のスコープ判定が間違っていたため、修正。

File size: 7.7 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    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    }
78}
79
80// DLL関数スケジュール
81void Linker::ResolveDllProcSchedules( long codeSectionBaseOffset, long importSectionBaseOffset, long lookupSize, long hintSize )
82{
83    BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
84    {
85        if( schedule.GetType() == Schedule::DllProc )
86        {
87#ifdef _AMD64_
88            nativeCode.Overwrite(
89                schedule.GetOffset(),
90                static_cast<long>( importSectionBaseOffset + schedule.GetDllProc().GetLookupAddress()
91                    - ( codeSectionBaseOffset + schedule.GetOffset() + sizeof(long) ) )
92            );
93#else
94            nativeCode.Overwrite(
95                schedule.GetOffset(),
96                static_cast<long>( imageBase + importSectionBaseOffset + lookupSize + hintSize
97                    + schedule.GetDllProc().GetLookupAddress() )
98            );
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{
139    int allInitVarSize = compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize();
140
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(),
149                    static_cast<long>( allInitVarSize + (nativeCode.GetLong( schedule.GetOffset() ) & 0x7FFFFFFF) + imageBase + rwSectionBaseOffset )
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
163void Linker::ResolveVtblSchedule( long dataSectionBaseOffset )
164{
165    BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
166    {
167        if( schedule.GetType() == Schedule::ComVtbl )
168        {
169            LONG_PTR vtblOffset = schedule.GetClass().GetComVtblOffset();
170
171            nativeCode.Overwrite(
172                schedule.GetOffset(),
173                static_cast<long>( vtblOffset + imageBase + dataSectionBaseOffset )
174            );
175        }
176
177        if( schedule.GetType() == Schedule::Vtbl )
178        {
179            LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
180
181            nativeCode.Overwrite(
182                schedule.GetOffset(),
183                static_cast<long>( vtblMasterListOffset + imageBase + dataSectionBaseOffset )
184            );
185        }
186    }
187
188    BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
189    {
190        if( schedule.GetType() == Schedule::ComVtbl )
191        {
192            LONG_PTR vtblOffset = schedule.GetClass().GetComVtblOffset();
193
194#ifdef _WIN64
195            dataTable.OverwriteInt64(
196                schedule.GetOffset(),
197                vtblOffset + imageBase + dataSectionBaseOffset
198            );
199#else
200            dataTable.Overwrite(
201                schedule.GetOffset(),
202                vtblOffset + imageBase + dataSectionBaseOffset
203            );
204#endif
205        }
206
207        if( schedule.GetType() == Schedule::Vtbl )
208        {
209            LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset();
210
211#ifdef _WIN64
212            dataTable.OverwriteInt64(
213                schedule.GetOffset(),
214                vtblMasterListOffset + imageBase + dataSectionBaseOffset
215            );
216#else
217            dataTable.Overwrite(
218                schedule.GetOffset(),
219                vtblMasterListOffset + imageBase + dataSectionBaseOffset
220            );
221#endif
222        }
223    }
224}
225
226void Linker::ResolveTypeInfoSchedule( long dataSectionBaseOffset )
227{
228    BOOST_FOREACH( const Schedule &schedule, dataTable.schedules )
229    {
230        if( schedule.GetType() == Schedule::TypeInfo )
231        {
232            LONG_PTR typeInfoDataTableOffset = schedule.GetClass().GetTypeInfoDataTableOffset();
233
234#ifdef _WIN64
235            dataTable.OverwriteInt64(
236                schedule.GetOffset(),
237                typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
238            );
239#else
240            dataTable.Overwrite(
241                schedule.GetOffset(),
242                typeInfoDataTableOffset + imageBase + dataSectionBaseOffset
243            );
244#endif
245        }
246    }
247}
248
249void Linker::Link( ObjectModule &masterObjectModule )
250{
251    // nativeCodeは初期状態でなければならない
252    if( nativeCode.GetSize() > 0 )
253    {
254        SetError();
255    }
256
257    nativeCode.PutEx( masterObjectModule.globalNativeCode );
258
259    masterObjectModule.meta.GetUserProcs().Iterator_Reset();
260    while( masterObjectModule.meta.GetUserProcs().Iterator_HasNext() )
261    {
262        const UserProc *pUserProc = masterObjectModule.meta.GetUserProcs().Iterator_GetNext();
263
264        if( pUserProc->GetNativeCode().GetSize() > 0 )
265        {
266            // 関数の開始位置(コードセクションからのオフセット)
267            int beginCodePos = nativeCode.GetSize();
268
269            // コードセクションに関数のネイティブコードを追加
270            nativeCode.PutEx( pUserProc->GetNativeCode() );
271
272            // 関数の終了位置(コードセクションからのオフセット)
273            int endCodePos = nativeCode.GetSize();
274
275            // コードセクション内の関数の範囲を設定
276            pUserProc->SetBeginOpAddress( beginCodePos );
277            pUserProc->SetEndOpAddress( endCodePos );
278        }
279    }
280}
281
282void Linker::SetDataTable( DataTable &dataTable )
283{
284    this->dataTable.Add( dataTable );
285}
Note: See TracBrowser for help on using the repository browser.