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