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 }