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