1 /*
   2  * Copyright (c) 2002, 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.remote;
  26 
  27 import sun.jvm.hotspot.debugger.*;
  28 
  29 class RemoteAddress implements Address {
  30   protected RemoteDebuggerClient debugger;
  31   protected long addr;
  32 
  33   RemoteAddress(RemoteDebuggerClient debugger, long addr) {
  34     this.debugger = debugger;
  35     this.addr = addr;
  36   }
  37 
  38   //
  39   // Basic Java routines
  40   //
  41 
  42   public boolean equals(Object arg) {
  43     if (arg == null) {
  44       return false;
  45     }
  46 
  47     if (!(arg instanceof RemoteAddress)) {
  48       return false;
  49     }
  50 
  51     return (addr == ((RemoteAddress) arg).addr);
  52   }
  53 
  54   public int hashCode() {
  55     // FIXME: suggestions on a better hash code?
  56     return (int) addr;
  57   }
  58 
  59   public String toString() {
  60     return debugger.addressValueToString(addr);
  61   }
  62 
  63   //
  64   // C/C++-related routines
  65   //
  66 
  67   public long getCIntegerAt(long offset, long numBytes, boolean isUnsigned) throws UnalignedAddressException, UnmappedAddressException {
  68     return debugger.readCInteger(addr + offset, numBytes, isUnsigned);
  69   }
  70 
  71   public Address getAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  72     return debugger.readAddress(addr + offset);
  73   }
  74   public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  75     return debugger.readCompOopAddress(addr + offset);
  76   }
  77   public Address getCompKlassAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  78     return debugger.readCompKlassAddress(addr + offset);
  79   }
  80 
  81   //
  82   // Java-related routines
  83   //
  84 
  85   public boolean getJBooleanAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  86     return debugger.readJBoolean(addr + offset);
  87   }
  88 
  89   public byte getJByteAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  90     return debugger.readJByte(addr + offset);
  91   }
  92 
  93   public char getJCharAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  94     return debugger.readJChar(addr + offset);
  95   }
  96 
  97   public double getJDoubleAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
  98     return debugger.readJDouble(addr + offset);
  99   }
 100 
 101   public float getJFloatAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 102     return debugger.readJFloat(addr + offset);
 103   }
 104 
 105   public int getJIntAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 106     return debugger.readJInt(addr + offset);
 107   }
 108 
 109   public long getJLongAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 110     return debugger.readJLong(addr + offset);
 111   }
 112 
 113   public short getJShortAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
 114     return debugger.readJShort(addr + offset);
 115   }
 116 
 117   public OopHandle getOopHandleAt(long offset)
 118     throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
 119     return debugger.readOopHandle(addr + offset);
 120   }
 121   public OopHandle getCompOopHandleAt(long offset)
 122     throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
 123     return debugger.readCompOopHandle(addr + offset);
 124   }
 125 
 126   // Mutators -- not implemented for now (FIXME)
 127   public void setCIntegerAt(long offset, long numBytes, long value) {
 128     throw new DebuggerException("Unimplemented");
 129   }
 130   public void setAddressAt(long offset, Address value) {
 131     throw new DebuggerException("Unimplemented");
 132   }
 133   public void       setJBooleanAt      (long offset, boolean value)
 134     throws UnmappedAddressException, UnalignedAddressException {
 135     throw new DebuggerException("Unimplemented");
 136   }
 137   public void       setJByteAt         (long offset, byte value)
 138     throws UnmappedAddressException, UnalignedAddressException {
 139     throw new DebuggerException("Unimplemented");
 140   }
 141   public void       setJCharAt         (long offset, char value)
 142     throws UnmappedAddressException, UnalignedAddressException {
 143     throw new DebuggerException("Unimplemented");
 144   }
 145   public void       setJDoubleAt       (long offset, double value)
 146     throws UnmappedAddressException, UnalignedAddressException {
 147     throw new DebuggerException("Unimplemented");
 148   }
 149   public void       setJFloatAt        (long offset, float value)
 150     throws UnmappedAddressException, UnalignedAddressException {
 151     throw new DebuggerException("Unimplemented");
 152   }
 153   public void       setJIntAt          (long offset, int value)
 154     throws UnmappedAddressException, UnalignedAddressException {
 155     throw new DebuggerException("Unimplemented");
 156   }
 157   public void       setJLongAt         (long offset, long value)
 158     throws UnmappedAddressException, UnalignedAddressException {
 159     throw new DebuggerException("Unimplemented");
 160   }
 161   public void       setJShortAt        (long offset, short value)
 162     throws UnmappedAddressException, UnalignedAddressException {
 163     throw new DebuggerException("Unimplemented");
 164   }
 165   public void       setOopHandleAt     (long offset, OopHandle value)
 166     throws UnmappedAddressException, UnalignedAddressException {
 167     throw new DebuggerException("Unimplemented");
 168   }
 169 
 170   //
 171   // Arithmetic operations -- necessary evil.
 172   //
 173 
 174   public Address    addOffsetTo       (long offset) throws UnsupportedOperationException {
 175     long value = addr + offset;
 176     if (value == 0) {
 177       return null;
 178     }
 179     return new RemoteAddress(debugger, value);
 180   }
 181 
 182   public OopHandle  addOffsetToAsOopHandle(long offset) throws UnsupportedOperationException {
 183     long value = addr + offset;
 184     if (value == 0) {
 185       return null;
 186     }
 187     return new RemoteOopHandle(debugger, value);
 188   }
 189 
 190   /** (FIXME: any signed/unsigned issues? Should this work for
 191       OopHandles?) */
 192   public long       minus(Address arg) {
 193     if (arg == null) {
 194       return addr;
 195     }
 196     return addr - ((RemoteAddress) arg).addr;
 197   }
 198 
 199   // Two's complement representation.
 200   // All negative numbers are larger than positive numbers.
 201   // Numbers with the same sign can be compared normally.
 202   // Test harness is below in main().
 203 
 204   public boolean    lessThan          (Address arg) {
 205     if (arg == null) {
 206       return false;
 207     }
 208     RemoteAddress remoteArg = (RemoteAddress) arg;
 209     if ((addr >= 0) && (remoteArg.addr < 0)) {
 210       return true;
 211     }
 212     if ((addr < 0) && (remoteArg.addr >= 0)) {
 213       return false;
 214     }
 215     return (addr < remoteArg.addr);
 216   }
 217 
 218   public boolean    lessThanOrEqual   (Address arg) {
 219     if (arg == null) {
 220       return false;
 221     }
 222     RemoteAddress remoteArg = (RemoteAddress) arg;
 223     if ((addr >= 0) && (remoteArg.addr < 0)) {
 224       return true;
 225     }
 226     if ((addr < 0) && (remoteArg.addr >= 0)) {
 227       return false;
 228     }
 229     return (addr <= remoteArg.addr);
 230   }
 231 
 232   public boolean    greaterThan       (Address arg) {
 233     if (arg == null) {
 234       return true;
 235     }
 236     RemoteAddress remoteArg = (RemoteAddress) arg;
 237     if ((addr >= 0) && (remoteArg.addr < 0)) {
 238       return false;
 239     }
 240     if ((addr < 0) && (remoteArg.addr >= 0)) {
 241       return true;
 242     }
 243     return (addr > remoteArg.addr);
 244   }
 245 
 246   public boolean    greaterThanOrEqual(Address arg) {
 247     if (arg == null) {
 248       return true;
 249     }
 250     RemoteAddress remoteArg = (RemoteAddress) arg;
 251     if ((addr >= 0) && (remoteArg.addr < 0)) {
 252       return false;
 253     }
 254     if ((addr < 0) && (remoteArg.addr >= 0)) {
 255       return true;
 256     }
 257     return (addr >= remoteArg.addr);
 258   }
 259 
 260   public Address    andWithMask(long mask) throws UnsupportedOperationException {
 261     long value = addr & mask;
 262     if (value == 0) {
 263       return null;
 264     }
 265     return new RemoteAddress(debugger, value);
 266   }
 267 
 268   public Address    orWithMask(long mask) throws UnsupportedOperationException {
 269     long value = addr | mask;
 270     if (value == 0) {
 271       return null;
 272     }
 273     return new RemoteAddress(debugger, value);
 274   }
 275 
 276   public Address    xorWithMask(long mask) throws UnsupportedOperationException {
 277     long value = addr ^ mask;
 278     if (value == 0) {
 279       return null;
 280     }
 281     return new RemoteAddress(debugger, value);
 282   }
 283 
 284   public long asLongValue() { return addr; }
 285   //--------------------------------------------------------------------------------
 286   // Internals only below this point
 287   //
 288 
 289   long getValue() {
 290     return addr;
 291   }
 292 
 293 
 294   private static void check(boolean arg, String failMessage) {
 295     if (!arg) {
 296       System.err.println(failMessage + ": FAILED");
 297       System.exit(1);
 298     }
 299   }
 300 
 301   // Test harness
 302   public static void main(String[] args) {
 303     // p/n indicates whether the interior address is really positive
 304     // or negative. In unsigned terms, p1 < p2 < n1 < n2.
 305 
 306     RemoteAddress p1 = new RemoteAddress(null, 0x7FFFFFFFFFFFFFF0L);
 307     RemoteAddress p2 = (RemoteAddress) p1.addOffsetTo(10);
 308     RemoteAddress n1 = (RemoteAddress) p2.addOffsetTo(10);
 309     RemoteAddress n2 = (RemoteAddress) n1.addOffsetTo(10);
 310 
 311     // lessThan positive tests
 312     check(p1.lessThan(p2), "lessThan 1");
 313     check(p1.lessThan(n1), "lessThan 2");
 314     check(p1.lessThan(n2), "lessThan 3");
 315     check(p2.lessThan(n1), "lessThan 4");
 316     check(p2.lessThan(n2), "lessThan 5");
 317     check(n1.lessThan(n2), "lessThan 6");
 318 
 319     // lessThan negative tests
 320     check(!p1.lessThan(p1), "lessThan 7");
 321     check(!p2.lessThan(p2), "lessThan 8");
 322     check(!n1.lessThan(n1), "lessThan 9");
 323     check(!n2.lessThan(n2), "lessThan 10");
 324 
 325     check(!p2.lessThan(p1), "lessThan 11");
 326     check(!n1.lessThan(p1), "lessThan 12");
 327     check(!n2.lessThan(p1), "lessThan 13");
 328     check(!n1.lessThan(p2), "lessThan 14");
 329     check(!n2.lessThan(p2), "lessThan 15");
 330     check(!n2.lessThan(n1), "lessThan 16");
 331 
 332     // lessThanOrEqual positive tests
 333     check(p1.lessThanOrEqual(p1), "lessThanOrEqual 1");
 334     check(p2.lessThanOrEqual(p2), "lessThanOrEqual 2");
 335     check(n1.lessThanOrEqual(n1), "lessThanOrEqual 3");
 336     check(n2.lessThanOrEqual(n2), "lessThanOrEqual 4");
 337 
 338     check(p1.lessThanOrEqual(p2), "lessThanOrEqual 5");
 339     check(p1.lessThanOrEqual(n1), "lessThanOrEqual 6");
 340     check(p1.lessThanOrEqual(n2), "lessThanOrEqual 7");
 341     check(p2.lessThanOrEqual(n1), "lessThanOrEqual 8");
 342     check(p2.lessThanOrEqual(n2), "lessThanOrEqual 9");
 343     check(n1.lessThanOrEqual(n2), "lessThanOrEqual 10");
 344 
 345     // lessThanOrEqual negative tests
 346     check(!p2.lessThanOrEqual(p1), "lessThanOrEqual 11");
 347     check(!n1.lessThanOrEqual(p1), "lessThanOrEqual 12");
 348     check(!n2.lessThanOrEqual(p1), "lessThanOrEqual 13");
 349     check(!n1.lessThanOrEqual(p2), "lessThanOrEqual 14");
 350     check(!n2.lessThanOrEqual(p2), "lessThanOrEqual 15");
 351     check(!n2.lessThanOrEqual(n1), "lessThanOrEqual 16");
 352 
 353     // greaterThan positive tests
 354     check(n2.greaterThan(p1), "greaterThan 1");
 355     check(n2.greaterThan(p2), "greaterThan 2");
 356     check(n2.greaterThan(n1), "greaterThan 3");
 357     check(n1.greaterThan(p1), "greaterThan 4");
 358     check(n1.greaterThan(p2), "greaterThan 5");
 359     check(p2.greaterThan(p1), "greaterThan 6");
 360 
 361     // greaterThan negative tests
 362     check(!p1.greaterThan(p1), "greaterThan 7");
 363     check(!p2.greaterThan(p2), "greaterThan 8");
 364     check(!n1.greaterThan(n1), "greaterThan 9");
 365     check(!n2.greaterThan(n2), "greaterThan 10");
 366 
 367     check(!p1.greaterThan(n2), "greaterThan 11");
 368     check(!p2.greaterThan(n2), "greaterThan 12");
 369     check(!n1.greaterThan(n2), "greaterThan 13");
 370     check(!p1.greaterThan(n1), "greaterThan 14");
 371     check(!p2.greaterThan(n1), "greaterThan 15");
 372     check(!p1.greaterThan(p2), "greaterThan 16");
 373 
 374     // greaterThanOrEqual positive tests
 375     check(p1.greaterThanOrEqual(p1), "greaterThanOrEqual 1");
 376     check(p2.greaterThanOrEqual(p2), "greaterThanOrEqual 2");
 377     check(n1.greaterThanOrEqual(n1), "greaterThanOrEqual 3");
 378     check(n2.greaterThanOrEqual(n2), "greaterThanOrEqual 4");
 379 
 380     check(n2.greaterThanOrEqual(p1), "greaterThanOrEqual 5");
 381     check(n2.greaterThanOrEqual(p2), "greaterThanOrEqual 6");
 382     check(n2.greaterThanOrEqual(n1), "greaterThanOrEqual 7");
 383     check(n1.greaterThanOrEqual(p1), "greaterThanOrEqual 8");
 384     check(n1.greaterThanOrEqual(p2), "greaterThanOrEqual 9");
 385     check(p2.greaterThanOrEqual(p1), "greaterThanOrEqual 10");
 386 
 387     // greaterThanOrEqual negative tests
 388     check(!p1.greaterThanOrEqual(n2), "greaterThanOrEqual 11");
 389     check(!p2.greaterThanOrEqual(n2), "greaterThanOrEqual 12");
 390     check(!n1.greaterThanOrEqual(n2), "greaterThanOrEqual 13");
 391     check(!p1.greaterThanOrEqual(n1), "greaterThanOrEqual 14");
 392     check(!p2.greaterThanOrEqual(n1), "greaterThanOrEqual 15");
 393     check(!p1.greaterThanOrEqual(p2), "greaterThanOrEqual 16");
 394 
 395     System.err.println("RemoteAddress: all tests passed successfully.");
 396   }
 397 }