Changeset 9706 in vbox
- Timestamp:
- Jun 16, 2008 9:29:30 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Disassembler/DisasmCore.cpp
r9676 r9706 251 251 * @param pcbInstruction Where to store the instruction size. Can be NULL. 252 252 */ 253 staticint disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)253 int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction) 254 254 { 255 255 const OPCODE *paOneByteMap; … … 274 274 } 275 275 276 while(1) 277 { 278 uint8_t codebyte = DISReadByte(pCpu, InstructionAddr+iByte); 279 uint8_t opcode = paOneByteMap[codebyte].opcode; 280 281 /* Hardcoded assumption about OP_* values!! */ 282 if (opcode <= OP_LAST_PREFIX) 276 #ifdef IN_RING3 277 # ifndef __L4ENV__ /* Unfortunately, we have no exception handling in l4env */ 278 try 279 # else 280 pCpu->pJumpBuffer = &jumpbuffer; 281 if (setjmp(jumpbuffer) == 0) 282 # endif 283 #endif 284 { 285 while(1) 283 286 { 284 /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */ 285 if (opcode != OP_REX) 287 uint8_t codebyte = DISReadByte(pCpu, InstructionAddr+iByte); 288 uint8_t opcode = paOneByteMap[codebyte].opcode; 289 290 /* Hardcoded assumption about OP_* values!! */ 291 if (opcode <= OP_LAST_PREFIX) 286 292 { 287 /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */ 288 pCpu->lastprefix = opcode; 289 pCpu->prefix &= ~PREFIX_REX; 293 /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */ 294 if (opcode != OP_REX) 295 { 296 /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */ 297 pCpu->lastprefix = opcode; 298 pCpu->prefix &= ~PREFIX_REX; 299 } 300 301 switch (opcode) 302 { 303 case OP_INVALID: 304 AssertMsgFailed(("Invalid opcode!!\n")); 305 return VERR_GENERAL_FAILURE; /** @todo better error code. */ 306 307 // segment override prefix byte 308 case OP_SEG: 309 pCpu->enmPrefixSeg = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START); 310 /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */ 311 if ( pCpu->mode != CPUMODE_64BIT 312 || pCpu->enmPrefixSeg >= DIS_SELREG_FS) 313 { 314 pCpu->prefix |= PREFIX_SEG; 315 } 316 iByte += sizeof(uint8_t); 317 continue; //fetch the next byte 318 319 // lock prefix byte 320 case OP_LOCK: 321 pCpu->prefix |= PREFIX_LOCK; 322 iByte += sizeof(uint8_t); 323 continue; //fetch the next byte 324 325 // address size override prefix byte 326 case OP_ADDRSIZE: 327 pCpu->prefix |= PREFIX_ADDRSIZE; 328 if (pCpu->mode == CPUMODE_16BIT) 329 pCpu->addrmode = CPUMODE_32BIT; 330 else 331 if (pCpu->mode == CPUMODE_32BIT) 332 pCpu->addrmode = CPUMODE_16BIT; 333 else 334 pCpu->addrmode = CPUMODE_32BIT; /* 64 bits */ 335 336 iByte += sizeof(uint8_t); 337 continue; //fetch the next byte 338 339 // operand size override prefix byte 340 case OP_OPSIZE: 341 pCpu->prefix |= PREFIX_OPSIZE; 342 if (pCpu->mode == CPUMODE_16BIT) 343 pCpu->opmode = CPUMODE_32BIT; 344 else 345 pCpu->opmode = CPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */ 346 347 iByte += sizeof(uint8_t); 348 continue; //fetch the next byte 349 350 // rep and repne are not really prefixes, but we'll treat them as such 351 case OP_REPE: 352 pCpu->prefix |= PREFIX_REP; 353 iByte += sizeof(uint8_t); 354 continue; //fetch the next byte 355 356 case OP_REPNE: 357 pCpu->prefix |= PREFIX_REPNE; 358 iByte += sizeof(uint8_t); 359 continue; //fetch the next byte 360 361 case OP_REX: 362 Assert(pCpu->mode == CPUMODE_64BIT); 363 /* REX prefix byte */ 364 pCpu->prefix |= PREFIX_REX; 365 pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1); 366 iByte += sizeof(uint8_t); 367 368 if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W) 369 pCpu->opmode = CPUMODE_64BIT; /* overrides size prefix byte */ 370 continue; //fetch the next byte 371 } 290 372 } 291 373 292 switch (opcode) 293 { 294 case OP_INVALID: 295 AssertMsgFailed(("Invalid opcode!!\n")); 296 return VERR_GENERAL_FAILURE; /** @todo better error code. */ 297 298 // segment override prefix byte 299 case OP_SEG: 300 pCpu->enmPrefixSeg = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START); 301 /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */ 302 if ( pCpu->mode != CPUMODE_64BIT 303 || pCpu->enmPrefixSeg >= DIS_SELREG_FS) 304 { 305 pCpu->prefix |= PREFIX_SEG; 306 } 307 iByte += sizeof(uint8_t); 308 continue; //fetch the next byte 309 310 // lock prefix byte 311 case OP_LOCK: 312 pCpu->prefix |= PREFIX_LOCK; 313 iByte += sizeof(uint8_t); 314 continue; //fetch the next byte 315 316 // address size override prefix byte 317 case OP_ADDRSIZE: 318 pCpu->prefix |= PREFIX_ADDRSIZE; 319 if (pCpu->mode == CPUMODE_16BIT) 320 pCpu->addrmode = CPUMODE_32BIT; 321 else 322 if (pCpu->mode == CPUMODE_32BIT) 323 pCpu->addrmode = CPUMODE_16BIT; 324 else 325 pCpu->addrmode = CPUMODE_32BIT; /* 64 bits */ 326 327 iByte += sizeof(uint8_t); 328 continue; //fetch the next byte 329 330 // operand size override prefix byte 331 case OP_OPSIZE: 332 pCpu->prefix |= PREFIX_OPSIZE; 333 if (pCpu->mode == CPUMODE_16BIT) 334 pCpu->opmode = CPUMODE_32BIT; 335 else 336 pCpu->opmode = CPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */ 337 338 iByte += sizeof(uint8_t); 339 continue; //fetch the next byte 340 341 // rep and repne are not really prefixes, but we'll treat them as such 342 case OP_REPE: 343 pCpu->prefix |= PREFIX_REP; 344 iByte += sizeof(uint8_t); 345 continue; //fetch the next byte 346 347 case OP_REPNE: 348 pCpu->prefix |= PREFIX_REPNE; 349 iByte += sizeof(uint8_t); 350 continue; //fetch the next byte 351 352 case OP_REX: 353 Assert(pCpu->mode == CPUMODE_64BIT); 354 /* REX prefix byte */ 355 pCpu->prefix |= PREFIX_REX; 356 pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1); 357 iByte += sizeof(uint8_t); 358 359 if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W) 360 pCpu->opmode = CPUMODE_64BIT; /* overrides size prefix byte */ 361 continue; //fetch the next byte 362 } 363 } 364 365 unsigned uIdx = iByte; 366 iByte += sizeof(uint8_t); //first opcode byte 367 368 pCpu->opaddr = InstructionAddr + uIdx; 369 pCpu->opcode = codebyte; 370 371 cbInc = ParseInstruction(InstructionAddr + iByte, &paOneByteMap[pCpu->opcode], pCpu); 372 iByte += cbInc; 373 break; 374 } 374 unsigned uIdx = iByte; 375 iByte += sizeof(uint8_t); //first opcode byte 376 377 pCpu->opaddr = InstructionAddr + uIdx; 378 pCpu->opcode = codebyte; 379 380 cbInc = ParseInstruction(InstructionAddr + iByte, &paOneByteMap[pCpu->opcode], pCpu); 381 iByte += cbInc; 382 break; 383 } 384 } 385 #ifdef IN_RING3 386 # ifndef __L4ENV__ 387 catch(...) 388 # else 389 else /* setjmp has returned a non-zero value: an exception occured */ 390 # endif 391 { 392 pCpu->opsize = 0; 393 return VERR_DIS_GEN_FAILURE; 394 } 395 #endif 375 396 376 397 pCpu->opsize = iByte;
Note:
See TracChangeset
for help on using the changeset viewer.