| [224] | 1 | #pragma once | 
|---|
|  | 2 |  | 
|---|
|  | 3 | #include <vector> | 
|---|
|  | 4 |  | 
|---|
| [228] | 5 | #include <jenga/include/common/Exception.h> | 
|---|
|  | 6 |  | 
|---|
| [225] | 7 | #include <BoostSerializationSupport.h> | 
|---|
|  | 8 |  | 
|---|
| [287] | 9 | #include <Binary.h> | 
|---|
|  | 10 |  | 
|---|
| [244] | 11 | class UserProc; | 
|---|
|  | 12 |  | 
|---|
| [224] | 13 | class Schedule | 
|---|
|  | 14 | { | 
|---|
|  | 15 | public: | 
|---|
|  | 16 | enum Type | 
|---|
|  | 17 | { | 
|---|
| [237] | 18 | None = 10000, | 
|---|
| [225] | 19 | GlobalVar,      // グローバル変数スケジュール | 
|---|
| [237] | 20 | DataTable,      // データテーブル スケジュール | 
|---|
| [357] | 21 | CatchAddress,   // Catchアドレス スケジュール | 
|---|
| [225] | 22 | Relocation,     // リロケーション情報スケジュール | 
|---|
| [244] | 23 | UserProc,       // ユーザ定義関数呼び出し側スケジュール | 
|---|
|  | 24 | AddressOf,      // ユーザ定義関数位置スケジュール | 
|---|
| [257] | 25 | DllProc,        // DLL関数位置スケジュール | 
|---|
| [282] | 26 | Vtbl,           // vtblスケジュール | 
|---|
| [355] | 27 | TypeInfo,       // TypeInfoスケジュール | 
|---|
| [224] | 28 | }; | 
|---|
|  | 29 |  | 
|---|
|  | 30 | private: | 
|---|
|  | 31 | Type type; | 
|---|
| [244] | 32 | long offset; | 
|---|
| [224] | 33 |  | 
|---|
| [244] | 34 | union{ | 
|---|
|  | 35 | LONG_PTR lpValue; | 
|---|
|  | 36 | const ::UserProc *pUserProc; | 
|---|
| [250] | 37 | const ::DllProc *pDllProc; | 
|---|
| [282] | 38 | const ::CClass *pClass; | 
|---|
| [244] | 39 | }; | 
|---|
|  | 40 |  | 
|---|
| [224] | 41 | // XMLシリアライズ用 | 
|---|
|  | 42 | private: | 
|---|
|  | 43 | friend class boost::serialization::access; | 
|---|
|  | 44 | template<class Archive> void serialize(Archive& ar, const unsigned int version) | 
|---|
|  | 45 | { | 
|---|
| [256] | 46 | trace_for_serialize( "serializing - Schedule" ); | 
|---|
|  | 47 |  | 
|---|
| [224] | 48 | ar & BOOST_SERIALIZATION_NVP( type ); | 
|---|
|  | 49 | ar & BOOST_SERIALIZATION_NVP( offset ); | 
|---|
| [272] | 50 |  | 
|---|
|  | 51 | switch( type ) | 
|---|
|  | 52 | { | 
|---|
|  | 53 | case UserProc: | 
|---|
|  | 54 | case AddressOf: | 
|---|
| [357] | 55 | case CatchAddress: | 
|---|
| [278] | 56 | ar & boost::serialization::make_nvp("pUserProc", const_cast<::UserProc *&>(pUserProc)); | 
|---|
| [272] | 57 | break; | 
|---|
|  | 58 | case DllProc: | 
|---|
| [278] | 59 | ar & boost::serialization::make_nvp("pDllProc", const_cast<::DllProc *&>(pDllProc)); | 
|---|
| [272] | 60 | break; | 
|---|
| [282] | 61 | case Vtbl: | 
|---|
| [355] | 62 | case TypeInfo: | 
|---|
| [282] | 63 | ar & boost::serialization::make_nvp("pClass", const_cast<::CClass *&>(pClass)); | 
|---|
|  | 64 | break; | 
|---|
| [272] | 65 | default: | 
|---|
|  | 66 | ar & BOOST_SERIALIZATION_NVP( lpValue ); | 
|---|
|  | 67 | break; | 
|---|
|  | 68 | } | 
|---|
| [224] | 69 | } | 
|---|
|  | 70 |  | 
|---|
|  | 71 | public: | 
|---|
|  | 72 | Schedule() | 
|---|
|  | 73 | { | 
|---|
|  | 74 | } | 
|---|
| [258] | 75 | Schedule( Type type, long offset, LONG_PTR lpValue = 0 ) | 
|---|
| [224] | 76 | : type( type ) | 
|---|
|  | 77 | , offset( offset ) | 
|---|
| [258] | 78 | , lpValue( lpValue ) | 
|---|
| [224] | 79 | { | 
|---|
|  | 80 | } | 
|---|
| [258] | 81 | Schedule( const ::UserProc *pUserProc, long offset ) | 
|---|
| [244] | 82 | : type( Schedule::UserProc ) | 
|---|
|  | 83 | , offset( offset ) | 
|---|
|  | 84 | , pUserProc( pUserProc ) | 
|---|
|  | 85 | { | 
|---|
|  | 86 | } | 
|---|
| [258] | 87 | Schedule( const ::DllProc *pDllProc, long offset ) | 
|---|
| [257] | 88 | : type( Schedule::DllProc ) | 
|---|
| [250] | 89 | , offset( offset ) | 
|---|
|  | 90 | , pDllProc( pDllProc ) | 
|---|
|  | 91 | { | 
|---|
|  | 92 | } | 
|---|
| [282] | 93 | Schedule( const ::CClass *pClass, long offset ) | 
|---|
|  | 94 | : type( Schedule::Vtbl ) | 
|---|
|  | 95 | , offset( offset ) | 
|---|
|  | 96 | , pClass( pClass ) | 
|---|
|  | 97 | { | 
|---|
|  | 98 | } | 
|---|
| [355] | 99 | Schedule( Type type, const ::CClass *pClass, long offset ) | 
|---|
|  | 100 | : type( type ) | 
|---|
|  | 101 | , pClass( pClass ) | 
|---|
|  | 102 | , offset( offset ) | 
|---|
|  | 103 | { | 
|---|
|  | 104 | } | 
|---|
| [224] | 105 | ~Schedule() | 
|---|
|  | 106 | { | 
|---|
|  | 107 | } | 
|---|
| [244] | 108 |  | 
|---|
| [257] | 109 | Type GetType() const | 
|---|
|  | 110 | { | 
|---|
|  | 111 | return type; | 
|---|
|  | 112 | } | 
|---|
|  | 113 | long GetOffset() const | 
|---|
|  | 114 | { | 
|---|
|  | 115 | return offset; | 
|---|
|  | 116 | } | 
|---|
| [258] | 117 | LONG_PTR GetLongPtrValue() const | 
|---|
|  | 118 | { | 
|---|
|  | 119 | return lpValue; | 
|---|
|  | 120 | } | 
|---|
| [257] | 121 | const ::DllProc &GetDllProc() const | 
|---|
|  | 122 | { | 
|---|
|  | 123 | if( type != Schedule::DllProc ) | 
|---|
|  | 124 | { | 
|---|
|  | 125 | SetError(); | 
|---|
|  | 126 | } | 
|---|
|  | 127 | return *pDllProc; | 
|---|
|  | 128 | } | 
|---|
|  | 129 | const ::UserProc &GetUserProc() const | 
|---|
|  | 130 | { | 
|---|
| [357] | 131 | if( !( type == Schedule::UserProc || type == Schedule::AddressOf || type == Schedule::CatchAddress ) ) | 
|---|
| [257] | 132 | { | 
|---|
|  | 133 | SetError(); | 
|---|
|  | 134 | } | 
|---|
|  | 135 | return *pUserProc; | 
|---|
|  | 136 | } | 
|---|
| [282] | 137 | const ::CClass &GetClass() const | 
|---|
|  | 138 | { | 
|---|
| [355] | 139 | if( !( type == Schedule::Vtbl || type == Schedule::TypeInfo ) ) | 
|---|
| [282] | 140 | { | 
|---|
|  | 141 | SetError(); | 
|---|
|  | 142 | } | 
|---|
|  | 143 | return *pClass; | 
|---|
|  | 144 | } | 
|---|
| [257] | 145 |  | 
|---|
| [244] | 146 | void SpecifyAddressOf() | 
|---|
|  | 147 | { | 
|---|
|  | 148 | if( type != Schedule::UserProc ) | 
|---|
|  | 149 | { | 
|---|
|  | 150 | SetError(); | 
|---|
|  | 151 | } | 
|---|
|  | 152 | type = Schedule::AddressOf; | 
|---|
|  | 153 | } | 
|---|
| [357] | 154 | void SpecifyCatchAddress() | 
|---|
|  | 155 | { | 
|---|
|  | 156 | if( type != Schedule::UserProc ) | 
|---|
|  | 157 | { | 
|---|
|  | 158 | SetError(); | 
|---|
|  | 159 | } | 
|---|
|  | 160 | type = Schedule::CatchAddress; | 
|---|
|  | 161 | } | 
|---|
| [224] | 162 | }; | 
|---|
|  | 163 | typedef std::vector<Schedule> Schedules; | 
|---|
|  | 164 |  | 
|---|
| [263] | 165 | #define CODETYPE_SYSTEMPROC     0x0001 | 
|---|
|  | 166 | #define CODETYPE_DEBUGPROC      0x0002 | 
|---|
|  | 167 | class SourceLine | 
|---|
|  | 168 | { | 
|---|
|  | 169 | int lineNum; | 
|---|
|  | 170 | long nativeCodePos; | 
|---|
| [280] | 171 | int sourceIndex; | 
|---|
| [263] | 172 | long sourceCodePos; | 
|---|
|  | 173 | DWORD codeType; | 
|---|
|  | 174 |  | 
|---|
|  | 175 | // XMLシリアライズ用 | 
|---|
|  | 176 | private: | 
|---|
|  | 177 | friend class boost::serialization::access; | 
|---|
|  | 178 | template<class Archive> void serialize(Archive& ar, const unsigned int version) | 
|---|
|  | 179 | { | 
|---|
|  | 180 | trace_for_serialize( "serializing - SourceLine" ); | 
|---|
|  | 181 |  | 
|---|
|  | 182 | ar & BOOST_SERIALIZATION_NVP( lineNum ); | 
|---|
|  | 183 | ar & BOOST_SERIALIZATION_NVP( nativeCodePos ); | 
|---|
| [280] | 184 | ar & BOOST_SERIALIZATION_NVP( sourceIndex ); | 
|---|
| [263] | 185 | ar & BOOST_SERIALIZATION_NVP( sourceCodePos ); | 
|---|
|  | 186 | ar & BOOST_SERIALIZATION_NVP( codeType ); | 
|---|
|  | 187 | } | 
|---|
|  | 188 |  | 
|---|
|  | 189 | public: | 
|---|
| [280] | 190 | SourceLine( int lineNum, int nativeCodePos, int sourceIndex, int sourceCodePos, DWORD codeType ) | 
|---|
| [263] | 191 | : lineNum( lineNum ) | 
|---|
|  | 192 | , nativeCodePos( nativeCodePos ) | 
|---|
| [280] | 193 | , sourceIndex( sourceIndex ) | 
|---|
| [263] | 194 | , sourceCodePos( sourceCodePos ) | 
|---|
|  | 195 | , codeType( codeType ) | 
|---|
|  | 196 | { | 
|---|
|  | 197 | } | 
|---|
|  | 198 | SourceLine() | 
|---|
|  | 199 | { | 
|---|
|  | 200 | } | 
|---|
|  | 201 |  | 
|---|
|  | 202 | int GetLineNum() const | 
|---|
|  | 203 | { | 
|---|
|  | 204 | return lineNum; | 
|---|
|  | 205 | } | 
|---|
|  | 206 | long GetNativeCodePos() const | 
|---|
|  | 207 | { | 
|---|
|  | 208 | return nativeCodePos; | 
|---|
|  | 209 | } | 
|---|
| [280] | 210 | int GetSourceIndex() const | 
|---|
|  | 211 | { | 
|---|
|  | 212 | return sourceIndex; | 
|---|
|  | 213 | } | 
|---|
|  | 214 | void SetSourceIndex( int sourceIndex ) | 
|---|
|  | 215 | { | 
|---|
|  | 216 | this->sourceIndex = sourceIndex; | 
|---|
|  | 217 | } | 
|---|
| [263] | 218 | long GetSourceCodePos() const | 
|---|
|  | 219 | { | 
|---|
|  | 220 | return sourceCodePos; | 
|---|
|  | 221 | } | 
|---|
|  | 222 | void SetSourceCodePos( int sourceCodePos ) | 
|---|
|  | 223 | { | 
|---|
|  | 224 | this->sourceCodePos = sourceCodePos; | 
|---|
|  | 225 | } | 
|---|
|  | 226 | DWORD GetCodeType() const | 
|---|
|  | 227 | { | 
|---|
|  | 228 | return codeType; | 
|---|
|  | 229 | } | 
|---|
|  | 230 | bool IsInSystemProc() const | 
|---|
|  | 231 | { | 
|---|
|  | 232 | return ( (codeType&CODETYPE_SYSTEMPROC) != 0 ); | 
|---|
|  | 233 | } | 
|---|
|  | 234 | bool IsInDebugProc() const | 
|---|
|  | 235 | { | 
|---|
|  | 236 | return ( (codeType&CODETYPE_DEBUGPROC) != 0 ); | 
|---|
|  | 237 | } | 
|---|
|  | 238 | }; | 
|---|
|  | 239 | typedef std::vector<SourceLine> SourceLines; | 
|---|
|  | 240 |  | 
|---|
| [287] | 241 | class NativeCode : public Binary | 
|---|
| [224] | 242 | { | 
|---|
| [263] | 243 | // リンカで解決しなければならないスケジュール | 
|---|
| [224] | 244 | Schedules schedules; | 
|---|
|  | 245 |  | 
|---|
| [263] | 246 | // ソースコード行番号とネイティブコード位置の対応情報 | 
|---|
|  | 247 | SourceLines sourceLines; | 
|---|
|  | 248 |  | 
|---|
| [224] | 249 | // XMLシリアライズ用 | 
|---|
|  | 250 | private: | 
|---|
|  | 251 | friend class boost::serialization::access; | 
|---|
| [287] | 252 | template<class Archive> void serialize(Archive& ar, const unsigned int version) | 
|---|
| [224] | 253 | { | 
|---|
| [256] | 254 | trace_for_serialize( "serializing(load) - NativeCode" ); | 
|---|
|  | 255 |  | 
|---|
| [287] | 256 | ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( Binary ); | 
|---|
| [224] | 257 | ar & BOOST_SERIALIZATION_NVP( schedules ); | 
|---|
| [263] | 258 | ar & BOOST_SERIALIZATION_NVP( sourceLines ); | 
|---|
| [224] | 259 | } | 
|---|
| [256] | 260 |  | 
|---|
| [224] | 261 | public: | 
|---|
|  | 262 | NativeCode() | 
|---|
| [287] | 263 | : Binary() | 
|---|
| [224] | 264 | { | 
|---|
|  | 265 | } | 
|---|
| [276] | 266 | NativeCode( const NativeCode &nativeCode ) | 
|---|
| [287] | 267 | : Binary() | 
|---|
| [256] | 268 | { | 
|---|
| [287] | 269 | PutEx( nativeCode ); | 
|---|
| [256] | 270 | } | 
|---|
| [276] | 271 | NativeCode( const char *codeBuffer, int size ) | 
|---|
| [287] | 272 | : Binary( codeBuffer, size ) | 
|---|
| [252] | 273 | { | 
|---|
|  | 274 | } | 
|---|
| [224] | 275 | ~NativeCode() | 
|---|
|  | 276 | { | 
|---|
|  | 277 | } | 
|---|
|  | 278 |  | 
|---|
| [256] | 279 | void operator =( const NativeCode &nativeCode ) | 
|---|
|  | 280 | { | 
|---|
|  | 281 | Clear(); | 
|---|
| [287] | 282 | PutEx( nativeCode ); | 
|---|
| [256] | 283 | } | 
|---|
|  | 284 |  | 
|---|
| [257] | 285 | const Schedules &GetSchedules() const | 
|---|
|  | 286 | { | 
|---|
|  | 287 | return schedules; | 
|---|
|  | 288 | } | 
|---|
| [237] | 289 |  | 
|---|
| [287] | 290 | void PutEx( const NativeCode &nativeCode ); | 
|---|
| [357] | 291 | void PutEx( long l, Schedule::Type scheduleType ); | 
|---|
| [245] | 292 | void PutUserProcSchedule( const UserProc *pUserProc, bool isCall ); | 
|---|
| [357] | 293 | void PutCatchAddressSchedule( const UserProc *pUserProc, long codePos ); | 
|---|
| [250] | 294 | void PutDllProcSchedule( const DllProc *pDllProc ); | 
|---|
| [282] | 295 | void PutVtblSchedule( const CClass *pClass ); | 
|---|
| [263] | 296 |  | 
|---|
| [265] | 297 | const SourceLines &GetSourceLines() const | 
|---|
|  | 298 | { | 
|---|
|  | 299 | return sourceLines; | 
|---|
|  | 300 | } | 
|---|
| [263] | 301 | void NextSourceLine(); | 
|---|
| [273] | 302 |  | 
|---|
|  | 303 | void ResetDataSectionBaseOffset( long dataSectionBaseOffset ); | 
|---|
| [280] | 304 | void ResetSourceIndexes( long sourceIndexBase ); | 
|---|
| [224] | 305 | }; | 
|---|