diff agent/src/share/classes/sun/jvm/hotspot/debugger/DebuggerUtilities.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/DebuggerUtilities.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger;
+
+/** Common routines for data conversion */
+
+public class DebuggerUtilities {
+  protected long addressSize;
+  protected boolean isBigEndian;
+
+  public DebuggerUtilities(long addressSize, boolean isBigEndian) {
+    this.addressSize = addressSize;
+    this.isBigEndian = isBigEndian;
+  }
+
+  public String addressValueToString(long address) {
+    StringBuffer buf = new StringBuffer();
+    buf.append("0x");
+    String val;
+    // Make negative addresses have the correct size
+    if (addressSize == 8) {
+      val = Long.toHexString(address);
+    } else {
+      val = Integer.toHexString((int) address);
+    }
+    for (int i = 0; i < ((2 * addressSize) - val.length()); i++) {
+      buf.append('0');
+    }
+    buf.append(val);
+    return buf.toString();
+  }
+
+  public void checkAlignment(long address, long alignment) {
+    if (address % alignment != 0) {
+      throw new UnalignedAddressException("Trying to read at address: " +
+                                           addressValueToString(address) +
+                                           " with alignment: " + alignment,
+                                          address);
+    }
+  }
+
+  public long scanAddress(String addrStr) throws NumberFormatException {
+    String s = addrStr.trim();
+    if (!s.startsWith("0x")) {
+      throw new NumberFormatException(addrStr);
+    }
+    long l = 0;
+    for (int i = 2; i < s.length(); ++i) {
+      int val = charToNibble(s.charAt(i));
+      l <<= 4;
+      l |= val;
+    }
+    return l;
+  }
+
+  public int charToNibble(char ascii) throws NumberFormatException {
+    if (ascii >= '0' && ascii <= '9') {
+      return ascii - '0';
+    } else if (ascii >= 'A' && ascii <= 'F') {
+      return 10 + ascii - 'A';
+    } else if (ascii >= 'a' && ascii <= 'f') {
+      return 10 + ascii - 'a';
+    }
+    throw new NumberFormatException(new Character(ascii).toString());
+  }
+
+  public boolean dataToJBoolean(byte[] data, long jbooleanSize) {
+    checkDataContents(data, jbooleanSize);
+
+    return (data[0] != 0);
+  }
+
+  public byte dataToJByte(byte[] data, long jbyteSize) {
+    checkDataContents(data, jbyteSize);
+
+    return data[0];
+  }
+
+  public char dataToJChar(byte[] data, long jcharSize) {
+    checkDataContents(data, jcharSize);
+
+    if (!isBigEndian) {
+      byteSwap(data);
+    }
+
+    return (char) (((data[0] & 0xFF) << 8) | (data[1] & 0xFF));
+  }
+
+  public double dataToJDouble(byte[] data, long jdoubleSize) {
+    long longBits = dataToJLong(data, jdoubleSize);
+
+    return Double.longBitsToDouble(longBits);
+  }
+
+  public float dataToJFloat(byte[] data, long jfloatSize) {
+    int intBits = dataToJInt(data, jfloatSize);
+
+    return Float.intBitsToFloat(intBits);
+  }
+
+  public int dataToJInt(byte[] data, long jintSize) {
+    checkDataContents(data, jintSize);
+
+    if (!isBigEndian) {
+      byteSwap(data);
+    }
+
+    return (((data[0] & 0xFF) << 24) | ((data[1] & 0xFF) << 16) | ((data[2] & 0xFF) << 8) | (data[3] & 0xFF));
+  }
+
+  public long dataToJLong(byte[] data, long jlongSize) {
+    checkDataContents(data, jlongSize);
+
+    if (!isBigEndian) {
+      byteSwap(data);
+    }
+
+    return rawDataToJLong(data);
+  }
+
+  public short dataToJShort(byte[] data, long jshortSize) {
+    checkDataContents(data, jshortSize);
+
+    if (!isBigEndian) {
+      byteSwap(data);
+    }
+
+    return (short) (((data[0] & 0xFF) << 8) | (data[1] & 0xFF));
+  }
+
+  public long dataToCInteger(byte[] data, boolean isUnsigned) {
+    checkDataContents(data, data.length);
+
+    if (!isBigEndian) {
+      byteSwap(data);
+    }
+
+    // By default we'll be zero-extending.
+    // Therefore we need to check to see whether isUnsigned is false and
+    // also the high bit of the data is set.
+    if ((data.length < 8) &&
+        (isUnsigned == false) &&
+        ((data[0] & 0x80) != 0)) {
+      // Must sign-extend and right-align the data
+      byte[] newData = new byte[8];
+      for (int i = 0; i < 8; ++i) {
+        if ((7 - i) < data.length) {
+          newData[i] = data[i + data.length - 8];
+        } else {
+          newData[i] = (byte) 0xFF;
+        }
+      }
+      data = newData;
+    }
+
+    // Now just do the usual loop
+    return rawDataToJLong(data);
+  }
+
+  public long dataToAddressValue(byte[] data) {
+    checkDataContents(data, addressSize);
+
+    if (!isBigEndian) {
+      byteSwap(data);
+    }
+
+    return rawDataToJLong(data);
+  }
+
+  public byte[] jbooleanToData(boolean value) {
+    byte[] res = new byte[1];
+    res[0] = (byte) (value ? 1 : 0);
+    return res;
+  }
+
+  public byte[] jbyteToData(byte value) {
+    byte[] res = new byte[1];
+    res[0] = value;
+    return res;
+  }
+
+  public byte[] jcharToData(char value) {
+    byte[] res = new byte[2];
+    res[0] = (byte) ((value >> 8) & 0xFF);
+    res[1] = (byte) value;
+    if (!isBigEndian) {
+      byteSwap(res);
+    }
+    return res;
+  }
+
+  public byte[] jdoubleToData(double value) {
+    return jlongToData(Double.doubleToLongBits(value));
+  }
+
+  public byte[] jfloatToData(float value) {
+    return jintToData(Float.floatToIntBits(value));
+  }
+
+  public byte[] jintToData(int value) {
+    byte[] res = new byte[4];
+    for (int i = 0; i < 4; i++) {
+      res[3 - i] = (byte) (value & 0xFF);
+      value >>>= 8;
+    }
+    if (!isBigEndian) {
+      byteSwap(res);
+    }
+    return res;
+  }
+
+  public byte[] jlongToData(long value) {
+    byte[] res = new byte[8];
+    for (int i = 0; i < 8; i++) {
+      res[7 - i] = (byte) (value & 0xFF);
+      value >>>= 8;
+    }
+    if (!isBigEndian) {
+      byteSwap(res);
+    }
+    return res;
+  }
+
+  public byte[] jshortToData(short value) {
+    byte[] res = new byte[2];
+    res[0] = (byte) ((value >> 8) & 0xFF);
+    res[1] = (byte) value;
+    if (!isBigEndian) {
+      byteSwap(res);
+    }
+    return res;
+  }
+
+  public byte[] cIntegerToData(long longNumBytes, long value) {
+    int numBytes = (int) longNumBytes;
+    byte[] res = new byte[numBytes];
+    for (int i = 0; i < numBytes; i++) {
+      res[numBytes - i - 1] = (byte) (value & 0xFF);
+      value >>>= 8;
+    }
+    if (!isBigEndian) {
+      byteSwap(res);
+    }
+    return res;
+  }
+
+  //--------------------------------------------------------------------------------
+  // Internals only below this point
+  //
+
+  private void checkDataContents(byte[] data, long len) {
+    if (data.length != (int) len) {
+      throw new InternalError("Bug in Win32Debugger");
+    }
+  }
+
+  private void byteSwap(byte[] data) {
+    for (int i = 0; i < (data.length / 2); ++i) {
+      int altIndex = data.length - i - 1;
+      byte t = data[altIndex];
+      data[altIndex] = data[i];
+      data[i] = t;
+    }
+  }
+
+  private long rawDataToJLong(byte[] data) {
+    long addr = 0;
+    for (int i = 0; i < data.length; ++i) {
+      addr <<= 8;
+      addr |= data[i] & 0xFF;
+    }
+
+    return addr;
+  }
+}