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