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 }