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