Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java
+++ new/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java
1 1 /*
2 2 * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation.
8 8 *
9 9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 12 * version 2 for more details (a copy is included in the LICENSE file that
13 13 * accompanied this code).
14 14 *
15 15 * You should have received a copy of the GNU General Public License version
16 16 * 2 along with this work; if not, write to the Free Software Foundation,
17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 18 *
19 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 20 * or visit www.oracle.com if you need additional information or have any
21 21 * questions.
22 22 *
23 23 */
24 24
25 25 package sun.jvm.hotspot.runtime.sparc;
26 26
27 27 import java.util.*;
28 28
29 29 import sun.jvm.hotspot.asm.sparc.*;
30 30 import sun.jvm.hotspot.code.*;
31 31 import sun.jvm.hotspot.compiler.*;
32 32 import sun.jvm.hotspot.debugger.*;
33 33 import sun.jvm.hotspot.debugger.cdbg.*;
34 34 import sun.jvm.hotspot.oops.*;
35 35 import sun.jvm.hotspot.runtime.*;
36 36 import sun.jvm.hotspot.runtime.posix.*;
37 37 import sun.jvm.hotspot.types.*;
38 38 import sun.jvm.hotspot.utilities.*;
39 39
40 40 /** Specialization of and implementation of abstract methods of the
41 41 Frame class for the SPARC CPU. (FIXME: this is as quick a port as
42 42 possible to get things running; will have to do a better job right
43 43 away.) */
44 44
45 45 public class SPARCFrame extends Frame {
46 46 // The pc value is the raw return address, plus 8 (pcReturnOffset()).
47 47 // the value of sp and youngerSP that is stored in this object
48 48 // is always, always, always the value that would be found in the
49 49 // register (or window save area) while the target VM was executing.
50 50 // The caller of the constructor will alwasy know if has a biased or
51 51 // unbiased version of the stack pointer and can convert real (unbiased)
52 52 // value via a helper routine we supply.
53 53 // Whenever we return sp or youngerSP values we do not return the internal
54 54 // value but the real (unbiased) pointers since these are the true, usable
55 55 // memory addresses. The outlier case is that of the null pointer. The current
56 56 // mechanism makes null pointers always look null whether biased or not.
57 57 // This seems to cause no problems. In theory null real pointers could be biased
58 58 // just like other values however this has impact on things like addOffsetTo()
59 59 // to be able to take an Address that represents null and add an offset to it.
60 60 // This doesn't seem worth the bother and the impact on the rest of the code
61 61 // when the biasSP and unbiasSP can make this invisible.
62 62 //
63 63 // The general rule in this code is that when we have a variable like FP, youngerSP, SP
64 64 // that these are real (i.e. unbiased) addresses. The instance variables in a Frame are
65 65 // always raw values. The other rule is that it except for the frame constructors and
66 66 // the unBiasSP helper all methods accept parameters that are real addresses.
67 67 //
68 68
69 69 /** Optional next-younger SP (used to locate O7, the PC) */
70 70 private Address raw_youngerSP;
71 71
72 72 /** Intepreter adjusts the stack pointer to make all locals contiguous */
73 73 private long interpreterSPAdjustmentOffset;
74 74
75 75 /** Number of stack entries for longs */
76 76 private static final int WORDS_PER_LONG = 2;
77 77
78 78 /** Normal SPARC return is 2 words past PC */
79 79 public static final int PC_RETURN_OFFSET = 8;
80 80
81 81 /** Size of each block, in order of increasing address */
82 82 public static final int REGISTER_SAVE_WORDS = 16;
83 83 // FIXME: read these from the remote process
84 84 //#ifdef _LP64
85 85 // callee_aggregate_return_pointer_words = 0,
86 86 //#else
87 87 // callee_aggregate_return_pointer_words = 1,
88 88 //#endif
89 89 public static final int CALLEE_AGGREGATE_RETURN_POINTER_WORDS = 1;
90 90 public static final int CALLEE_REGISTER_ARGUMENT_SAVE_AREA_WORDS = 6;
91 91
92 92 // offset of each block, in order of increasing address:
93 93 public static final int REGISTER_SAVE_WORDS_SP_OFFSET = 0;
94 94 public static final int CALLEE_AGGREGATE_RETURN_POINTER_SP_OFFSET = REGISTER_SAVE_WORDS_SP_OFFSET + REGISTER_SAVE_WORDS;
95 95 public static final int CALLEE_REGISTER_ARGUMENT_SAVE_AREA_SP_OFFSET = (CALLEE_AGGREGATE_RETURN_POINTER_SP_OFFSET +
96 96 CALLEE_AGGREGATE_RETURN_POINTER_WORDS);
97 97 public static final int MEMORY_PARAMETER_WORD_SP_OFFSET = (CALLEE_REGISTER_ARGUMENT_SAVE_AREA_SP_OFFSET +
98 98 CALLEE_REGISTER_ARGUMENT_SAVE_AREA_WORDS);
99 99 public static final int VARARGS_OFFSET = MEMORY_PARAMETER_WORD_SP_OFFSET;
100 100
101 101 private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.runtime.sparc.SPARCFrame.DEBUG") != null;
102 102
103 103 public static Address unBiasSP(Address raw_sp) {
104 104 if (raw_sp != null) {
105 105 return raw_sp.addOffsetTo(VM.getVM().getStackBias());
106 106 } else {
107 107 return null;
108 108 }
109 109 }
110 110
111 111 public static Address biasSP(Address real_sp) {
112 112 if (real_sp != null) {
113 113 if (DEBUG) {
114 114 System.out.println("biasing realsp: " + real_sp + " biased: " + real_sp.addOffsetTo(-VM.getVM().getStackBias()) );
115 115 }
116 116 return real_sp.addOffsetTo(-VM.getVM().getStackBias());
117 117 } else {
118 118 if (DEBUG) {
119 119 System.out.println("biasing null realsp");
120 120 }
121 121 return null;
122 122 }
123 123 }
124 124 //
125 125 // This is used to find the younger sp for a thread thatn has stopped but hasn't
126 126 // conveniently told us the information where we can find the pc or the frame
127 127 // containing the pc that corresponds to last_java_sp. This method will walk
128 128 // the frames trying to find the frame which we contains the data we need.
129 129 //
130 130 public static Address findYoungerSP(Address top, Address find) {
131 131 // top and find are unBiased sp values
132 132 // we return an unBiased value
133 133 Address findRaw = biasSP(find);
134 134 if (top == null || find == null || findRaw == null) {
135 135 throw new RuntimeException("bad values for findYoungerSP top: " + top + " find: " + find);
136 136 }
137 137 // It would be unusual to find more than 20 native frames before we find the java frame
138 138 // we are looking for.
139 139 final int maxFrames = 20;
140 140 int count = 0;
141 141 Address search = top;
142 142 Address next;
143 143 Address pc;
144 144 if (DEBUG) {
145 145 System.out.println("findYoungerSP top: " + top + " find: " + find + " findRaw: " + findRaw);
146 146 }
147 147 while ( count != maxFrames && search != null) {
148 148 next = search.getAddressAt(SPARCRegisters.I6.spOffsetInSavedWindow());
149 149 pc = search.getAddressAt(SPARCRegisters.I7.spOffsetInSavedWindow());
150 150 if (DEBUG) {
151 151 System.out.println("findYoungerSP next: " + next + " pc: " + pc);
152 152 }
153 153 if (next.equals(findRaw)) {
154 154 return search;
155 155 }
156 156 search = unBiasSP(next);
157 157 }
158 158 if (DEBUG) {
159 159 System.out.println("findYoungerSP: never found younger, top: " + top + " find: " + find);
160 160 }
161 161 return null;
162 162 }
163 163
164 164 public Address getSP() {
165 165 if (DEBUG) {
166 166 System.out.println("getSP raw: " + raw_sp + " unbiased: " + unBiasSP(raw_sp));
167 167 }
168 168 return unBiasSP(raw_sp);
169 169 }
170 170
171 171 public Address getID() {
172 172 return getSP();
173 173 }
174 174
175 175 public Address getYoungerSP() {
176 176 if (DEBUG) {
177 177 System.out.println("getYoungerSP: " + raw_youngerSP + " unbiased: " + unBiasSP(raw_youngerSP));
178 178 }
179 179 return unBiasSP(raw_youngerSP);
180 180 }
181 181
182 182 /** This constructor relies on the fact that the creator of a frame
183 183 has flushed register windows which the frame will refer to, and
184 184 that those register windows will not be reloaded until the frame
185 185 is done reading and writing the stack. Moreover, if the
186 186 "younger_pc" argument points into the register save area of the
187 187 next younger frame (though it need not), the register window for
188 188 that next younger frame must also stay flushed. (The caller is
189 189 responsible for ensuring this.) */
190 190 public SPARCFrame(Address raw_sp, Address raw_youngerSP, boolean youngerFrameIsInterpreted) {
191 191 super();
192 192 if (DEBUG) {
193 193 System.out.println("Constructing frame(1) raw_sp: " + raw_sp + " raw_youngerSP: " + raw_youngerSP);
194 194 }
195 195 if (Assert.ASSERTS_ENABLED) {
196 196 Assert.that((unBiasSP(raw_sp).andWithMask(VM.getVM().getAddressSize() - 1) == null),
197 197 "Expected raw sp likely got real sp, value was " + raw_sp);
198 198 if (raw_youngerSP != null) {
199 199 Assert.that((unBiasSP(raw_youngerSP).andWithMask(VM.getVM().getAddressSize() - 1) == null),
200 200 "Expected raw youngerSP likely got real youngerSP, value was " + raw_youngerSP);
201 201 }
202 202 }
203 203 this.raw_sp = raw_sp;
204 204 this.raw_youngerSP = raw_youngerSP;
205 205 if (raw_youngerSP == null) {
206 206 // make a deficient frame which doesn't know where its PC is
207 207 pc = null;
208 208 } else {
209 209 Address youngerSP = unBiasSP(raw_youngerSP);
210 210 pc = youngerSP.getAddressAt(SPARCRegisters.I7.spOffsetInSavedWindow()).addOffsetTo(PC_RETURN_OFFSET);
211 211
212 212 if (Assert.ASSERTS_ENABLED) {
213 213 Assert.that(youngerSP.getAddressAt(SPARCRegisters.FP.spOffsetInSavedWindow()).
214 214 equals(raw_sp),
215 215 "youngerSP must be valid");
216 216 }
217 217 }
218 218
219 219 if (youngerFrameIsInterpreted) {
220 220 long IsavedSP = SPARCRegisters.IsavedSP.spOffsetInSavedWindow();
221 221 // compute adjustment to this frame's SP made by its interpreted callee
222 222 interpreterSPAdjustmentOffset = 0;
223 223 Address savedSP = unBiasSP(getYoungerSP().getAddressAt(IsavedSP));
224 224 if (savedSP == null) {
225 225 if ( DEBUG) {
226 226 System.out.println("WARNING: IsavedSP was null for frame " + this);
227 227 }
228 228 } else {
229 229 interpreterSPAdjustmentOffset = savedSP.minus(getSP());
230 230 }
231 231 } else {
232 232 interpreterSPAdjustmentOffset = 0;
233 233 }
234 234 if ( pc != null) {
235 235 // Look for a deopt pc and if it is deopted convert to original pc
236 236 CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
237 237 if (cb != null && cb.isJavaMethod()) {
238 238 NMethod nm = (NMethod) cb;
239 239 if (pc.equals(nm.deoptHandlerBegin())) {
240 240 // adjust pc if frame is deoptimized.
241 241 pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset());
242 242 deoptimized = true;
243 243 }
244 244 }
245 245 }
246 246 }
247 247
248 248 /** Make a deficient frame which doesn't know where its PC is (note
249 249 no youngerSP argument) */
250 250 public SPARCFrame(Address raw_sp, Address pc) {
251 251 super();
252 252 if (DEBUG) {
253 253 System.out.println("Constructing frame(2) raw_sp: " + raw_sp );
254 254 }
255 255 this.raw_sp = raw_sp;
256 256 if (Assert.ASSERTS_ENABLED) {
257 257 Assert.that((unBiasSP(raw_sp).andWithMask(VM.getVM().getAddressSize() - 1) == null),
258 258 "Expected raw sp likely got real sp, value was " + raw_sp);
259 259 }
260 260 raw_youngerSP = null;
261 261 this.pc = pc;
262 262 interpreterSPAdjustmentOffset = 0;
263 263 }
264 264
265 265 /** Only used internally */
266 266 private SPARCFrame() {
267 267 }
268 268
269 269 public Object clone() {
270 270 SPARCFrame frame = new SPARCFrame();
271 271 frame.raw_sp = raw_sp;
272 272 frame.pc = pc;
273 273 frame.raw_youngerSP = raw_youngerSP;
274 274 frame.interpreterSPAdjustmentOffset = interpreterSPAdjustmentOffset;
275 275 frame.deoptimized = deoptimized;
276 276 return frame;
277 277 }
278 278
279 279 public boolean equals(Object arg) {
280 280 if (arg == null) {
281 281 return false;
282 282 }
283 283
284 284 if (!(arg instanceof SPARCFrame)) {
285 285 return false;
286 286 }
287 287
288 288 SPARCFrame other = (SPARCFrame) arg;
289 289
290 290 return (AddressOps.equal(getSP(), other.getSP()) &&
291 291 AddressOps.equal(getFP(), other.getFP()) &&
292 292 AddressOps.equal(getPC(), other.getPC()));
293 293 }
294 294
295 295 public int hashCode() {
296 296 if (raw_sp == null) {
297 297 return 0;
298 298 }
299 299
300 300 return raw_sp.hashCode();
301 301 }
302 302
303 303 public String toString() {
304 304 Address fp = getFP();
305 305 Address sp = getSP();
306 306 Address youngerSP = getYoungerSP();
307 307
308 308 return "sp: " + (sp == null? "null" : sp.toString()) +
309 309 ", younger_sp: " + (youngerSP == null? "null" : youngerSP.toString()) +
310 310 ", fp: " + (fp == null? "null" : fp.toString()) +
311 311 ", pc: " + (pc == null? "null" : pc.toString());
312 312 }
313 313
314 314 /** <P> Identifies a signal handler frame on the stack. </P>
315 315
316 316 <P> There are a few different algorithms for doing this, and
317 317 they vary from platform to platform. For example, based on a
318 318 conversation with Dave Dice, Solaris/x86 will be substantially
319 319 simpler to handle than Solaris/SPARC because the signal handler
320 320 frame can be identified because of a program counter == -1. </P>
321 321
322 322 <P> The dbx group provided code and advice on these topics; the
323 323 code below evolved from theirs, but is not correct/robust.
324 324 Without going into too many details, it seems that looking for
325 325 the incoming argument to the sigacthandler frame (which is what
326 326 this code identifies) is not guaranteed to be stable across
327 327 versions of Solaris, since that function is supplied by
328 328 libthread and is not guaranteed not to clobber I2 before it
329 329 calls __sighndlr later. From discussions, it sounds like a
330 330 robust algorithm which wouldn't require traversal of the
331 331 ucontext chain (used by dbx, but which Dave Dice thinks isn't
332 332 robust in the face of libthread -- need to follow up) would be
333 333 to be able to properly identify the __sighndlr frame, then get
334 334 I2 and treat that as a ucontext. To identify __sighndlr we would
335 335 need to look up that symbol in the remote process and look for a
336 336 program counter within a certain (small) distance. </P>
337 337
338 338 <P> If the underlying Debugger supports CDebugger interface, we
339 339 take the approach of __sighnldr symbol. This approach is more robust
340 340 compared to the original hueristic approach. Of course, if there
341 341 is no CDebugger support, we fallback to the hueristic approach. </P>
342 342
343 343 <P> The current implementation seems to work with Solaris 2.8.
344 344 A nice property of this system is that if we find a core file
345 345 this algorithm doesn't work on, we can change the code and try
346 346 again, so I'm putting this in as the current mechanism for
347 347 finding signal handler frames on Solaris/SPARC. </P> */
348 348 public boolean isSignalHandlerFrameDbg() {
349 349 CDebugger cdbg = VM.getVM().getDebugger().getCDebugger();
350 350 if (cdbg != null) {
351 351 LoadObject dso = cdbg.loadObjectContainingPC(getPC());
352 352 if (dso != null) {
353 353 ClosestSymbol cs = dso.closestSymbolToPC(getPC());
354 354 if (cs != null && cs.getName().equals("__sighndlr")) {
355 355 return true;
356 356 } else {
357 357 return false;
358 358 }
359 359 } else {
360 360 return false;
361 361 }
362 362 } else {
363 363 if (getYoungerSP() == null) {
364 364 // System.err.println(" SPARCFrame.isSignalHandlerFrameDbg: youngerSP = " + getYoungerSP());
365 365 return false;
366 366 }
367 367 Address i2 = getSP().getAddressAt(SPARCRegisters.I2.spOffsetInSavedWindow());
368 368 if (i2 == null) {
369 369 return false;
370 370 }
371 371 Address fp = getFP();
372 372 // My (mistaken) understanding of the dbx group's code was that
373 373 // the signal handler frame could be identified by testing the
374 374 // incoming argument to see whether it was a certain distance
375 375 // below the frame pointer; in fact, their code did substantially
376 376 // more than this (traversal of the ucontext chain, which this
377 377 // code can't do because the topmost ucontext is not currently
378 378 // available via the proc_service APIs in dbx). The current code
379 379 // appears to work, but is probably not robust.
380 380 int MAJOR_HACK_OFFSET = 8; // Difference between expected location of the ucontext and reality
381 381 // System.err.println(" SPARCFrame.isSignalHandlerFrameDbg: I2 = " + i2 +
382 382 // ", fp = " + fp + ", raw_youngerSP = " + getYoungerSP());
383 383 boolean res = i2.equals(fp.addOffsetTo(VM.getVM().getAddressSize() * (REGISTER_SAVE_WORDS + MAJOR_HACK_OFFSET)));
384 384 if (res) {
385 385 // Qualify this with another test (FIXME: this is a gross heuristic found while testing)
386 386 Address sigInfoAddr = getSP().getAddressAt(SPARCRegisters.I5.spOffsetInSavedWindow());
387 387 if (sigInfoAddr == null) {
388 388 System.err.println("Frame with fp = " + fp + " looked like a signal handler frame but wasn't");
389 389 res = false;
390 390 }
391 391 }
392 392 return res;
393 393 }
394 394 }
395 395
396 396 public int getSignalNumberDbg() {
397 397 // From looking at the stack trace in dbx, it looks like the
398 398 // siginfo* comes into sigacthandler in I5. It would be much more
399 399 // robust to look at the __sighndlr frame instead, but we can't
400 400 // currently identify that frame.
401 401
402 402 Address sigInfoAddr = getSP().getAddressAt(SPARCRegisters.I5.spOffsetInSavedWindow());
403 403 // Read si_signo out of siginfo*
404 404 return (int) sigInfoAddr.getCIntegerAt(0, 4, false);
405 405 }
406 406
407 407 public String getSignalNameDbg() {
408 408 return POSIXSignals.getSignalName(getSignalNumberDbg());
409 409 }
410 410
411 411 public boolean isInterpretedFrameValid() {
412 412 if (Assert.ASSERTS_ENABLED) {
413 413 Assert.that(isInterpretedFrame(), "Not an interpreted frame");
414 414 }
415 415 // These are reasonable sanity checks
416 416 if (getFP() == null || (getFP().andWithMask(2 * VM.getVM().getAddressSize() - 1)) != null) {
417 417 return false;
418 418 }
419 419 if (getSP() == null || (getSP().andWithMask(2 * VM.getVM().getAddressSize() - 1)) != null) {
420 420 return false;
421 421 }
422 422 if (getFP().addOffsetTo(INTERPRETER_FRAME_VM_LOCAL_WORDS * VM.getVM().getAddressSize()).lessThan(getSP())) {
423 423 return false;
424 424 }
425 425
426 426 OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0);
427 427
428 428 if (VM.getVM().getObjectHeap().isValidMethod(methodHandle) == false) {
429 429 return false;
430 430 }
431 431
432 432 // These are hacks to keep us out of trouble.
433 433 // The problem with these is that they mask other problems
434 434 if (getFP().lessThanOrEqual(getSP())) { // this attempts to deal with unsigned comparison above
435 435 return false;
436 436 }
437 437 if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) { // stack frames shouldn't be large.
438 438 return false;
439 439 }
440 440 // FIXME: this is not atomic with respect to GC and is unsuitable
441 441 // for use in a non-debugging, or reflective, system. Need to
442 442 // figure out how to express this.
443 443 Address bcx = addressOfInterpreterFrameBCX().getAddressAt(0);
444 444
445 445 Method method;
446 446 try {
447 447 method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle);
448 448 } catch (UnknownOopException ex) {
449 449 return false;
450 450 }
451 451 int bci = bcpToBci(bcx, method);
452 452 //validate bci
453 453 if (bci < 0) return false;
454 454
455 455 return true;
456 456 }
457 457
458 458 //--------------------------------------------------------------------------------
459 459 // Accessors:
460 460 //
461 461
462 462 /** Accessors */
463 463
464 464 public long frameSize() {
465 465 return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize());
466 466 }
467 467
468 468 public Address getLink() {
469 469 return unBiasSP(getFP().getAddressAt(SPARCRegisters.FP.spOffsetInSavedWindow()));
470 470 }
471 471
472 472 // FIXME: not implementable yet
473 473 // public void setLink(Address addr) {
474 474 // if (Assert.ASSERTS_ENABLED) {
475 475 // Assert.that(getLink().equals(addr), "frame nesting is controlled by hardware");
476 476 // }
477 477 // }
478 478
479 479 public Frame sender(RegisterMap regMap, CodeBlob cb) {
480 480 SPARCRegisterMap map = (SPARCRegisterMap) regMap;
481 481
482 482 if (Assert.ASSERTS_ENABLED) {
483 483 Assert.that(map != null, "map must be set");
484 484 }
485 485
486 486 // Default is we don't have to follow them. The sender_for_xxx
487 487 // will update it accordingly
488 488 map.setIncludeArgumentOops(false);
489 489
490 490 if (isEntryFrame()) {
491 491 return senderForEntryFrame(map);
492 492 }
493 493
494 494 Address youngerSP = getSP();
495 495 Address sp = getSenderSP();
496 496 boolean isInterpreted = false;
497 497
498 498 // FIXME: this is a hack to get stackwalking to work in the face
499 499 // of a signal like a SEGV. For debugging purposes it's important
500 500 // that (a) we are able to traverse the stack if we take a signal
501 501 // and (b) that we get the correct program counter in this
502 502 // situation. If we are not using alternate signal stacks then (a)
503 503 // seems to work all the time (on SPARC), but (b) is violated for
504 504 // the frame just below the signal handler.
505 505
506 506 // The mechanism for finding the ucontext is not robust. In
507 507 // addition, we may find that we need to be able to fetch more
508 508 // registers from the ucontext than just the program counter,
509 509 // since the register windows on the stack are "stale". This will
510 510 // require substantial restructuring of this frame code, so has
511 511 // been avoided for now.
512 512
513 513 // It is difficult to find a clean solution for mixing debugging
514 514 // situations with VM frame traversal. One could consider
515 515 // implementing generic frame traversal in the dbx style and only
516 516 // using the VM's stack walking mechanism on a per-frame basis,
517 517 // for example to traverse Java-level activations in a compiled
518 518 // frame. However, this will probably not interact well with the
519 519 // mechanism for finding oops on the stack.
520 520
521 521 if (VM.getVM().isDebugging()) {
522 522 // If we are a signal handler frame, use a trick: make the
523 523 // youngerSP of the caller frame point to the top of the
524 524 // ucontext's contained register set. This should allow fetching
525 525 // of the registers for the frame just below the signal handler
526 526 // frame in the usual fashion.
527 527 if (isSignalHandlerFrameDbg()) {
528 528
529 529 if (DEBUG) {
530 530 System.out.println("SPARCFrame.sender: found signal handler frame");
531 531 }
532 532
533 533 // Try to give a valid SP and PC for a "deficient frame" since
534 534 // we don't have a real register save area; making this class
535 535 // work by reading its information from a ucontext as well as
536 536 // a register save area is a major undertaking and has been
537 537 // deferred for now. It is very important that the PC is
538 538 // correct, which is why we don't just fall through to the
539 539 // other code (which would read the PC from the stale register
540 540 // window and thereby fail to get the actual location of the
541 541 // fault).
542 542
543 543 long offset = getMContextAreaOffsetInUContext();
544 544 Address fp = sp;
545 545 // System.out.println(" FP: " + fp);
546 546 fp = fp.addOffsetTo(getUContextOffset() + getMContextAreaOffsetInUContext());
547 547 // System.out.println(" start of mcontext: " + fp);
548 548 // FIXME: put these elsewhere. These are the register numbers
549 549 // in /usr/include/sys/regset.h. They might belong in
550 550 // SPARCReigsters.java, but we currently don't have that list
551 551 // of numbers in the SA code (because all of the registers are
552 552 // listed as instances of SPARCRegister) and it appears that
553 553 // our numbering of the registers and this one don't match up.
554 554 int PC_OFFSET_IN_GREGSET = 1;
555 555 int SP_OFFSET_IN_GREGSET = 17;
556 556 raw_sp = fp.getAddressAt(VM.getVM().getAddressSize() * SP_OFFSET_IN_GREGSET);
557 557 Address pc = fp.getAddressAt(VM.getVM().getAddressSize() * PC_OFFSET_IN_GREGSET);
558 558 return new SPARCFrame(raw_sp, pc);
559 559 }
560 560 }
561 561
562 562 // Note: The version of this operation on any platform with callee-save
563 563 // registers must update the register map (if not null).
↓ open down ↓ |
563 lines elided |
↑ open up ↑ |
564 564 // In order to do this correctly, the various subtypes of
565 565 // of frame (interpreted, compiled, glue, native),
566 566 // must be distinguished. There is no need on SPARC for
567 567 // such distinctions, because all callee-save registers are
568 568 // preserved for all frames via SPARC-specific mechanisms.
569 569 //
570 570 // *** HOWEVER, *** if and when we make any floating-point
571 571 // registers callee-saved, then we will have to copy over
572 572 // the RegisterMap update logic from the Intel code.
573 573
574 - if (isRicochetFrame()) return senderForRicochetFrame(map);
575 -
576 574 // The constructor of the sender must know whether this frame is interpreted so it can set the
577 575 // sender's _interpreter_sp_adjustment field.
578 576 if (VM.getVM().getInterpreter().contains(pc)) {
579 577 isInterpreted = true;
580 578 map.makeIntegerRegsUnsaved();
581 579 map.shiftWindow(sp, youngerSP);
582 580 } else {
583 581 // Find a CodeBlob containing this frame's pc or elide the lookup and use the
584 582 // supplied blob which is already known to be associated with this frame.
585 583 cb = VM.getVM().getCodeCache().findBlob(pc);
586 584 if (cb != null) {
587 585 // Update the location of all implicitly saved registers
588 586 // as the address of these registers in the register save
589 587 // area (for %o registers we use the address of the %i
590 588 // register in the next younger frame)
591 589 map.shiftWindow(sp, youngerSP);
592 590 if (map.getUpdateMap()) {
593 591 if (cb.callerMustGCArguments()) {
594 592 map.setIncludeArgumentOops(true);
595 593 }
596 594 if (cb.getOopMaps() != null) {
597 595 OopMapSet.updateRegisterMap(this, cb, map, VM.getVM().isDebugging());
598 596 }
599 597 }
600 598 }
601 599 }
602 600
603 601 return new SPARCFrame(biasSP(sp), biasSP(youngerSP), isInterpreted);
604 602 }
605 603
606 604 protected boolean hasSenderPD() {
607 605 try {
608 606 // FIXME: should not happen!!!
609 607 if (getSP() == null) {
610 608 return false;
611 609 }
612 610 if ( unBiasSP(getSP().getAddressAt(SPARCRegisters.FP.spOffsetInSavedWindow())) == null ) {
613 611 return false;
614 612 }
615 613 return true;
616 614 } catch (RuntimeException e) {
617 615 if (DEBUG) {
618 616 System.out.println("Bad frame " + this);
619 617 }
620 618 throw e;
621 619 }
622 620 }
623 621
624 622 //--------------------------------------------------------------------------------
625 623 // Return address:
626 624 //
627 625
628 626 public Address getSenderPC() {
629 627 return addressOfI7().getAddressAt(0).addOffsetTo(PC_RETURN_OFFSET);
630 628 }
631 629
632 630 // FIXME: currently unimplementable
633 631 // inline void frame::set_sender_pc(address addr) { *I7_addr() = addr - pc_return_offset; }
634 632
635 633 public Address getUnextendedSP() {
636 634 return getSP().addOffsetTo(interpreterSPAdjustmentOffset);
637 635 }
638 636
639 637 public Address getSenderSP() {
640 638 return getFP();
641 639 }
642 640
643 641 /** Given the next-younger sp for a given frame's sp, compute the
644 642 frame. We need the next-younger sp, because its register save
645 643 area holds the flushed copy of its I7, which is the PC of the
646 644 frame we are interested in. */
647 645 public SPARCFrame afterSave() {
648 646 return new SPARCFrame(biasSP(getYoungerSP()), null);
649 647 }
650 648
651 649 /** Accessors for the instance variables */
652 650 public Address getFP() {
653 651 Address sp = getSP();
654 652 if (sp == null) {
655 653 System.out.println("SPARCFrame.getFP(): sp == null");
656 654 }
657 655 Address fpAddr = sp.addOffsetTo(SPARCRegisters.FP.spOffsetInSavedWindow());
658 656 try {
659 657 Address fp = unBiasSP(fpAddr.getAddressAt(0));
660 658 if (fp == null) {
661 659 System.out.println("SPARCFrame.getFP(): fp == null (&fp == " + fpAddr + ")");
662 660 }
663 661 return fp;
664 662 } catch (RuntimeException e) {
665 663 System.out.println("SPARCFrame.getFP(): is bad (&fp == " + fpAddr + " sp = " + sp + ")");
666 664 return null;
667 665 }
668 666 }
669 667
670 668 private Address addressOfFPSlot(int index) {
671 669 return getFP().addOffsetTo(index * VM.getVM().getAddressSize());
672 670 }
673 671
674 672 // FIXME: temporarily elided
675 673 // // All frames
676 674 //
677 675 // intptr_t* fp_addr_at(int index) const { return &fp()[index]; }
678 676 // intptr_t* sp_addr_at(int index) const { return &sp()[index]; }
679 677 // intptr_t fp_at( int index) const { return *fp_addr_at(index); }
680 678 // intptr_t sp_at( int index) const { return *sp_addr_at(index); }
681 679 //
682 680 // private:
683 681 // inline address* I7_addr() const;
684 682 // inline address* O7_addr() const;
685 683 //
686 684 // inline address* I0_addr() const;
687 685 // inline address* O0_addr() const;
688 686 //
689 687 // public:
690 688 // // access to SPARC arguments and argument registers
691 689 //
692 690 // intptr_t* register_addr(Register reg) const {
693 691 // return sp_addr_at(reg.sp_offset_in_saved_window());
694 692 // }
695 693 // intptr_t* memory_param_addr(int param_ix, bool is_in) const {
696 694 // int offset = callee_register_argument_save_area_sp_offset + param_ix;
697 695 // if (is_in)
698 696 // return fp_addr_at(offset);
699 697 // else
700 698 // return sp_addr_at(offset);
701 699 // }
702 700 // intptr_t* param_addr(int param_ix, bool is_in) const {
703 701 // if (param_ix >= callee_register_argument_save_area_words)
704 702 // return memory_param_addr(param_ix, is_in);
705 703 // else if (is_in)
706 704 // return register_addr(Argument(param_ix, true).as_register());
707 705 // else {
708 706 // // the registers are stored in the next younger frame
709 707 // // %%% is this really necessary?
710 708 // frame next_younger = after_save();
711 709 // return next_younger.register_addr(Argument(param_ix, true).as_register());
712 710 // }
713 711 // }
714 712
715 713 //--------------------------------------------------------------------------------
716 714 // Interpreter frames:
717 715 //
718 716
719 717 /** 2 words, also used to save float regs across calls to C */
720 718 public static final int INTERPRETER_FRAME_D_SCRATCH_FP_OFFSET = -2;
721 719 public static final int INTERPRETER_FRAME_L_SCRATCH_FP_OFFSET = -4;
722 720 /** For native calls only */
723 721 public static final int INTERPRETER_FRAME_PADDING_OFFSET = -5;
724 722 /** For native calls only */
725 723 public static final int INTERPRETER_FRAME_MIRROR_OFFSET = -6;
726 724 /** Should be same as above, and should be zero mod 8 */
727 725 public static final int INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET = -6;
728 726 public static final int INTERPRETER_FRAME_VM_LOCAL_WORDS = -INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET;
729 727
730 728 /** Interpreter frame set-up needs to save 2 extra words in outgoing
731 729 param area for class and jnienv arguments for native stubs (see
732 730 nativeStubGen_sparc.cpp) */
733 731 public static final int INTERPRETER_FRAME_EXTRA_OUTGOING_ARGUMENT_WORDS = 2;
734 732
735 733 // FIXME: elided for now
736 734 //
737 735 // // the compiler frame has many of the same fields as the interpreter frame
738 736 // // %%%%% factor out declarations of the shared fields
739 737 // enum compiler_frame_fixed_locals {
740 738 // compiler_frame_d_scratch_fp_offset = -2,
741 739 // compiler_frame_vm_locals_fp_offset = -2, // should be same as above
742 740 //
743 741 // compiler_frame_vm_local_words = -compiler_frame_vm_locals_fp_offset
744 742 // };
745 743 //
746 744 // private:
747 745 //
748 746 // // where LcpoolCache is saved:
749 747 // constantPoolCacheOop* interpreter_frame_cpoolcache_addr() const {
750 748 // return (constantPoolCacheOop*)sp_addr_at( LcpoolCache.sp_offset_in_saved_window());
751 749 // }
752 750 //
753 751 // // where Lmonitors is saved:
754 752 // BasicObjectLock** interpreter_frame_monitors_addr() const {
755 753 // return (BasicObjectLock**) sp_addr_at( Lmonitors.sp_offset_in_saved_window());
756 754 // }
757 755 // intptr_t** interpreter_frame_esp_addr() const {
758 756 // return (intptr_t**)sp_addr_at( Lesp.sp_offset_in_saved_window());
759 757 // }
760 758 //
761 759 // inline void interpreter_frame_set_tos_address(intptr_t* x);
762 760 //
763 761 // // next two fns read and write Lmonitors value,
764 762 // private:
765 763 // BasicObjectLock* interpreter_frame_monitors() const { return *interpreter_frame_monitors_addr(); }
766 764 // void interpreter_frame_set_monitors(BasicObjectLock* monitors) { *interpreter_frame_monitors_addr() = monitors; }
767 765 //
768 766 //#ifndef CORE
769 767 //inline oop *frame::pd_compiled_argument_to_location(VMReg::Name reg, RegisterMap reg_map, int arg_size) const {
770 768 // COMPILER1_ONLY(return (oop *) (arg_size - 1 - reg + sp() + memory_parameter_word_sp_offset); )
771 769 // COMPILER2_ONLY(return oopmapreg_to_location(reg, ®_map); )
772 770 //}
773 771 //#endif
774 772
775 773 // FIXME: NOT FINISHED
776 774 public Address addressOfInterpreterFrameLocals() {
777 775 return getSP().addOffsetTo(SPARCRegisters.Llocals.spOffsetInSavedWindow());
778 776 }
779 777
780 778 // FIXME: this is not atomic with respect to GC and is unsuitable
781 779 // for use in a non-debugging, or reflective, system.
782 780 private Address addressOfInterpreterFrameBCX() {
783 781 // %%%%% reinterpreting Lbcp as a bcx
784 782 return getSP().addOffsetTo(SPARCRegisters.Lbcp.spOffsetInSavedWindow());
785 783 }
786 784
787 785 public int getInterpreterFrameBCI() {
788 786 // FIXME: this is not atomic with respect to GC and is unsuitable
789 787 // for use in a non-debugging, or reflective, system. Need to
790 788 // figure out how to express this.
791 789 Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
792 790 OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0);
793 791 Method method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle);
794 792 return bcpToBci(bcp, method);
795 793 }
796 794
797 795 public Address addressOfInterpreterFrameExpressionStack() {
798 796 return addressOfInterpreterFrameMonitors().addOffsetTo(-1 * VM.getVM().getAddressSize());
799 797 }
800 798
801 799 public int getInterpreterFrameExpressionStackDirection() {
802 800 return -1;
803 801 }
804 802
805 803 /** Top of expression stack */
806 804 public Address addressOfInterpreterFrameTOS() {
807 805 return getSP().getAddressAt(SPARCRegisters.Lesp.spOffsetInSavedWindow()).addOffsetTo(VM.getVM().getAddressSize());
808 806 }
809 807
810 808 /** Expression stack from top down */
811 809 public Address addressOfInterpreterFrameTOSAt(int slot) {
812 810 return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize());
813 811 }
814 812
815 813 public Address getInterpreterFrameSenderSP() {
816 814 if (Assert.ASSERTS_ENABLED) {
817 815 Assert.that(isInterpretedFrame(), "interpreted frame expected");
818 816 }
819 817 return getFP();
820 818 }
821 819
822 820 // FIXME: elided for now
823 821 //inline void frame::interpreter_frame_set_tos_address( intptr_t* x ) {
824 822 // *interpreter_frame_esp_addr() = x - 1;
825 823 //}
826 824
827 825 //--------------------------------------------------------------------------------
828 826 // Monitors:
829 827 //
830 828
831 829 private Address addressOfInterpreterFrameMonitors() {
832 830 return getSP().addOffsetTo(SPARCRegisters.Lmonitors.spOffsetInSavedWindow()).getAddressAt(0);
833 831 }
834 832
835 833 // Monitors
836 834 public BasicObjectLock interpreterFrameMonitorBegin() {
837 835 int roundedVMLocalWords = Bits.roundTo(INTERPRETER_FRAME_VM_LOCAL_WORDS, WORDS_PER_LONG);
838 836 return new BasicObjectLock(addressOfFPSlot(-1 * roundedVMLocalWords));
839 837 }
840 838
841 839 public BasicObjectLock interpreterFrameMonitorEnd() {
842 840 return new BasicObjectLock(addressOfInterpreterFrameMonitors());
843 841 }
844 842
845 843 public int interpreterFrameMonitorSize() {
846 844 return Bits.roundTo(BasicObjectLock.size(), WORDS_PER_LONG * (int) VM.getVM().getAddressSize());
847 845 }
848 846
849 847 // FIXME: elided for now
850 848 // // monitor elements
851 849 //
852 850 // // in keeping with Intel side: end is lower in memory than begin;
853 851 // // and beginning element is oldest element
854 852 // // Also begin is one past last monitor.
855 853 //
856 854 // inline BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
857 855 // int rounded_vm_local_words = round_to(frame::interpreter_frame_vm_local_words, WordsPerLong);
858 856 // return (BasicObjectLock *)fp_addr_at(-rounded_vm_local_words);
859 857 // }
860 858 //
861 859 // inline BasicObjectLock* frame::interpreter_frame_monitor_end() const {
862 860 // return interpreter_frame_monitors();
863 861 // }
864 862 //
865 863 //
866 864 // inline void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
867 865 // interpreter_frame_set_monitors(value);
868 866 // }
869 867 //
870 868 //
871 869 // inline int frame::interpreter_frame_monitor_size() {
872 870 // return round_to(BasicObjectLock::size(), WordsPerLong);
873 871 // }
874 872
875 873 public Address addressOfInterpreterFrameMethod() {
876 874 return getSP().addOffsetTo(SPARCRegisters.Lmethod.spOffsetInSavedWindow());
877 875 }
878 876
879 877 public Address addressOfInterpreterFrameCPCache() {
880 878 return getSP().addOffsetTo(SPARCRegisters.LcpoolCache.spOffsetInSavedWindow());
881 879 }
882 880
883 881 //--------------------------------------------------------------------------------
884 882 // Entry frames:
885 883 //
886 884
887 885 public JavaCallWrapper getEntryFrameCallWrapper() {
888 886 // Note: adjust this code if the link argument in StubGenerator::call_stub() changes!
889 887 SPARCArgument link = new SPARCArgument(0, false);
890 888 return (JavaCallWrapper) VMObjectFactory.newObject(JavaCallWrapper.class,
891 889 getSP().getAddressAt(link.asIn().asRegister().spOffsetInSavedWindow()));
892 890 }
893 891
894 892 //
895 893 //
896 894 // inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
897 895 // // note: adjust this code if the link argument in StubGenerator::call_stub() changes!
898 896 // const Argument link = Argument(0, false);
899 897 // return (JavaCallWrapper*)sp()[link.as_in().as_register().sp_offset_in_saved_window()];
900 898 // }
901 899
902 900 //--------------------------------------------------------------------------------
903 901 // Safepoints:
904 902 //
905 903
906 904 protected Address addressOfSavedOopResult() {
907 905 return addressOfO0();
908 906 }
909 907
910 908 protected Address addressOfSavedReceiver() {
911 909 return addressOfO0();
912 910 }
913 911
914 912
915 913 //--------------------------------------------------------------------------------
916 914 // Internals only below this point
917 915 //
918 916
919 917 private Address addressOfI7() {
920 918 return getSP().addOffsetTo(SPARCRegisters.I7.spOffsetInSavedWindow());
921 919 }
922 920
923 921 private Address addressOfO7() {
924 922 return afterSave().addressOfI7();
925 923 }
926 924
927 925 private Address addressOfI0() {
928 926 return getSP().addOffsetTo(SPARCRegisters.I0.spOffsetInSavedWindow());
929 927 }
930 928
931 929 private Address addressOfO0() {
932 930 return afterSave().addressOfI0();
933 931 }
934 932
935 933 private static boolean addressesEqual(Address a1, Address a2) {
936 934 if ((a1 == null) && (a2 == null)) {
937 935 return true;
↓ open down ↓ |
352 lines elided |
↑ open up ↑ |
938 936 }
939 937
940 938 if ((a1 == null) || (a2 == null)) {
941 939 return false;
942 940 }
943 941
944 942 return (a1.equals(a2));
945 943 }
946 944
947 945
948 - private Frame senderForRicochetFrame(SPARCRegisterMap map) {
949 - if (DEBUG) {
950 - System.out.println("senderForRicochetFrame");
951 - }
952 - //RicochetFrame* f = RicochetFrame::from_frame(fr);
953 - // Cf. is_interpreted_frame path of frame::sender
954 - Address youngerSP = getSP();
955 - Address sp = getSenderSP();
956 - map.makeIntegerRegsUnsaved();
957 - map.shiftWindow(sp, youngerSP);
958 - boolean thisFrameAdjustedStack = true; // I5_savedSP is live in this RF
959 - return new SPARCFrame(biasSP(sp), biasSP(youngerSP), thisFrameAdjustedStack);
960 - }
961 -
962 946 private Frame senderForEntryFrame(RegisterMap regMap) {
963 947 SPARCRegisterMap map = (SPARCRegisterMap) regMap;
964 948
965 949 if (Assert.ASSERTS_ENABLED) {
966 950 Assert.that(map != null, "map must be set");
967 951 }
968 952 // Java frame called from C; skip all C frames and return top C
969 953 // frame of that chunk as the sender
970 954 JavaCallWrapper jcw = getEntryFrameCallWrapper();
971 955 if (Assert.ASSERTS_ENABLED) {
972 956 Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero");
973 957 Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack");
974 958 }
975 959 Address lastJavaSP = jcw.getLastJavaSP();
976 960 Address lastJavaPC = jcw.getLastJavaPC();
977 961 map.clear();
978 962
979 963 map.makeIntegerRegsUnsaved();
980 964 map.shiftWindow(lastJavaSP, null);
981 965
982 966 if (Assert.ASSERTS_ENABLED) {
983 967 Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
984 968 }
985 969
986 970 if (lastJavaPC != null) {
987 971 return new SPARCFrame(biasSP(lastJavaSP), lastJavaPC);
988 972 } else {
989 973 Address youngerSP = getNextYoungerSP(lastJavaSP, getSP());
990 974 return new SPARCFrame(biasSP(lastJavaSP), biasSP(youngerSP), false);
991 975 }
992 976 }
993 977
994 978 private static Address getNextYoungerSP(Address oldSP, Address youngSP) {
995 979 Address sp = getNextYoungerSPOrNull(oldSP, youngSP, null);
996 980 if (Assert.ASSERTS_ENABLED) {
997 981 Assert.that(sp != null, "missed the SP");
998 982 }
999 983 return sp;
1000 984 }
1001 985
1002 986 private static Address getNextYoungerSPOrNull(Address oldSP, Address youngSP, Address sp) {
1003 987 if (youngSP == null) {
1004 988 // FIXME
1005 989 throw new RuntimeException("can not handle null youngSP in debugging system (seems to require register window flush)");
1006 990 }
1007 991
1008 992 if (sp == null) {
1009 993 sp = youngSP;
1010 994 }
1011 995
1012 996 Address previousSP = null;
1013 997
1014 998 /** Minimum frame size is 16 */
1015 999 int maxFrames = (int) (oldSP.minus(sp) / (16 * VM.getVM().getAddressSize()));
1016 1000
1017 1001 while(!sp.equals(oldSP) && spIsValid(oldSP, youngSP, sp)) {
1018 1002 if (maxFrames-- <= 0) {
1019 1003 // too many frames have gone by; invalid parameters given to this function
1020 1004 break;
1021 1005 }
1022 1006 previousSP = sp;
1023 1007 sp = unBiasSP(sp.getAddressAt(SPARCRegisters.FP.spOffsetInSavedWindow()));
1024 1008 }
1025 1009
1026 1010 return (sp.equals(oldSP) ? previousSP : null);
1027 1011 }
1028 1012
1029 1013 private static boolean spIsValid(Address oldSP, Address youngSP, Address sp) {
1030 1014 long mask = VM.getVM().getAddressSize();
1031 1015 mask = 2 * mask - 1;
1032 1016 return ((sp.andWithMask(mask) == null) &&
1033 1017 (sp.lessThanOrEqual(oldSP)) &&
1034 1018 (sp.greaterThanOrEqual(youngSP)));
1035 1019 }
1036 1020
1037 1021 // FIXME: this is a hopefully temporary hack (not sure what is going on)
1038 1022 public long getUContextOffset() {
1039 1023 // FIXME: there is something I clearly don't understand about the
1040 1024 // way the signal handler frame is laid out, because I shouldn't need this extra offset
1041 1025 int MAJOR_HACK_OFFSET = 8;
1042 1026 // System.out.println(" SPARCFrame.isSignalHandlerFrameDbg: I2 = " + i2 + ", fp = " + fp + ", youngerSP = " + youngerSP);
1043 1027 return VM.getVM().getAddressSize() * (REGISTER_SAVE_WORDS + MAJOR_HACK_OFFSET);
1044 1028 }
1045 1029
1046 1030 public long getMContextAreaOffsetInUContext() {
1047 1031 // From dbx-related sources:
1048 1032 // /*
1049 1033 // * struct sigframe is declaredf in the kernel sources in
1050 1034 // * .../uts/sun4c/os/machdep.c/sendsig()
1051 1035 // * unfortunately we only get a pointer to the 'uc' passed
1052 1036 // * to the sighandler so we need to do this stuff to get
1053 1037 // * to 'rwin'.
1054 1038 // * Have to do it like this to take account of alignment.
1055 1039 // */
1056 1040 // static struct sigframe {
1057 1041 // struct rwindow rwin;
1058 1042 // ucontext_t uc;
1059 1043 // } sf_help;
1060 1044
1061 1045 // From /usr/include/sys/ucontext.h:
1062 1046 // #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
1063 1047 // struct ucontext {
1064 1048 // #else
1065 1049 // struct __ucontext {
1066 1050 // #endif
1067 1051 // uint_t uc_flags;
1068 1052 // ucontext_t *uc_link;
1069 1053 // sigset_t uc_sigmask;
1070 1054 // stack_t uc_stack;
1071 1055 // mcontext_t uc_mcontext;
1072 1056 // #ifdef __sparcv9
1073 1057 // long uc_filler[4];
1074 1058 // #else /* __sparcv9 */
1075 1059 // long uc_filler[23];
1076 1060 // #endif /* __sparcv9 */
1077 1061 // };
1078 1062
1079 1063 // This walks to the start of the gregs in the mcontext_t
1080 1064 // (first entry in that data structure). Really should read
1081 1065 // this from header file.
1082 1066
1083 1067 // Also not sure exactly how alignment works...maybe should read these offsets from the target VM
1084 1068 // (When you have a hammer, everything looks like a nail)
1085 1069 long offset = VM.getVM().alignUp(4, VM.getVM().getAddressSize()); // uc_flags
1086 1070 offset = VM.getVM().alignUp(offset + VM.getVM().getAddressSize(), 8); // uc_link plus
1087 1071 // doubleword alignment for structs?
1088 1072 offset += 16 + // uc_sigmask
1089 1073 2 * VM.getVM().getAddressSize() + 4; // uc_stack
1090 1074 offset = VM.getVM().alignUp(offset + VM.getVM().getAddressSize(), 8); // doubleword alignment for structs?
1091 1075
1092 1076 // System.out.println("SPARCFrame.getMContextAreaOffsetInUContext: offset = " + offset);
1093 1077
1094 1078 return offset;
1095 1079 }
1096 1080 }
↓ open down ↓ |
125 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX