00169 :
00170
00171 Routine emulates an unaligned data reference from user part
00172 of
the address space.
00173
00174 Arguments:
00175
00176 ExceptionRecord - Supplies a pointer to
the exception record.
00177
00178 ExceptionFrame - Supplies a pointer to an exception frame.
00179
00180 TrapFrame - Supplies a pointer to a trap frame
00181
00182 QuadwordOnly - Supplies a
boolean which controls whether both longword
00183 and quadword references are to be emulated or quadword references
00184
only.
00185
00186 Return Value:
00187
00188 True
is returned
if reference
is successfully emulated,
00189 otherwise False
is returned.
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 }
}