1 /*
   2  * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.debugger;
  26 
  27 /** <P> This is the bottom-most interface which abstracts address
  28     access for both debugging and introspection. In the situation of
  29     debugging a target VM, these routines can throw the specified
  30     RuntimeExceptions to indicate failure and allow recovery of the
  31     debugging system. If these are used for introspecting the current
  32     VM and implementing functionality in it, however, it is expected
  33     that these kinds of failures will not occur and, in fact, a crash
  34     will occur if the situation arises where they would have been
  35     thrown. </P>
  36 
  37     <P> Addresses are immutable. Further, it was decided not to expose
  38     the representation of the Address (and provide a corresponding
  39     factory method from, for example, long to Address). Unfortunately,
  40     because of the existence of C and "reuse" of low bits of pointers,
  41     it is occasionally necessary to perform logical operations like
  42     masking off the low bits of an "address". While these operations
  43     could be used to generate arbitrary Address objects, allowing this
  44     is not the intent of providing these operations. </P>
  45 
  46     <P> This interface is able to fetch all Java primitive types,
  47     addresses, oops, and C integers of arbitrary size (see @see
  48     sun.jvm.hotspot.types.CIntegerType for further discussion). Note
  49     that the result of the latter is restricted to fitting into a
  50     64-bit value and the high-order bytes will be silently discarded
  51     if too many bytes are requested. </P>
  52 
  53     <P> Implementations may have restrictions, for example that the
  54     Java-related routines may not be called until a certain point in
  55     the bootstrapping process once the sizes of the Java primitive
  56     types are known. (The current implementation has that property.)
  57     </P>
  58 
  59     <P> A note of warning: in C addresses, when represented as
  60     integers, are usually represented with unsigned types.
  61     Unfortunately, there are no unsigned primitive types in Java, so
  62     care will have to be taken in the implementation of this interface
  63     if using longs as the representation for 64-bit correctness. This
  64     is not so simple for the comparison operators. </P> */
  65 
  66 public interface Address {
  67 
  68   /** This is stated explicitly here because it is important for
  69       implementations to understand that equals() and hashCode() must
  70       absolutely, positively work properly -- i.e., two Address
  71       objects representing the same address are both equal (via
  72       equals()) and have the same hash code. */
  73   public boolean equals(Object arg);
  74 
  75   /** This is stated explicitly here because it is important for
  76       implementations to understand that equals() and hashCode() must
  77       absolutely, positively work properly -- i.e., two Address
  78       objects representing the same address are both equal (via
  79       equals()) and have the same hash code. */
  80   public int hashCode();
  81 
  82   //
  83   // C/C++-related routines
  84   //
  85 
  86   public long       getCIntegerAt      (long offset, long numBytes, boolean isUnsigned)
  87     throws UnmappedAddressException, UnalignedAddressException;
  88   /** This returns null if the address at the given offset is NULL. */
  89   public Address    getAddressAt       (long offset) throws UnmappedAddressException, UnalignedAddressException;
  90   /** Returns the decoded address at the given offset */
  91   public Address    getCompOopAddressAt (long offset) throws UnmappedAddressException, UnalignedAddressException;
  92   public Address    getCompKlassAddressAt (long offset) throws UnmappedAddressException, UnalignedAddressException;
  93 
  94   //
  95   // Java-related routines
  96   //
  97 
  98   public boolean    getJBooleanAt      (long offset) throws UnmappedAddressException, UnalignedAddressException;
  99   public byte       getJByteAt         (long offset) throws UnmappedAddressException, UnalignedAddressException;
 100   public char       getJCharAt         (long offset) throws UnmappedAddressException, UnalignedAddressException;
 101   public double     getJDoubleAt       (long offset) throws UnmappedAddressException, UnalignedAddressException;
 102   public float      getJFloatAt        (long offset) throws UnmappedAddressException, UnalignedAddressException;
 103   public int        getJIntAt          (long offset) throws UnmappedAddressException, UnalignedAddressException;
 104   public long       getJLongAt         (long offset) throws UnmappedAddressException, UnalignedAddressException;
 105   public short      getJShortAt        (long offset) throws UnmappedAddressException, UnalignedAddressException;
 106   /** This returns null if the address at the given offset is NULL. */
 107   public OopHandle  getOopHandleAt     (long offset)
 108     throws UnmappedAddressException, UnalignedAddressException, NotInHeapException;
 109   public OopHandle  getCompOopHandleAt (long offset)
 110     throws UnmappedAddressException, UnalignedAddressException, NotInHeapException;
 111 
 112   //
 113   // C/C++-related mutators. These throw UnmappedAddressException if
 114   // the target is read-only (for example, a core file rather than an
 115   // active process), if the target address is unmapped, or if it is
 116   // read-only. The implementation may supply extra detail messages.
 117   //
 118 
 119   /** Sets a C integer numBytes in size at the specified offset. Note
 120       that there is no "unsigned" flag for the accessor since the
 121       value will not be sign-extended; the number of bytes are simply
 122       copied from the value into the target address space. */
 123   public void setCIntegerAt(long offset, long numBytes, long value);
 124 
 125   /** Sets an Address at the specified location. */
 126   public void setAddressAt(long offset, Address value);
 127 
 128   //
 129   // Java-related mutators -- see above.
 130   //
 131 
 132   public void       setJBooleanAt      (long offset, boolean value)
 133     throws UnmappedAddressException, UnalignedAddressException;
 134   public void       setJByteAt         (long offset, byte value)
 135     throws UnmappedAddressException, UnalignedAddressException;
 136   public void       setJCharAt         (long offset, char value)
 137     throws UnmappedAddressException, UnalignedAddressException;
 138   public void       setJDoubleAt       (long offset, double value)
 139     throws UnmappedAddressException, UnalignedAddressException;
 140   public void       setJFloatAt        (long offset, float value)
 141     throws UnmappedAddressException, UnalignedAddressException;
 142   public void       setJIntAt          (long offset, int value)
 143     throws UnmappedAddressException, UnalignedAddressException;
 144   public void       setJLongAt         (long offset, long value)
 145     throws UnmappedAddressException, UnalignedAddressException;
 146   public void       setJShortAt        (long offset, short value)
 147     throws UnmappedAddressException, UnalignedAddressException;
 148   public void       setOopHandleAt     (long offset, OopHandle value)
 149     throws UnmappedAddressException, UnalignedAddressException;
 150 
 151   //
 152   // Arithmetic operations -- necessary evil.
 153   //
 154 
 155   /** This throws an UnsupportedOperationException if this address happens
 156       to actually be an OopHandle, because interior object pointers
 157       are not allowed. Negative offsets are allowed and handle the
 158       subtraction case. */
 159   public Address    addOffsetTo        (long offset) throws UnsupportedOperationException;
 160 
 161   /** This method had to be added in order to support heap iteration
 162       in the debugging system, and is effectively the dangerous
 163       operation of allowing interior object pointers. For this reason
 164       it was kept as a separate API and its use is forbidden in the
 165       non-debugging (i.e., reflective system) case. It is strongly
 166       recommended that this not be called by clients: it is currently
 167       wrapped up in the Space's iteration mechanism. */
 168   public OopHandle  addOffsetToAsOopHandle(long offset) throws UnsupportedOperationException;
 169 
 170   /** Performs the subtraction "this - arg", returning the resulting
 171       offset in bytes. Note that this must handle a null argument
 172       properly, and can be used to convert an Address into a long for
 173       further manipulation, but that the reverse conversion is not
 174       possible. (FIXME: any signed/unsigned issues? Should this work
 175       for OopHandles?) */
 176   public long       minus(Address arg);
 177 
 178   /** Performs unsigned comparison "this < arg".
 179       (FIXME: should this work for OopHandles?) */
 180   public boolean    lessThan          (Address arg);
 181   /** Performs unsigned comparison "this <= arg".
 182       (FIXME: should this work for OopHandles?) */
 183   public boolean    lessThanOrEqual   (Address arg);
 184   /** Performs unsigned comparison "this > arg".
 185       (FIXME: should this work for OopHandles?) */
 186   public boolean    greaterThan       (Address arg);
 187   /** Performs unsigned comparison "this >= arg".
 188       (FIXME: should this work for OopHandles?) */
 189   public boolean    greaterThanOrEqual(Address arg);
 190 
 191   /** This throws an UnsupportedOperationException if this address happens
 192       to actually be an OopHandle. Performs a logical "and" operation
 193       of the bits of the address and the mask (least significant bits
 194       of the Address and the mask are aligned) and returns the result
 195       as an Address. Returns null if the result was zero. */
 196   public Address    andWithMask(long mask) throws UnsupportedOperationException;
 197 
 198   /** This throws an UnsupportedOperationException if this address happens
 199       to actually be an OopHandle. Performs a logical "or" operation
 200       of the bits of the address and the mask (least significant bits
 201       of the Address and the mask are aligned) and returns the result
 202       as an Address. Returns null if the result was zero. */
 203   public Address    orWithMask(long mask) throws UnsupportedOperationException;
 204 
 205   /** This throws an UnsupportedOperationException if this address happens
 206       to actually be an OopHandle. Performs a logical "exclusive or"
 207       operation of the bits of the address and the mask (least
 208       significant bits of the Address and the mask are aligned) and
 209       returns the result as an Address. Returns null if the result was
 210       zero. */
 211   public Address    xorWithMask(long mask) throws UnsupportedOperationException;
 212 
 213   // return address as long integer.
 214   public long asLongValue();
 215 }