2 Copyright (C) 2001-2008, The Perl Foundation.
7 src/jit_debug_xcoff.c - XCOFF stabs for JIT
11 Write an XCOFF stabs file for JIT code. This file is based on
14 Stabs is a file format for information that describes a program to a
17 For more information see the stabs documentation at
18 http://sources.redhat.com/gdb/current/onlinedocs/stabs_toc.html.
28 /* HEADERIZER HFILE: none */
31 #include <parrot/parrot.h>
32 #include "parrot/exec.h"
37 /* following from /usr/include/dbxstclass.h */
38 # define C_GSYM "0x80" /* global variable */
39 # define C_LSYM "0x81" /* stack variable */
40 # define C_PSYM "0x82" /* parameter */
41 # define C_RSYM "0x83" /* register variable */
42 # define C_RPSYM "0x84"
43 # define C_STSYM "0x85" /* variable in data section */
44 # define C_TCSYM "0x86"
45 # define C_BCOMM "0x87"
46 # define C_ECOML "0x88"
47 # define C_ECOMM "0x89"
48 # define C_DECL "0x8c" /* type declaration */
49 # define C_ENTRY "0x8d"
51 # define C_BSTAT "0x8f"
52 # define C_ESTAT "0x90"
54 void Parrot_jit_debug(PARROT_INTERP
);
56 # define BIT_SIZE(t) ((int)(sizeof (t)*8))
57 # define BYTE_SIZE(t) ((int)sizeof (t))
58 # define BIT_OFFSET(str, field) ((int)(offsetof((str), (field)) * 8))
60 typedef struct BaseTypes
{
67 =item C<static void write_types(FILE *stabs, PARROT_INTERP)>
69 Writes the types to C<stabs>.
76 write_types(FILE *stabs
, PARROT_INTERP
)
79 /* borrowed from mono */
80 static BaseTypes base_types
[] = {
85 {"Int32", "-1"}, /* 5 */
87 {"Int64", ";01000000000000000000000;0777777777777777777777;"},
88 {"UInt64", ";0000000000000;01777777777777777777777;"},
90 {"Double", "-13"}, /* 10 */
91 {"LongDouble", "-14"},
93 {"INTVAL", "5;"}, /* 12 */
98 {"FLOATVAL", "10;"}, /* 13 */
103 {"CharPtr", "*1;"}, /* 15 */
106 for (i
= 0; base_types
[i
].name
; ++i
) {
107 if (! base_types
[i
].spec
)
109 fprintf(stabs
, ".stabx \"%s:t%d=", base_types
[i
].name
, i
);
110 if (base_types
[i
].spec
[0] == ';') {
111 fprintf(stabs
, "r%d%s\"", i
, base_types
[i
].spec
);
114 fprintf(stabs
, "%s\"", base_types
[i
].spec
);
116 fprintf(stabs
, ",0," C_DECL
",0\n");
118 fprintf(stabs
, ".stabx \"STRING:t%d=*%d\""
119 ",0," C_DECL
",0\n", i
, i
+1);
121 fprintf(stabs
, ".stabx \"Parrot_String:T%d=s%d"
123 "buflen:6,%d,%d;" /* XXX type */
126 "strstart:15,%d,%d;" /* fake a char* */
128 ",0," C_DECL
",0\n", i
++, BYTE_SIZE(STRING
),
129 BIT_OFFSET(STRING
, cache
._b
._bufstart
), BIT_SIZE(void*),
130 BIT_OFFSET(STRING
, cache
._b
._buflen
), BIT_SIZE(size_t),
131 BIT_OFFSET(STRING
, flags
), BIT_SIZE(UINTVAL
),
132 BIT_OFFSET(STRING
, bufused
), BIT_SIZE(UINTVAL
),
133 BIT_OFFSET(STRING
, strstart
), BIT_SIZE(void*));
135 fprintf(stabs
, ".stabx \"PMCType:T%d=e", i
++);
136 for (j
= 0; j
< interp
->n_vtable_max
; ++j
) {
137 if (interp
->vtables
[j
] && interp
->vtables
[j
]->whoami
) {
138 STRING
* name
= interp
->vtables
[j
]->whoami
;
139 fwrite(name
->strstart
, name
->strlen
, 1, stabs
);
140 fprintf(stabs
, ":%d,", j
);
143 fprintf(stabs
, ";\",0," C_DECL
",0\n");
146 fprintf(stabs
, ".stabx \"PMC:T%d=s%d", i
, BYTE_SIZE(PMC
));
147 fprintf(stabs
, "cache:%d,%d,%d;",
148 i
+ 1, BIT_OFFSET(PMC
, cache
), BIT_SIZE(UnionVal
));
149 fprintf(stabs
, "flags:%d,%d,%d;",
150 i
+ 1, BIT_OFFSET(PMC
, flags
), BIT_SIZE(Parrot_UInt
));
151 fprintf(stabs
, "vtable:*%d,%d,%d;",
152 i
+ 3, BIT_OFFSET(PMC
, vtable
), BIT_SIZE(void*));
153 fprintf(stabs
, "data:14,%d,%d;",
154 BIT_OFFSET(PMC
, data
), BIT_SIZE(void*));
155 fprintf(stabs
, "pmc_ext:*%d,%d,%d;",
156 i
, BIT_OFFSET(PMC
, pmc_ext
), BIT_SIZE(void*));
157 fprintf(stabs
, ";\"");
158 fprintf(stabs
, ",0," C_DECL
",0\n");
160 fprintf(stabs
, ".stabx \"cache:%d,%d,%d;"
164 i
+ 2, BIT_SIZE(UnionVal
), BIT_SIZE(Parrot_UInt
));
165 fprintf(stabs
, ".stabx \"UnionVal:T%d=u%d"
169 ",0," C_DECL
",0\n", i
+ 2, BYTE_SIZE(UnionVal
),
170 BIT_OFFSET(UnionVal
, int_val
), BIT_SIZE(INTVAL
),
171 i
, BIT_OFFSET(UnionVal
, pmc_val
), BIT_SIZE(void*));
172 fprintf(stabs
, ".stabx \"VTABLE:T%d=s%d"
173 "base_type:%d,%d,%d;"
175 ",0," C_DECL
",0\n", i
+ 3, BYTE_SIZE(UnionVal
),
176 i
- 1, BIT_OFFSET(VTABLE
, base_type
), BIT_SIZE(INTVAL
));
184 write_vars(FILE *stabs, PARROT_INTERP)>
186 Writes the contents of the registers to C<stabs>.
193 write_vars(FILE *stabs
, PARROT_INTERP
)
196 /* fake static var stabs */
197 fprintf(stabs
, ".bs parrot_jit_vars\n");
198 for (i
= 0; i
< NUM_REGISTERS
; i
++) {
199 fprintf(stabs
, ".stabx \"I%d:V12\",0x%p," C_STSYM
",0\n", i
,
200 (char*)®_INT(interp
, i
));
201 fprintf(stabs
, ".stabx \"N%d:V13\",0x%p," C_STSYM
",0\n", i
,
202 (char*)®_NUM(interp
, i
));
203 fprintf(stabs
, ".stabx \"S%d:V16\",0x%p," C_STSYM
",0\n", i
,
204 (char*)®_STR(interp
, i
));
205 fprintf(stabs
, ".stabx \"P%d:V19\",0x%p," C_STSYM
",0\n", i
,
206 (char*)®_PMC(interp
, i
));
208 fprintf(stabs
, ".es\n");
213 =item C<static STRING *
214 debug_file(PARROT_INTERP, STRING *file, const char *ext)>
216 Returns C<file> with C<ext> appended.
223 debug_file(PARROT_INTERP
, STRING
*file
, const char *ext
)
226 ret
= string_copy(interp
, file
);
227 ret
= string_append(interp
, ret
,
228 string_make(interp
, ext
, strlen(ext
), NULL
,
229 PObj_external_FLAG
));
236 Parrot_jit_debug_stabs(PARROT_INTERP)>
238 Writes the JIT debugging stabs.
245 Parrot_jit_debug_stabs(PARROT_INTERP
)
247 Parrot_jit_info_t
*jit_info
= interp
->jit_info
;
249 STRING
*pasmfile
, *stabsfile
, *ofile
, *cmd
;
255 if (interp
->code
->debugs
) {
257 char *src
= string_to_cstring(interp
,
258 Parrot_debug_pc_to_filename(interp
,
259 interp
->code
->debugs
, 0));
260 pasmfile
= string_make(interp
, src
, strlen(src
), NULL
,
262 file
= string_copy(interp
, pasmfile
);
265 ext
= strrchr(src
, '.');
266 if (ext
&& STREQ(ext
, ".pasm"))
267 string_chopn_inplace(interp
, file
, 4);
268 else if (ext
&& STREQ(ext
, ".pir"))
269 string_chopn_inplace(interp
, file
, 3);
270 else if (!ext
) /* EVAL_n */
271 file
= string_append(interp
, file
,
272 string_make(interp
, ".", 1, NULL
, PObj_external_FLAG
));
273 string_cstring_free(src
);
277 string_chopn_inplace(interp
, file
, 3);
278 pasmfile
= debug_file(interp
, file
, "pasm");
280 stabsfile
= debug_file(interp
, file
, "stabs.s");
281 ofile
= debug_file(interp
, file
, "o");
283 char *temp
= string_to_cstring(interp
, stabsfile
);
284 stabs
= fopen(temp
, "w");
285 string_cstring_free(temp
);
291 char *temp
= string_to_cstring(interp
, pasmfile
);
293 fprintf(stabs
, ".file \"%s\"\n", temp
);
294 string_cstring_free(temp
);
296 /* declare function name */
297 fprintf(stabs
, ".jit_func:\n");
298 /* jit_func start addr */
299 fprintf(stabs
, ".stabx \"jit_func:F1\",0x%p," C_FUN
",0\n",
300 jit_info
->arena
.start
);
301 fprintf(stabs
, ".function .jit_func,.jit_func,0,0\n");
302 fprintf(stabs
, ".bf 1\n");
304 write_types(stabs
, interp
);
305 write_vars(stabs
, interp
);
306 /* if we don't have line numbers, emit dummys, assuming there are
307 * no comments and spaces in source for testing
311 fprintf(stabs
, ".line 1\n");
314 for (i
= 0; i
< interp
->code
->base
.size
; i
++) {
315 if (jit_info
->arena
.op_map
[i
].ptr
) {
316 op_info_t
* op
= &interp
->op_info_table
[
317 interp
->code
->base
.data
[i
]];
318 if (interp
->code
->debugs
) {
319 line
= (int)interp
->code
->debugs
->base
.data
[lc
++];
321 fprintf(stabs
, ".line %d # 0x%p %s\n", line
,
322 (int)((char *)jit_info
->arena
.op_map
[i
].ptr
-
323 (char *)jit_info
->arena
.start
),
329 fprintf(stabs
, ".stabx \"\",0x%p," C_FUN
",0\n",
330 (char *) jit_info
->arena
.size
);
331 fprintf(stabs
, ".ef %d\n", line
);
333 /* run the stabs file through C<as> generating file.o */
334 cmd
= Parrot_sprintf_c(interp
, "as %Ss -o %Ss", stabsfile
, ofile
);
337 char *temp
= string_to_cstring(interp
, cmd
);
339 string_cstring_free(temp
);
346 Parrot_jit_debug(PARROT_INTERP)>
348 Writes the JIT debugging stabs. Just calls C<Parrot_jit_debug_stabs()>.
355 Parrot_jit_debug(PARROT_INTERP
)
357 Parrot_jit_debug_stabs(interp
);
369 F<src/jit_debug.c>, F<src/jit.c>, F<src/jit.h>.
378 * c-file-style: "parrot"
380 * vim: expandtab shiftwidth=4: