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

Last change on this file since 311 was 288, checked in by dai_9181, 17 years ago
File size: 3.9 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
21// DLL関数スケジュール
22void Linker::ResolveDllProcSchedules( long codeSectionBaseOffset, long importSectionBaseOffset, long lookupSize, long hintSize )
23{
24 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
25 {
26 if( schedule.GetType() == Schedule::DllProc )
27 {
28#ifdef _AMD64_
29 nativeCode.Overwrite(
30 schedule.GetOffset(),
31 static_cast<long>( importSectionBaseOffset + schedule.GetDllProc().GetLookupAddress()
32 - ( codeSectionBaseOffset + schedule.GetOffset() + sizeof(long) ) )
33 );
34#else
35 nativeCode.Overwrite(
36 schedule.GetOffset(),
37 static_cast<long>( imageBase + importSectionBaseOffset + lookupSize + hintSize
38 + schedule.GetDllProc().GetLookupAddress() )
39 );
40#endif
41 }
42 }
43}
44
45// ユーザ定義関数スケジュール
46void Linker::ResolveUserProcSchedules( long codeSectionBaseOffset )
47{
48 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
49 {
50 if( schedule.GetType() == Schedule::UserProc
51 || schedule.GetType() == Schedule::AddressOf )
52 {
53 if( schedule.GetUserProc().GetBeginOpAddress() == 0
54 && schedule.GetUserProc().GetEndOpAddress() == 0 )
55 {
56 SetError();
57 }
58
59 if( schedule.GetType() == Schedule::UserProc )
60 {
61 nativeCode.Overwrite(
62 schedule.GetOffset(),
63 static_cast<long>( schedule.GetUserProc().GetBeginOpAddress() - ( schedule.GetOffset() + sizeof(long) ) )
64 );
65 }
66 else if( schedule.GetType() == Schedule::AddressOf )
67 {
68 nativeCode.Overwrite(
69 schedule.GetOffset(),
70 static_cast<long>( schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset )
71 );
72 }
73 }
74 }
75}
76
77// グローバル変数スケジュール
78void Linker::ResolveGlobalVarSchedules( long rwSectionBaseOffset )
79{
80 int allInitVarSize = compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize();
81
82 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
83 {
84 if( schedule.GetType() == Schedule::GlobalVar )
85 {
86 if( nativeCode.GetLong( schedule.GetOffset() ) & 0x80000000 )
87 {
88 nativeCode.Overwrite(
89 schedule.GetOffset(),
90 static_cast<long>( allInitVarSize + (nativeCode.GetLong( schedule.GetOffset() ) & 0x7FFFFFFF) + imageBase + rwSectionBaseOffset )
91 );
92 }
93 else
94 {
95 nativeCode.Overwrite(
96 schedule.GetOffset(),
97 static_cast<long>( nativeCode.GetLong( schedule.GetOffset() ) + imageBase + rwSectionBaseOffset )
98 );
99 }
100 }
101 }
102}
103
104void Linker::ResolveVtblSchedule( long dataSectionBaseOffset )
105{
106 BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() )
107 {
108 if( schedule.GetType() == Schedule::Vtbl )
109 {
110 LONG_PTR vtblAddress = schedule.GetClass().GetVtblGlobalOffset();
111
112 nativeCode.Overwrite(
113 schedule.GetOffset(),
114 static_cast<long>( vtblAddress + imageBase + dataSectionBaseOffset )
115 );
116 }
117 }
118}
119
120void Linker::Link( ObjectModule &masterObjectModule )
121{
122 // nativeCodeは初期状態でなければならない
123 if( nativeCode.GetSize() > 0 )
124 {
125 SetError();
126 }
127
128 nativeCode.PutEx( masterObjectModule.globalNativeCode );
129
130 masterObjectModule.meta.GetUserProcs().Iterator_Reset();
131 while( masterObjectModule.meta.GetUserProcs().Iterator_HasNext() )
132 {
133 const UserProc *pUserProc = masterObjectModule.meta.GetUserProcs().Iterator_GetNext();
134
135 if( pUserProc->GetNativeCode().GetSize() > 0 )
136 {
137 pUserProc->SetBeginOpAddress( nativeCode.GetSize() );
138
139 nativeCode.PutEx( pUserProc->GetNativeCode() );
140
141 pUserProc->SetEndOpAddress( nativeCode.GetSize() );
142 }
143 }
144}
Note: See TracBrowser for help on using the repository browser.