source: dev/trunk/abdev/BasicCompiler_Common/include/NativeCode.h@ 279

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

sourceをObjectModuleに入れた

File size: 7.7 KB
RevLine 
[224]1#pragma once
2
3#include <vector>
4
[228]5#include <jenga/include/common/Exception.h>
6
[225]7#include <BoostSerializationSupport.h>
8
[244]9class UserProc;
10
[224]11class Schedule
12{
13public:
14 enum Type
15 {
[237]16 None = 10000,
[225]17 GlobalVar, // グローバル変数スケジュール
[237]18 DataTable, // データテーブル スケジュール
[225]19 Relocation, // リロケーション情報スケジュール
[244]20 UserProc, // ユーザ定義関数呼び出し側スケジュール
21 AddressOf, // ユーザ定義関数位置スケジュール
[257]22 DllProc, // DLL関数位置スケジュール
[224]23 };
24
25private:
26 Type type;
[244]27 long offset;
[224]28
[244]29 union{
30 LONG_PTR lpValue;
31 const ::UserProc *pUserProc;
[250]32 const ::DllProc *pDllProc;
[244]33 };
34
[224]35 // XMLシリアライズ用
36private:
37 friend class boost::serialization::access;
38 template<class Archive> void serialize(Archive& ar, const unsigned int version)
39 {
[256]40 trace_for_serialize( "serializing - Schedule" );
41
[224]42 ar & BOOST_SERIALIZATION_NVP( type );
43 ar & BOOST_SERIALIZATION_NVP( offset );
[272]44
45 switch( type )
46 {
47 case UserProc:
48 case AddressOf:
[278]49 ar & boost::serialization::make_nvp("pUserProc", const_cast<::UserProc *&>(pUserProc));
[272]50 break;
51 case DllProc:
[278]52 ar & boost::serialization::make_nvp("pDllProc", const_cast<::DllProc *&>(pDllProc));
[272]53 break;
54 default:
55 ar & BOOST_SERIALIZATION_NVP( lpValue );
56 break;
57 }
[224]58 }
59
60public:
61 Schedule()
62 {
63 }
[258]64 Schedule( Type type, long offset, LONG_PTR lpValue = 0 )
[224]65 : type( type )
66 , offset( offset )
[258]67 , lpValue( lpValue )
[224]68 {
69 }
[258]70 Schedule( const ::UserProc *pUserProc, long offset )
[244]71 : type( Schedule::UserProc )
72 , offset( offset )
73 , pUserProc( pUserProc )
74 {
75 }
[258]76 Schedule( const ::DllProc *pDllProc, long offset )
[257]77 : type( Schedule::DllProc )
[250]78 , offset( offset )
79 , pDllProc( pDllProc )
80 {
81 }
[224]82 ~Schedule()
83 {
84 }
[244]85
[257]86 Type GetType() const
87 {
88 return type;
89 }
90 long GetOffset() const
91 {
92 return offset;
93 }
[258]94 LONG_PTR GetLongPtrValue() const
95 {
96 return lpValue;
97 }
[257]98 const ::DllProc &GetDllProc() const
99 {
100 if( type != Schedule::DllProc )
101 {
102 SetError();
103 }
104 return *pDllProc;
105 }
106 const ::UserProc &GetUserProc() const
107 {
[258]108 if( !( type == Schedule::UserProc || type == Schedule::AddressOf ) )
[257]109 {
110 SetError();
111 }
112 return *pUserProc;
113 }
114
[244]115 void SpecifyAddressOf()
116 {
117 if( type != Schedule::UserProc )
118 {
119 SetError();
120 }
121 type = Schedule::AddressOf;
122 }
[224]123};
124typedef std::vector<Schedule> Schedules;
125
[263]126#define CODETYPE_SYSTEMPROC 0x0001
127#define CODETYPE_DEBUGPROC 0x0002
128class SourceLine
129{
130 int lineNum;
131 long nativeCodePos;
132 long sourceCodePos;
133 DWORD codeType;
134
135 // XMLシリアライズ用
136private:
137 friend class boost::serialization::access;
138 template<class Archive> void serialize(Archive& ar, const unsigned int version)
139 {
140 trace_for_serialize( "serializing - SourceLine" );
141
142 ar & BOOST_SERIALIZATION_NVP( lineNum );
143 ar & BOOST_SERIALIZATION_NVP( nativeCodePos );
144 ar & BOOST_SERIALIZATION_NVP( sourceCodePos );
145 ar & BOOST_SERIALIZATION_NVP( codeType );
146 }
147
148public:
149 SourceLine( int lineNum, int nativeCodePos, int sourceCodePos, DWORD codeType )
150 : lineNum( lineNum )
151 , nativeCodePos( nativeCodePos )
152 , sourceCodePos( sourceCodePos )
153 , codeType( codeType )
154 {
155 }
156 SourceLine()
157 {
158 }
159
160 int GetLineNum() const
161 {
162 return lineNum;
163 }
164 long GetNativeCodePos() const
165 {
166 return nativeCodePos;
167 }
168 long GetSourceCodePos() const
169 {
170 return sourceCodePos;
171 }
172 void SetSourceCodePos( int sourceCodePos )
173 {
174 this->sourceCodePos = sourceCodePos;
175 }
176 DWORD GetCodeType() const
177 {
178 return codeType;
179 }
180 bool IsInSystemProc() const
181 {
182 return ( (codeType&CODETYPE_SYSTEMPROC) != 0 );
183 }
184 bool IsInDebugProc() const
185 {
186 return ( (codeType&CODETYPE_DEBUGPROC) != 0 );
187 }
188};
189typedef std::vector<SourceLine> SourceLines;
190
[224]191class NativeCode
192{
193 int allocateSize;
194 char *codeBuffer;
195 int size;
196
[263]197 // リンカで解決しなければならないスケジュール
[224]198 Schedules schedules;
199
[263]200 // ソースコード行番号とネイティブコード位置の対応情報
201 SourceLines sourceLines;
202
[224]203 // XMLシリアライズ用
204private:
205 friend class boost::serialization::access;
206 BOOST_SERIALIZATION_SPLIT_MEMBER();
207 template<class Archive> void load(Archive& ar, const unsigned int version)
208 {
[256]209 trace_for_serialize( "serializing(load) - NativeCode" );
210
[224]211 std::string code;
212 ar & BOOST_SERIALIZATION_NVP( code );
213 ar & BOOST_SERIALIZATION_NVP( size );
214 ar & BOOST_SERIALIZATION_NVP( schedules );
[263]215 ar & BOOST_SERIALIZATION_NVP( sourceLines );
[224]216
217 // 読み込み後の処理
218 Realloc( size );
219 for( int i=0; i<size; i++ )
220 {
[279]221 ULONG_PTR l1 = ( ( code[i*3] >= 'a' ) ? ( code[i*3] - 'a' + 0x0a ) : ( code[i*3] - '0' ) ) * 0x10;
222 ULONG_PTR l2 = ( code[i*3+1] >= 'a' ) ? ( code[i*3+1] - 'a' + 0x0a ) : ( code[i*3+1] - '0' );
223 ULONG_PTR l = l1 + l2;
224 codeBuffer[i] = static_cast<char>(l);
[224]225 }
226 }
227 template<class Archive> void save(Archive& ar, const unsigned int version) const
228 {
[256]229 trace_for_serialize( "serializing(save) - NativeCode" );
230
[224]231 // 保存準備
[256]232 char *tempCode = (char *)calloc( (size+1) * 3, 1 );
[224]233 for( int i=0; i<size; i++ )
234 {
235 char temp[32];
[256]236 sprintf( temp, "%02x,", (unsigned char)codeBuffer[i] );
[224]237 tempCode[i*3] = temp[0];
238 tempCode[i*3+1] = temp[1];
239 tempCode[i*3+2] = temp[2];
240 }
241
242 std::string code = tempCode;
243 free( tempCode );
244
245 ar & BOOST_SERIALIZATION_NVP( code );
246 ar & BOOST_SERIALIZATION_NVP( size );
247 ar & BOOST_SERIALIZATION_NVP( schedules );
[263]248 ar & BOOST_SERIALIZATION_NVP( sourceLines );
[224]249 }
250
251
[256]252 void Realloc( int newSize )
[224]253 {
[256]254 if( allocateSize < newSize + 8192 )
[224]255 {
[256]256 while( allocateSize < newSize + 8192 )
[224]257 {
258 allocateSize += 8192;
259 }
260 codeBuffer = (char *)realloc( codeBuffer, allocateSize );
261 }
262 }
263
264public:
265 NativeCode()
266 : allocateSize( 8192 )
267 , codeBuffer( (char *)malloc( allocateSize ) )
268 , size( 0 )
269 {
270 }
[276]271 NativeCode( const NativeCode &nativeCode )
[256]272 : allocateSize( 8192 )
273 , codeBuffer( (char *)malloc( allocateSize ) )
274 , size( 0 )
275 {
[276]276 Put( nativeCode );
[256]277 }
[276]278 NativeCode( const char *codeBuffer, int size )
[252]279 : allocateSize( 8192 )
280 , codeBuffer( (char *)malloc( allocateSize ) )
281 , size( 0 )
282 {
[276]283 Put( codeBuffer, size );
[252]284 }
[224]285 ~NativeCode()
286 {
287 free( codeBuffer );
288 }
289 void Clear()
290 {
291 size = 0;
292 }
293
[256]294 void operator =( const NativeCode &nativeCode )
295 {
296 Clear();
[276]297 Put( nativeCode );
[256]298 }
299
[263]300 const char *GetCodeBuffer() const
301 {
302 return codeBuffer;
303 }
[237]304 int GetSize() const
305 {
306 return size;
307 }
[257]308 const Schedules &GetSchedules() const
309 {
310 return schedules;
311 }
[237]312
[253]313 long GetLong( int codePos ) const
314 {
315 return *(long *)(this->codeBuffer+codePos);
316 }
317
[237]318 void Overwrite( int codePos, char c )
319 {
320 codeBuffer[codePos] = c;
321 }
[241]322 void Overwrite( int codePos, long newLongValue )
323 {
324 *(long *)(this->codeBuffer+codePos) = newLongValue;
325 }
[237]326
[276]327 void Put( const char *codeBuffer, int size )
[224]328 {
[256]329 Realloc( this->size + size );
[224]330
331 memcpy( this->codeBuffer + this->size, codeBuffer, size );
332 this->size += size;
333 }
[276]334 void Put( const NativeCode &nativeCode );
[226]335 void Put( _int64 i64data )
[224]336 {
[226]337 Put( (const char *)(&i64data), sizeof(_int64) );
[224]338 }
339 void Put( long l, Schedule::Type scheduleType = Schedule::None )
340 {
341 if( scheduleType != Schedule::None )
342 {
343 schedules.push_back( Schedule( scheduleType, size ) );
344 }
345
346 *((long *)(codeBuffer+size))=l;
347 size += sizeof(long);
348 }
[245]349 void PutUserProcSchedule( const UserProc *pUserProc, bool isCall );
[250]350 void PutDllProcSchedule( const DllProc *pDllProc );
[226]351 void Put( short s )
352 {
353 Put( (const char *)(&s), sizeof(short) );
354 }
355 void Put( char c )
356 {
[256]357 Realloc( size + 1 );
[226]358 codeBuffer[size++] = c;
359 }
[263]360
[265]361 const SourceLines &GetSourceLines() const
362 {
363 return sourceLines;
364 }
[263]365 void NextSourceLine();
[273]366
367 void ResetDataSectionBaseOffset( long dataSectionBaseOffset );
[224]368};
Note: See TracBrowser for help on using the repository browser.