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