1 /*
2  * Copyright (c) 2003, 2012, 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 /* This file is auto-generated */
26 #include "JvmOffsetsIndex.h"
27 
28 #define DEBUG
29 
30 #ifdef DEBUG
31 #define MARK_LINE this->line = __LINE__
32 #else
33 #define MARK_LINE
34 #endif
35 
36 #ifdef _LP64
37 #define STACK_BIAS 0x7ff
38 #define pointer uint64_t
39 #else
40 #define STACK_BIAS 0
41 #define pointer uint32_t
42 #endif
43 
44 extern pointer __JvmOffsets;
45 
46 extern pointer __1cJCodeCacheF_heap_;
47 extern pointer __1cIUniverseO_collectedHeap_;
48 
49 extern pointer __1cHnmethodG__vtbl_;
50 extern pointer __1cNMethodG__vtbl_;
51 extern pointer __1cKBufferBlobG__vtbl_;
52 
53 #define copyin_ptr(ADDR)    *(pointer*)  copyin((pointer) (ADDR), sizeof(pointer))
54 #define copyin_uchar(ADDR)  *(uchar_t*)  copyin((pointer) (ADDR), sizeof(uchar_t))
55 #define copyin_uint16(ADDR) *(uint16_t*) copyin((pointer) (ADDR), sizeof(uint16_t))
56 #define copyin_uint32(ADDR) *(uint32_t*) copyin((pointer) (ADDR), sizeof(uint32_t))
57 #define copyin_int32(ADDR)  *(int32_t*)  copyin((pointer) (ADDR), sizeof(int32_t))
58 #define copyin_uint8(ADDR)  *(uint8_t*)  copyin((pointer) (ADDR), sizeof(uint8_t))
59 
60 #define SAME(x) x
61 #define copyin_offset(JVM_CONST)  JVM_CONST = \
62 	copyin_int32(JvmOffsetsPtr + SAME(IDX_)JVM_CONST * sizeof(int32_t))
63 
64 int init_done;
65 
66 dtrace:helper:ustack:
67 {
68   MARK_LINE;
69   this->done = 0;
70   /*
71    * TBD:
72    * Here we initialize init_done, otherwise jhelper does not work.
73    * Therefore, copyin_offset() statements work multiple times now.
74    * There is a hope we could avoid it in the future, and so,
75    * this initialization can be removed.
76    */
77   init_done  = 0;
78   this->error = (char *) NULL;
79   this->result = (char *) NULL;
80   this->isMethod = 0;
81   this->codecache = 0;
82   this->klass = (pointer) NULL;
83   this->vtbl  = (pointer) NULL;
84   this->suffix = '\0';
85 }
86 
87 dtrace:helper:ustack:
88 {
89   MARK_LINE;
90   /* Initialization of JvmOffsets constants */
91   JvmOffsetsPtr = (pointer) &``__JvmOffsets;
92 }
93 
94 dtrace:helper:ustack:
95 /!init_done && !this->done/
96 {
97   MARK_LINE;
98   init_done = 1;
99 
100   copyin_offset(COMPILER);
101   copyin_offset(OFFSET_CollectedHeap_reserved);
102   copyin_offset(OFFSET_MemRegion_start);
103   copyin_offset(OFFSET_MemRegion_word_size);
104   copyin_offset(SIZE_HeapWord);
105 
106   copyin_offset(OFFSET_interpreter_frame_method);
107   copyin_offset(OFFSET_Klass_name);
108   copyin_offset(OFFSET_ConstantPool_pool_holder);
109 
110   copyin_offset(OFFSET_HeapBlockHeader_used);
111   copyin_offset(OFFSET_oopDesc_metadata);
112 
113   copyin_offset(OFFSET_Symbol_length);
114   copyin_offset(OFFSET_Symbol_body);
115 
116   copyin_offset(OFFSET_Method_constMethod);
117   copyin_offset(OFFSET_ConstMethod_constants);
118   copyin_offset(OFFSET_ConstMethod_name_index);
119   copyin_offset(OFFSET_ConstMethod_signature_index);
120 
121   copyin_offset(OFFSET_CodeHeap_memory);
122   copyin_offset(OFFSET_CodeHeap_segmap);
123   copyin_offset(OFFSET_CodeHeap_log2_segment_size);
124 
125   copyin_offset(OFFSET_VirtualSpace_low);
126   copyin_offset(OFFSET_VirtualSpace_high);
127 
128   copyin_offset(OFFSET_CodeBlob_name);
129 
130   copyin_offset(OFFSET_nmethod_method);
131   copyin_offset(SIZE_HeapBlockHeader);
132   copyin_offset(SIZE_oopDesc);
133   copyin_offset(SIZE_ConstantPool);
134 
135   copyin_offset(OFFSET_NarrowPtrStruct_base);
136   copyin_offset(OFFSET_NarrowPtrStruct_shift);
137 
138   /*
139    * The PC to translate is in arg0.
140    */
141   this->pc = arg0;
142 
143   /*
144    * The methodPtr is in %l2 on SPARC.  This can be found at
145    * offset 8 from the frame pointer on 32-bit processes.
146    */
147 #if   defined(__sparc)
148   this->methodPtr = copyin_ptr(arg1 + 2 * sizeof(pointer) + STACK_BIAS);
149 #elif defined(__i386) || defined(__amd64)
150   this->methodPtr = copyin_ptr(arg1 + OFFSET_interpreter_frame_method);
151 #else
152 #error "Don't know architecture"
153 #endif
154 
155   this->CodeCache_heap_address = copyin_ptr(&``__1cJCodeCacheF_heap_);
156 
157   /* Reading volatile values */
158   this->CodeCache_low = copyin_ptr(this->CodeCache_heap_address +
159       OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
160 
161   this->CodeCache_high = copyin_ptr(this->CodeCache_heap_address +
162       OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
163 
164   this->CodeCache_segmap_low = copyin_ptr(this->CodeCache_heap_address +
165       OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_low);
166 
167   this->CodeCache_segmap_high = copyin_ptr(this->CodeCache_heap_address +
168       OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_high);
169 
170   this->CodeHeap_log2_segment_size = copyin_uint32(
171       this->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size);
172 
173   this->Method_vtbl             = (pointer) &``__1cNMethodG__vtbl_;
174 
175   /*
176    * Get Java heap bounds
177    */
178   this->Universe_collectedHeap = copyin_ptr(&``__1cIUniverseO_collectedHeap_);
179   this->heap_start = copyin_ptr(this->Universe_collectedHeap +
180       OFFSET_CollectedHeap_reserved +
181       OFFSET_MemRegion_start);
182   this->heap_size = SIZE_HeapWord *
183     copyin_ptr(this->Universe_collectedHeap +
184         OFFSET_CollectedHeap_reserved +
185         OFFSET_MemRegion_word_size
186         );
187   this->heap_end = this->heap_start + this->heap_size;
188 }
189 
190 dtrace:helper:ustack:
191 /!this->done &&
192 this->CodeCache_low <= this->pc && this->pc < this->CodeCache_high/
193 {
194   MARK_LINE;
195   this->codecache = 1;
196 
197   /*
198    * Find start.
199    */
200   this->segment = (this->pc - this->CodeCache_low) >>
201     this->CodeHeap_log2_segment_size;
202   this->block = this->CodeCache_segmap_low;
203   this->tag = copyin_uchar(this->block + this->segment);
204   "second";
205 }
206 
207 dtrace:helper:ustack:
208 /!this->done && this->codecache && this->tag > 0/
209 {
210   MARK_LINE;
211   this->tag = copyin_uchar(this->block + this->segment);
212   this->segment = this->segment - this->tag;
213 }
214 
215 dtrace:helper:ustack:
216 /!this->done && this->codecache && this->tag > 0/
217 {
218   MARK_LINE;
219   this->tag = copyin_uchar(this->block + this->segment);
220   this->segment = this->segment - this->tag;
221 }
222 
223 dtrace:helper:ustack:
224 /!this->done && this->codecache && this->tag > 0/
225 {
226   MARK_LINE;
227   this->tag = copyin_uchar(this->block + this->segment);
228   this->segment = this->segment - this->tag;
229 }
230 
231 dtrace:helper:ustack:
232 /!this->done && this->codecache && this->tag > 0/
233 {
234   MARK_LINE;
235   this->tag = copyin_uchar(this->block + this->segment);
236   this->segment = this->segment - this->tag;
237 }
238 
239 dtrace:helper:ustack:
240 /!this->done && this->codecache && this->tag > 0/
241 {
242   MARK_LINE;
243   this->tag = copyin_uchar(this->block + this->segment);
244   this->segment = this->segment - this->tag;
245 }
246 
247 dtrace:helper:ustack:
248 /!this->done && this->codecache && this->tag > 0/
249 {
250   MARK_LINE;
251   this->error = "<couldn't find start>";
252   this->done = 1;
253 }
254 
255 dtrace:helper:ustack:
256 /!this->done && this->codecache/
257 {
258   MARK_LINE;
259   this->block = this->CodeCache_low +
260     (this->segment << this->CodeHeap_log2_segment_size);
261   this->used = copyin_uint32(this->block + OFFSET_HeapBlockHeader_used);
262 }
263 
264 dtrace:helper:ustack:
265 /!this->done && this->codecache && !this->used/
266 {
267   MARK_LINE;
268   this->error = "<block not in use>";
269   this->done = 1;
270 }
271 
272 dtrace:helper:ustack:
273 /!this->done && this->codecache/
274 {
275   MARK_LINE;
276   this->start = this->block + SIZE_HeapBlockHeader;
277   this->vtbl = copyin_ptr(this->start);
278 
279   this->nmethod_vtbl            = (pointer) &``__1cHnmethodG__vtbl_;
280   this->BufferBlob_vtbl         = (pointer) &``__1cKBufferBlobG__vtbl_;
281 }
282 
283 dtrace:helper:ustack:
284 /!this->done && this->vtbl == this->nmethod_vtbl/
285 {
286   MARK_LINE;
287   this->methodPtr = copyin_ptr(this->start + OFFSET_nmethod_method);
288   this->suffix = '*';
289   this->isMethod = 1;
290 }
291 
292 dtrace:helper:ustack:
293 /!this->done && this->vtbl == this->BufferBlob_vtbl/
294 {
295   MARK_LINE;
296   this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
297 }
298 
299 
300 dtrace:helper:ustack:
301 /!this->done && this->vtbl == this->BufferBlob_vtbl && this->methodPtr != 0/
302 {
303   MARK_LINE;
304   this->klass = copyin_ptr(this->methodPtr);
305   this->isMethod = this->klass == this->Method_vtbl;
306   this->done = !this->isMethod;
307 }
308 
309 dtrace:helper:ustack:
310 /!this->done && !this->isMethod/
311 {
312   MARK_LINE;
313   this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
314   this->result = this->name != 0 ? copyinstr(this->name) : "<CodeBlob>";
315   this->done = 1;
316 }
317 
318 dtrace:helper:ustack:
319 /!this->done && this->isMethod/
320 {
321   MARK_LINE;
322   this->constMethod = copyin_ptr(this->methodPtr +
323       OFFSET_Method_constMethod);
324 
325   this->nameIndex = copyin_uint16(this->constMethod +
326       OFFSET_ConstMethod_name_index);
327 
328   this->signatureIndex = copyin_uint16(this->constMethod +
329       OFFSET_ConstMethod_signature_index);
330 
331   this->constantPool = copyin_ptr(this->constMethod +
332       OFFSET_ConstMethod_constants);
333 
334   this->nameSymbol = copyin_ptr(this->constantPool +
335       this->nameIndex * sizeof (pointer) + SIZE_ConstantPool);
336 
337   this->nameSymbolLength = copyin_uint16(this->nameSymbol +
338       OFFSET_Symbol_length);
339 
340   this->signatureSymbol = copyin_ptr(this->constantPool +
341       this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool);
342 
343   this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
344       OFFSET_Symbol_length);
345 
346   this->klassPtr = copyin_ptr(this->constantPool +
347       OFFSET_ConstantPool_pool_holder);
348 
349   this->klassSymbol = copyin_ptr(this->klassPtr +
350       OFFSET_Klass_name);
351 
352   this->klassSymbolLength = copyin_uint16(this->klassSymbol +
353       OFFSET_Symbol_length);
354 
355   /*
356    * Enough for three strings, plus the '.', plus the trailing '\0'.
357    */
358   this->result = (char *) alloca(this->klassSymbolLength +
359       this->nameSymbolLength +
360       this->signatureSymbolLength + 2 + 1);
361 
362   copyinto(this->klassSymbol + OFFSET_Symbol_body,
363       this->klassSymbolLength, this->result);
364 
365   /*
366    * Add the '.' between the class and the name.
367    */
368   this->result[this->klassSymbolLength] = '.';
369 
370   copyinto(this->nameSymbol + OFFSET_Symbol_body,
371       this->nameSymbolLength,
372       this->result + this->klassSymbolLength + 1);
373 
374   copyinto(this->signatureSymbol + OFFSET_Symbol_body,
375       this->signatureSymbolLength,
376       this->result + this->klassSymbolLength +
377       this->nameSymbolLength + 1);
378 
379   /*
380    * Now we need to add a trailing '\0' and possibly a tag character.
381    */
382   this->result[this->klassSymbolLength + 1 +
383       this->nameSymbolLength +
384       this->signatureSymbolLength] = this->suffix;
385   this->result[this->klassSymbolLength + 2 +
386       this->nameSymbolLength +
387       this->signatureSymbolLength] = '\0';
388 
389   this->done = 1;
390 }
391 
392 dtrace:helper:ustack:
393 /this->done && this->error == (char *) NULL/
394 {
395   this->result;
396 }
397 
398 dtrace:helper:ustack:
399 /this->done && this->error != (char *) NULL/
400 {
401   this->error;
402 }
403 
404 dtrace:helper:ustack:
405 /!this->done && this->codecache/
406 {
407   this->done = 1;
408   "error";
409 }
410 
411 
412 dtrace:helper:ustack:
413 /!this->done/
414 {
415   NULL;
416 }
417