00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
#include "ki.h"
00029
00030
00031
00032
00033 ULONGLONG
00034
KiEmulateLoadLong(
00035 IN PULONG UnalignedAddress
00036 );
00037
00038 ULONGLONG
00039
KiEmulateLoadQuad(
00040 IN PUQUAD UnalignedAddress
00041 );
00042
00043 ULONGLONG
00044
KiEmulateLoadFloatIEEESingle(
00045 IN PULONG UnalignedAddress
00046 );
00047
00048 ULONGLONG
00049
KiEmulateLoadFloatIEEEDouble(
00050 IN PUQUAD UnalignedAddress
00051 );
00052
00053
VOID
00054
KiEmulateStoreLong(
00055 IN PULONG UnalignedAddress,
00056 IN ULONGLONG Data
00057 );
00058
00059
VOID
00060
KiEmulateStoreQuad(
00061 IN PUQUAD UnalignedAddress,
00062 IN ULONGLONG Data
00063 );
00064
00065
VOID
00066
KiEmulateStoreFloatIEEESingle(
00067 IN PULONG UnalignedAddress,
00068 IN ULONGLONG Data
00069 );
00070
00071
VOID
00072
KiEmulateStoreFloatIEEEDouble(
00073 IN PUQUAD UnalignedAddress,
00074 IN ULONGLONG Data
00075 );
00076
00077
VOID
00078
KiEnablePALAlignmentFixups(
00079 VOID
00080 );
00081
00082
VOID
00083
KiDisablePALAlignmentFixups(
00084 VOID
00085 );
00086
00087
VOID
00088
KiProfileInterrupt(
00089 IN KPROFILE_SOURCE ProfileSource,
00090 IN PKTRAP_FRAME TrapFrame
00091 );
00092
00093
00094
VOID
00095 KiEnableAlignmentExceptions(
00096 VOID
00097 )
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 {
00118
if (
KeProcessorLevel >= PROCESSOR_ALPHA_21164) {
00119
KiDisablePALAlignmentFixups();
00120 }
00121 }
00122
00123
00124
VOID
00125 KiDisableAlignmentExceptions(
00126 VOID
00127 )
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 {
00152
if ((
KeProcessorLevel >= PROCESSOR_ALPHA_21164) &&
00153 (
KiEnableAlignmentFaultExceptions == 0)) {
00154
KiEnablePALAlignmentFixups();
00155 }
00156 }
00157
00158
00159 BOOLEAN
00160 KiEmulateReference (
00161 IN OUT PEXCEPTION_RECORD ExceptionRecord,
00162 IN OUT PKEXCEPTION_FRAME ExceptionFrame,
00163 IN OUT PKTRAP_FRAME TrapFrame,
00164 IN BOOLEAN QuadwordOnly
00165 )
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 {
00194
00195 ULONGLONG Data;
00196 PVOID EffectiveAddress;
00197 PVOID ExceptionAddress;
00198 ULONG Fa;
00199 ULONG Opcode;
00200
KPROCESSOR_MODE PreviousMode;
00201 ULONG Ra;
00202 KIRQL OldIrql;
00203
00204
00205
00206
00207
if (
KiProfileAlignmentFixup) {
00208
00209
if (++
KiProfileAlignmentFixupCount >=
KiProfileAlignmentFixupInterval) {
00210
00211
KeRaiseIrql(
PROFILE_LEVEL, &OldIrql);
00212
KiProfileAlignmentFixupCount = 0;
00213
KiProfileInterrupt(ProfileAlignmentFixup, TrapFrame);
00214
KeLowerIrql(OldIrql);
00215
00216 }
00217 }
00218
00219
00220
00221
00222
00223 ExceptionAddress = ExceptionRecord->ExceptionAddress;
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 Opcode = (ULONG)ExceptionRecord->ExceptionInformation[0];
00235 Ra = (ULONG)ExceptionRecord->ExceptionInformation[1];
00236 Fa = Ra + 32;
00237 EffectiveAddress = (PVOID)ExceptionRecord->ExceptionInformation[2];
00238
00239
00240
00241
00242
00243 PreviousMode = (
KPROCESSOR_MODE)(((
PSR *)(&TrapFrame->Psr))->MODE);
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
try {
00254
00255
switch (Opcode) {
00256
00257
00258
00259
00260
00261
case LDL_OP:
00262
if (QuadwordOnly !=
FALSE) {
00263
return FALSE;
00264 }
00265
if( PreviousMode !=
KernelMode ){
00266
ProbeForRead( EffectiveAddress,
00267
sizeof(LONG),
00268
sizeof(UCHAR) );
00269 }
00270 Data =
KiEmulateLoadLong( EffectiveAddress );
00271
KiSetRegisterValue( Ra,
00272 Data,
00273 ExceptionFrame,
00274 TrapFrame );
00275
00276
break;
00277
00278
00279
00280
00281
00282
case LDQ_OP:
00283
if( PreviousMode !=
KernelMode ){
00284
ProbeForRead( EffectiveAddress,
00285
sizeof(LONGLONG),
00286
sizeof(UCHAR) );
00287 }
00288 Data =
KiEmulateLoadQuad( EffectiveAddress );
00289
KiSetRegisterValue( Ra,
00290 Data,
00291 ExceptionFrame,
00292 TrapFrame );
00293
00294
break;
00295
00296
00297
00298
00299
00300
case LDS_OP:
00301
if (QuadwordOnly !=
FALSE) {
00302
return FALSE;
00303 }
00304
if( PreviousMode !=
KernelMode ){
00305
ProbeForRead( EffectiveAddress,
00306
sizeof(
float),
00307
sizeof(UCHAR) );
00308 }
00309 Data =
KiEmulateLoadFloatIEEESingle( EffectiveAddress );
00310
KiSetRegisterValue( Fa,
00311 Data,
00312 ExceptionFrame,
00313 TrapFrame );
00314
00315
break;
00316
00317
00318
00319
00320
00321
case LDT_OP:
00322
if( PreviousMode !=
KernelMode ){
00323
ProbeForRead( EffectiveAddress,
00324
sizeof(DOUBLE),
00325
sizeof(UCHAR) );
00326 }
00327 Data =
KiEmulateLoadFloatIEEEDouble( EffectiveAddress );
00328
KiSetRegisterValue( Fa,
00329 Data,
00330 ExceptionFrame,
00331 TrapFrame );
00332
00333
break;
00334
00335
00336
00337
00338
00339
case LDWU_OP :
00340
if (QuadwordOnly !=
FALSE) {
00341
return FALSE;
00342 }
00343
if (PreviousMode !=
KernelMode) {
00344
ProbeForRead(EffectiveAddress,
00345
sizeof(
SHORT),
00346
sizeof(UCHAR));
00347 }
00348 Data = (ULONGLONG)*(UNALIGNED
USHORT *)EffectiveAddress;
00349
KiSetRegisterValue(Ra,
00350 Data,
00351 ExceptionFrame,
00352 TrapFrame);
00353
00354
break;
00355
00356
00357
00358
00359
00360
case STL_OP:
00361
if (QuadwordOnly !=
FALSE) {
00362
return FALSE;
00363 }
00364
if( PreviousMode !=
KernelMode ){
00365
ProbeForWrite( EffectiveAddress,
00366
sizeof(LONG),
00367
sizeof(UCHAR) );
00368 }
00369 Data =
KiGetRegisterValue( Ra,
00370 ExceptionFrame,
00371 TrapFrame );
00372
KiEmulateStoreLong( EffectiveAddress, (ULONG)Data );
00373
00374
break;
00375
00376
00377
00378
00379
00380
case STQ_OP:
00381
if( PreviousMode !=
KernelMode ){
00382
ProbeForWrite( EffectiveAddress,
00383
sizeof(LONGLONG),
00384
sizeof(UCHAR) );
00385 }
00386 Data =
KiGetRegisterValue( Ra,
00387 ExceptionFrame,
00388 TrapFrame );
00389
KiEmulateStoreQuad( EffectiveAddress, Data );
00390
00391
break;
00392
00393
00394
00395
00396
00397
case STS_OP:
00398
if (QuadwordOnly !=
FALSE) {
00399
return FALSE;
00400 }
00401
if( PreviousMode !=
KernelMode ){
00402
ProbeForWrite( EffectiveAddress,
00403
sizeof(
float),
00404
sizeof(UCHAR) );
00405 }
00406 Data =
KiGetRegisterValue( Fa,
00407 ExceptionFrame,
00408 TrapFrame );
00409
KiEmulateStoreFloatIEEESingle( EffectiveAddress, Data );
00410
00411
break;
00412
00413
00414
00415
00416
00417
case STT_OP:
00418
if( PreviousMode !=
KernelMode ){
00419
ProbeForWrite( EffectiveAddress,
00420
sizeof(DOUBLE),
00421
sizeof(UCHAR) );
00422 }
00423 Data =
KiGetRegisterValue( Fa,
00424 ExceptionFrame,
00425 TrapFrame );
00426
KiEmulateStoreFloatIEEEDouble( EffectiveAddress, Data );
00427
00428
break;
00429
00430
00431
00432
00433
00434
case STW_OP :
00435
if (QuadwordOnly !=
FALSE) {
00436
return FALSE;
00437 }
00438
if (PreviousMode !=
KernelMode) {
00439
ProbeForWrite(EffectiveAddress,
00440
sizeof(
SHORT),
00441
sizeof(UCHAR));
00442 }
00443 Data =
KiGetRegisterValue(Ra,
00444 ExceptionFrame,
00445 TrapFrame);
00446 *(UNALIGNED
USHORT *)EffectiveAddress = (
USHORT)Data;
00447
00448
break;
00449
00450
00451
00452
00453
00454
default:
00455
return FALSE;
00456 }
00457
00458 TrapFrame->Fir += 4;
00459
return TRUE;
00460
00461 } except (
KiCopyInformation(ExceptionRecord,
00462 (GetExceptionInformation())->ExceptionRecord)) {
00463
00464
00465
00466
00467
00468 ExceptionRecord->ExceptionAddress = ExceptionAddress;
00469
00470
return FALSE;
00471 }
00472 }
00473