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
25package sun.jvm.hotspot.debugger.proc;
26
27import sun.jvm.hotspot.debugger.*;
28
29class ProcAddress implements Address {
30  protected ProcDebugger debugger;
31  protected long addr;
32
33  ProcAddress(ProcDebugger 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 ProcAddress)) {
48      return false;
49    }
50
51    return (addr == ((ProcAddress) 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  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 ProcAddress(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 ProcOopHandle(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 - ((ProcAddress) 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 arg) {
207    if (arg == null) {
208      return false;
209    }
210    ProcAddress dbxArg = (ProcAddress) arg;
211    if ((addr >= 0) && (dbxArg.addr < 0)) {
212      return true;
213    }
214    if ((addr < 0) && (dbxArg.addr >= 0)) {
215      return false;
216    }
217    return (addr < dbxArg.addr);
218  }
219
220  public boolean    lessThanOrEqual   (Address arg) {
221    if (arg == null) {
222      return false;
223    }
224    ProcAddress dbxArg = (ProcAddress) arg;
225    if ((addr >= 0) && (dbxArg.addr < 0)) {
226      return true;
227    }
228    if ((addr < 0) && (dbxArg.addr >= 0)) {
229      return false;
230    }
231    return (addr <= dbxArg.addr);
232  }
233
234  public boolean    greaterThan       (Address arg) {
235    if (arg == null) {
236      return true;
237    }
238    ProcAddress dbxArg = (ProcAddress) arg;
239    if ((addr >= 0) && (dbxArg.addr < 0)) {
240      return false;
241    }
242    if ((addr < 0) && (dbxArg.addr >= 0)) {
243      return true;
244    }
245    return (addr > dbxArg.addr);
246  }
247
248  public boolean    greaterThanOrEqual(Address arg) {
249    if (arg == null) {
250      return true;
251    }
252    ProcAddress dbxArg = (ProcAddress) arg;
253    if ((addr >= 0) && (dbxArg.addr < 0)) {
254      return false;
255    }
256    if ((addr < 0) && (dbxArg.addr >= 0)) {
257      return true;
258    }
259    return (addr >= dbxArg.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 ProcAddress(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 ProcAddress(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 ProcAddress(debugger, value);
284  }
285
286  public long asLongValue() { return addr; }
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    ProcAddress p1 = new ProcAddress(null, 0x7FFFFFFFFFFFFFF0L);
309    ProcAddress p2 = (ProcAddress) p1.addOffsetTo(10);
310    ProcAddress n1 = (ProcAddress) p2.addOffsetTo(10);
311    ProcAddress n2 = (ProcAddress) 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("ProcAddress: all tests passed successfully.");
398  }
399}
400