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

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