Mercurial > hg > truffle
comparison graal/com.oracle.max.asmdis/src/com/sun/max/asm/dis/x86/X86Disassembler.java @ 4142:bc8527f3071c
Adjust code base to new level of warnings.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sun, 18 Dec 2011 05:24:06 +0100 |
parents | e233f5660da4 |
children |
comparison
equal
deleted
inserted
replaced
4141:04d21be7a24f | 4142:bc8527f3071c |
---|---|
160 break; | 160 break; |
161 } | 161 } |
162 byteValue = stream.read(); | 162 byteValue = stream.read(); |
163 } while (byteValue >= 0); | 163 } while (byteValue >= 0); |
164 | 164 |
165 if (TRACE && !justSkip) { | |
166 System.out.println("Scanned header: " + header); | |
167 } | |
168 | |
169 return justSkip ? null : header; | 165 return justSkip ? null : header; |
170 } | 166 } |
171 | 167 |
172 private List<Argument> scanArguments(BufferedInputStream stream, X86Template template, X86InstructionHeader header, byte modRMByte, byte sibByte) throws IOException { | 168 private List<Argument> scanArguments(BufferedInputStream stream, X86Template template, X86InstructionHeader header, byte modRMByte, byte sibByte) throws IOException { |
173 final List<Argument> arguments = new ArrayList<Argument>(); | 169 final List<Argument> arguments = new ArrayList<>(); |
174 final byte rexByte = (header.rexPrefix != null) ? header.rexPrefix.byteValue() : 0; | 170 final byte rexByte = (header.rexPrefix != null) ? header.rexPrefix.byteValue() : 0; |
175 for (X86Parameter parameter : template.parameters()) { | 171 for (X86Parameter parameter : template.parameters()) { |
176 int value = 0; | 172 int value = 0; |
177 switch (parameter.place()) { | 173 switch (parameter.place()) { |
178 case MOD_REG_REXR: | 174 case MOD_REG_REXR: |
247 } | 243 } |
248 } | 244 } |
249 return arguments; | 245 return arguments; |
250 } | 246 } |
251 | 247 |
252 private int getModVariantParameterIndex(X86Template template, byte modRMByte, byte sibByte) { | 248 private static int getModVariantParameterIndex(X86Template template, byte modRMByte, byte sibByte) { |
253 if (template.modCase() == X86TemplateContext.ModCase.MOD_0 && X86Field.MOD.extract(modRMByte) != X86TemplateContext.ModCase.MOD_0.value()) { | 249 if (template.modCase() == X86TemplateContext.ModCase.MOD_0 && X86Field.MOD.extract(modRMByte) != X86TemplateContext.ModCase.MOD_0.value()) { |
254 switch (template.rmCase()) { | 250 switch (template.rmCase()) { |
255 case NORMAL: { | 251 case NORMAL: { |
256 if (template.addressSizeAttribute() == WordWidth.BITS_16) { | 252 if (template.addressSizeAttribute() == WordWidth.BITS_16) { |
257 if (X86Field.RM.extract(modRMByte) != X86TemplateContext.RMCase.SWORD.value()) { | 253 if (X86Field.RM.extract(modRMByte) != X86TemplateContext.RMCase.SWORD.value()) { |
355 continue; | 351 continue; |
356 } | 352 } |
357 | 353 |
358 // Remove the mod variant argument | 354 // Remove the mod variant argument |
359 final Argument modVariantArgument = arguments.get(modVariantParameterIndex); | 355 final Argument modVariantArgument = arguments.get(modVariantParameterIndex); |
360 final List<Argument> result = new ArrayList<Argument>(); | 356 final List<Argument> result = new ArrayList<>(); |
361 for (Argument argument : arguments) { | 357 for (Argument argument : arguments) { |
362 if (modVariantArgument != argument) { | 358 if (modVariantArgument != argument) { |
363 result.add(argument); | 359 result.add(argument); |
364 } | 360 } |
365 } | 361 } |
366 arguments = result; | 362 arguments = result; |
367 } | 363 } |
368 if (!(Utils.indexOfIdentical(arguments, null) != -1)) { | 364 if (!(Utils.indexOfIdentical(arguments, null) != -1)) { |
369 byte[] bytes; | 365 byte[] bytes; |
370 if (true) { | 366 final Assembler assembler = createAssembler(currentPosition); |
371 final Assembler assembler = createAssembler(currentPosition); | 367 try { |
372 try { | 368 assembly.assemble(assembler, template, arguments); |
373 assembly.assemble(assembler, template, arguments); | 369 } catch (AssemblyException e) { |
374 } catch (AssemblyException e) { | 370 // try the next template |
375 // try the next template | 371 continue; |
376 continue; | |
377 } | |
378 bytes = assembler.toByteArray(); | |
379 } else { // TODO: does not work yet | |
380 final X86TemplateAssembler templateAssembler = new X86TemplateAssembler(template, addressWidth()); | |
381 bytes = templateAssembler.assemble(arguments); | |
382 } | 372 } |
373 bytes = assembler.toByteArray(); | |
383 if (bytes != null) { | 374 if (bytes != null) { |
384 stream.reset(); | 375 stream.reset(); |
385 if (Streams.startsWith(stream, bytes)) { | 376 if (Streams.startsWith(stream, bytes)) { |
386 final DisassembledInstruction disassembledInstruction = createDisassembledInstruction(currentPosition, bytes, template, arguments); | 377 final DisassembledInstruction disassembledInstruction = createDisassembledInstruction(currentPosition, bytes, template, arguments); |
387 currentPosition += bytes.length; | 378 currentPosition += bytes.length; |
414 final DisassembledInstruction disassembledInstruction = createDisassembledInstruction(currentPosition, bytes, template, empty); | 405 final DisassembledInstruction disassembledInstruction = createDisassembledInstruction(currentPosition, bytes, template, empty); |
415 currentPosition++; | 406 currentPosition++; |
416 return disassembledInstruction; | 407 return disassembledInstruction; |
417 } | 408 } |
418 } | 409 } |
419 if (INLINE_INVALID_INSTRUCTIONS_AS_BYTES) { | 410 |
420 stream.reset(); | 411 stream.reset(); |
421 final int size = 1; | 412 final int size = 1; |
422 final byte[] data = new byte[size]; | 413 final byte[] data = new byte[size]; |
423 Streams.readFully(stream, data); | 414 Streams.readFully(stream, data); |
424 final InlineData inlineData = new InlineData(currentPosition, data); | 415 final InlineData inlineData = new InlineData(currentPosition, data); |
425 final DisassembledData disassembledData = createDisassembledDataObjects(inlineData).iterator().next(); | 416 final DisassembledData disassembledData = createDisassembledDataObjects(inlineData).iterator().next(); |
426 currentPosition += size; | 417 currentPosition += size; |
427 return disassembledData; | 418 return disassembledData; |
428 } | |
429 throw new AssemblyException("unknown instruction"); | |
430 } | 419 } |
431 | 420 |
432 /** | 421 /** |
433 * Creates a disassembled instruction based on a given sequence of bytes, a template and a set of arguments. The | 422 * Creates a disassembled instruction based on a given sequence of bytes, a template and a set of arguments. The |
434 * caller has performed the necessary decoding of the bytes to derive the template and arguments. | 423 * caller has performed the necessary decoding of the bytes to derive the template and arguments. |
442 protected X86DisassembledInstruction createDisassembledInstruction(int position, byte[] bytes, X86Template template, List<Argument> arguments) { | 431 protected X86DisassembledInstruction createDisassembledInstruction(int position, byte[] bytes, X86Template template, List<Argument> arguments) { |
443 return new X86DisassembledInstruction(this, position, bytes, template, arguments); | 432 return new X86DisassembledInstruction(this, position, bytes, template, arguments); |
444 } | 433 } |
445 | 434 |
446 private static final int MORE_THAN_ANY_INSTRUCTION_LENGTH = 100; | 435 private static final int MORE_THAN_ANY_INSTRUCTION_LENGTH = 100; |
447 private static final boolean INLINE_INVALID_INSTRUCTIONS_AS_BYTES = true; | |
448 | |
449 @Override | 436 @Override |
450 public List<DisassembledObject> scanOne0(BufferedInputStream stream) throws IOException, AssemblyException { | 437 public List<DisassembledObject> scanOne0(BufferedInputStream stream) throws IOException, AssemblyException { |
451 final List<DisassembledObject> disassembledObjects = new ArrayList<DisassembledObject>(); | 438 final List<DisassembledObject> disassembledObjects = new ArrayList<>(); |
452 stream.mark(MORE_THAN_ANY_INSTRUCTION_LENGTH); | 439 stream.mark(MORE_THAN_ANY_INSTRUCTION_LENGTH); |
453 final X86InstructionHeader header = scanInstructionHeader(stream, false); | 440 final X86InstructionHeader header = scanInstructionHeader(stream, false); |
454 if (header == null) { | 441 if (header == null) { |
455 throw new AssemblyException("unknown instruction"); | 442 throw new AssemblyException("unknown instruction"); |
456 } | 443 } |
458 return disassembledObjects; | 445 return disassembledObjects; |
459 } | 446 } |
460 | 447 |
461 @Override | 448 @Override |
462 public List<DisassembledObject> scan0(BufferedInputStream stream) throws IOException, AssemblyException { | 449 public List<DisassembledObject> scan0(BufferedInputStream stream) throws IOException, AssemblyException { |
463 final SortedSet<Integer> knownGoodCodePositions = new TreeSet<Integer>(); | 450 final SortedSet<Integer> knownGoodCodePositions = new TreeSet<>(); |
464 final List<DisassembledObject> result = new ArrayList<DisassembledObject>(); | 451 final List<DisassembledObject> result = new ArrayList<>(); |
465 boolean processingKnownValidCode = true; | 452 boolean processingKnownValidCode = true; |
466 | 453 |
467 while (true) { | 454 while (true) { |
468 while (knownGoodCodePositions.size() > 0 && knownGoodCodePositions.first().intValue() < currentPosition) { | 455 while (knownGoodCodePositions.size() > 0 && knownGoodCodePositions.first().intValue() < currentPosition) { |
469 knownGoodCodePositions.remove(knownGoodCodePositions.first()); | 456 knownGoodCodePositions.remove(knownGoodCodePositions.first()); |
516 result.add(disassembledObject); | 503 result.add(disassembledObject); |
517 } | 504 } |
518 } | 505 } |
519 } | 506 } |
520 | 507 |
521 private boolean isRelativeJumpForward(DisassembledInstruction instruction) { | 508 private static boolean isRelativeJumpForward(DisassembledInstruction instruction) { |
522 return instruction.template().internalName().equals("jmp") && // check if this is a jump instruction... | 509 return instruction.template().internalName().equals("jmp") && // check if this is a jump instruction... |
523 instruction.arguments().size() == 1 && // that accepts one operand... | 510 instruction.arguments().size() == 1 && // that accepts one operand... |
524 ((Utils.first(instruction.arguments()) instanceof Immediate32Argument && // which is a relative offset... | 511 ((Utils.first(instruction.arguments()) instanceof Immediate32Argument && // which is a relative offset... |
525 ((Immediate32Argument) Utils.first(instruction.arguments())).value() >= 0) || // forward in the code stream | 512 ((Immediate32Argument) Utils.first(instruction.arguments())).value() >= 0) || // forward in the code stream |
526 (Utils.first(instruction.arguments()) instanceof Immediate8Argument && // which is a relative offset... | 513 (Utils.first(instruction.arguments()) instanceof Immediate8Argument && // which is a relative offset... |
537 return di.template().externalName(); | 524 return di.template().externalName(); |
538 } | 525 } |
539 | 526 |
540 @Override | 527 @Override |
541 public String operandsToString(DisassembledInstruction di, AddressMapper addressMapper) { | 528 public String operandsToString(DisassembledInstruction di, AddressMapper addressMapper) { |
542 final LinkedList<X86Operand> operandQueue = new LinkedList<X86Operand>(); | 529 final LinkedList<X86Operand> operandQueue = new LinkedList<>(); |
543 for (Operand operand : di.template().operands()) { | 530 for (Operand operand : di.template().operands()) { |
544 operandQueue.add((X86Operand) operand); | 531 operandQueue.add((X86Operand) operand); |
545 } | 532 } |
546 final LinkedList<Argument> argumentQueue = new LinkedList<Argument>(di.arguments()); | 533 final LinkedList<Argument> argumentQueue = new LinkedList<>(di.arguments()); |
547 String result = ""; | 534 String result = ""; |
548 String separator = ""; | 535 String separator = ""; |
549 while (!operandQueue.isEmpty()) { | 536 while (!operandQueue.isEmpty()) { |
550 result += separator + getOperand(di, operandQueue, argumentQueue, addressMapper); | 537 result += separator + getOperand(di, operandQueue, argumentQueue, addressMapper); |
551 separator = ", "; | 538 separator = ", "; |
560 s = " " + s; | 547 s = " " + s; |
561 } | 548 } |
562 return Strings.padLengthWithSpaces(mnemonic(di), 8) + s; | 549 return Strings.padLengthWithSpaces(mnemonic(di), 8) + s; |
563 } | 550 } |
564 | 551 |
565 private String getSibIndexAndScale(Queue<X86Operand> operands, Queue<Argument> arguments) { | 552 private static String getSibIndexAndScale(Queue<X86Operand> operands, Queue<Argument> arguments) { |
566 X86Parameter parameter = (X86Parameter) operands.remove(); | 553 X86Parameter parameter = (X86Parameter) operands.remove(); |
567 assert parameter.place() == ParameterPlace.SIB_INDEX || parameter.place() == ParameterPlace.SIB_INDEX_REXX; | 554 assert parameter.place() == ParameterPlace.SIB_INDEX || parameter.place() == ParameterPlace.SIB_INDEX_REXX; |
568 final String result = arguments.remove().disassembledValue(); | 555 final String result = arguments.remove().disassembledValue(); |
569 parameter = (X86Parameter) operands.remove(); | 556 parameter = (X86Parameter) operands.remove(); |
570 assert parameter.place() == ParameterPlace.SIB_SCALE; | 557 assert parameter.place() == ParameterPlace.SIB_SCALE; |
573 return result; | 560 return result; |
574 } | 561 } |
575 return result + " * " + scale.disassembledValue(); | 562 return result + " * " + scale.disassembledValue(); |
576 } | 563 } |
577 | 564 |
578 private String addition(Argument argument, String space) { | 565 private static String addition(Argument argument, String space) { |
579 assert argument instanceof ImmediateArgument; | 566 assert argument instanceof ImmediateArgument; |
580 final long value = argument.asLong(); | 567 final long value = argument.asLong(); |
581 final String s = Long.toString(value); | 568 final String s = Long.toString(value); |
582 if (value >= 0) { | 569 if (value >= 0) { |
583 return "+" + space + s; | 570 return "+" + space + s; |
584 } | 571 } |
585 return "-" + space + s.substring(1); | 572 return "-" + space + s.substring(1); |
586 } | 573 } |
587 | 574 |
588 private String getOperand(DisassembledInstruction di, Queue<X86Operand> operands, Queue<Argument> arguments, AddressMapper addressMapper) { | 575 private static String getOperand(DisassembledInstruction di, Queue<X86Operand> operands, Queue<Argument> arguments, AddressMapper addressMapper) { |
589 final X86Operand operand = operands.remove(); | 576 final X86Operand operand = operands.remove(); |
590 if (operand instanceof ImplicitOperand) { | 577 if (operand instanceof ImplicitOperand) { |
591 final ImplicitOperand implicitOperand = (ImplicitOperand) operand; | 578 final ImplicitOperand implicitOperand = (ImplicitOperand) operand; |
592 return implicitOperand.argument().disassembledValue(); | 579 return implicitOperand.argument().disassembledValue(); |
593 } | 580 } |