Starting release 0.7.0
[parrot.git] / src / jit_debug_xcoff.c
blobc91cda11430d905e2fec9f37888a48354218b808
1 /*
2 Copyright (C) 2001-2008, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/jit_debug_xcoff.c - XCOFF stabs for JIT
9 =head1 DESCRIPTION
11 Write an XCOFF stabs file for JIT code. This file is based on
12 F<src/jit_debug.c>.
14 Stabs is a file format for information that describes a program to a
15 debugger.
17 For more information see the stabs documentation at
18 http://sources.redhat.com/gdb/current/onlinedocs/stabs_toc.html.
20 =head2 Functions
22 =over 4
24 =cut
28 /* HEADERIZER HFILE: none */
29 /* HEADERIZER STOP */
31 #include <parrot/parrot.h>
32 #include "parrot/exec.h"
33 #include "jit.h"
35 #ifdef __IBMC__
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"
50 # define C_FUN "0x8e"
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 {
61 const char *name;
62 const char *spec;
63 } BaseTypes;
67 =item C<static void write_types(FILE *stabs, PARROT_INTERP)>
69 Writes the types to C<stabs>.
71 =cut
75 static void
76 write_types(FILE *stabs, PARROT_INTERP)
78 int i, j;
79 /* borrowed from mono */
80 static BaseTypes base_types[] = {
81 {"Char", "-6"},
82 {"Byte", "-5"},
83 {"Int16", "-3"},
84 {"UInt16", "-7"},
85 {"Int32", "-1"}, /* 5 */
86 {"UInt32", "-8"},
87 {"Int64", ";01000000000000000000000;0777777777777777777777;"},
88 {"UInt64", ";0000000000000;01777777777777777777777;"},
89 {"Single", "-12"},
90 {"Double", "-13"}, /* 10 */
91 {"LongDouble", "-14"},
92 # if INTVAL_SIZE == 4
93 {"INTVAL", "5;"}, /* 12 */
94 # else
95 {"INTVAL", "7;"},
96 # endif
97 # if NUMVAL_SIZE == 8
98 {"FLOATVAL", "10;"}, /* 13 */
99 # else
100 {"FLOATVAL", "11;"},
101 # endif
102 {"Ptr", "*0;"},
103 {"CharPtr", "*1;"}, /* 15 */
104 {0, 0}
106 for (i = 0; base_types[i].name; ++i) {
107 if (! base_types[i].spec)
108 continue;
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);
113 else {
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);
120 ++i;
121 fprintf(stabs, ".stabx \"Parrot_String:T%d=s%d"
122 "bufstart:14,%d,%d;"
123 "buflen:6,%d,%d;" /* XXX type */
124 "flags:12,%d,%d;"
125 "bufused:12,%d,%d;"
126 "strstart:15,%d,%d;" /* fake a char* */
127 ";\""
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");
145 /* PMC type */
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;"
161 "flags:12,%d,%d;"
162 ";\""
163 ",0," C_DECL ",0\n",
164 i + 2, BIT_SIZE(UnionVal), BIT_SIZE(Parrot_UInt));
165 fprintf(stabs, ".stabx \"UnionVal:T%d=u%d"
166 "int_val:12,%d,%d;"
167 "pmc_val:*%d,%d,%d;"
168 ";\""
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;"
174 ";\""
175 ",0," C_DECL ",0\n", i + 3, BYTE_SIZE(UnionVal),
176 i - 1, BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL));
177 i += 4;
183 =item C<static void
184 write_vars(FILE *stabs, PARROT_INTERP)>
186 Writes the contents of the registers to C<stabs>.
188 =cut
192 static void
193 write_vars(FILE *stabs, PARROT_INTERP)
195 int i;
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*)&REG_INT(interp, i));
201 fprintf(stabs, ".stabx \"N%d:V13\",0x%p," C_STSYM ",0\n", i,
202 (char*)&REG_NUM(interp, i));
203 fprintf(stabs, ".stabx \"S%d:V16\",0x%p," C_STSYM ",0\n", i,
204 (char*)&REG_STR(interp, i));
205 fprintf(stabs, ".stabx \"P%d:V19\",0x%p," C_STSYM ",0\n", i,
206 (char*)&REG_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.
218 =cut
222 static STRING *
223 debug_file(PARROT_INTERP, STRING *file, const char *ext)
225 STRING *ret;
226 ret = string_copy(interp, file);
227 ret = string_append(interp, ret,
228 string_make(interp, ext, strlen(ext), NULL,
229 PObj_external_FLAG));
230 return ret;
235 =item C<static void
236 Parrot_jit_debug_stabs(PARROT_INTERP)>
238 Writes the JIT debugging stabs.
240 =cut
244 static void
245 Parrot_jit_debug_stabs(PARROT_INTERP)
247 Parrot_jit_info_t *jit_info = interp->jit_info;
248 STRING *file = NULL;
249 STRING *pasmfile, *stabsfile, *ofile, *cmd;
250 FILE *stabs;
251 size_t i;
252 int line;
253 opcode_t lc;
255 if (interp->code->debugs) {
256 char *ext;
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,
261 PObj_external_FLAG);
262 file = string_copy(interp, pasmfile);
263 /* chop pasm/pir */
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);
275 else {
276 /* chop pbc */
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);
287 if (stabs == NULL)
288 return;
291 char *temp = string_to_cstring(interp, pasmfile);
292 /* filename info */
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
310 /* jit_begin */
311 fprintf(stabs, ".line 1\n");
312 line = 1;
313 lc = 0;
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),
324 op->full_name);
325 line++;
328 /* eof */
329 fprintf(stabs, ".stabx \"\",0x%p," C_FUN ",0\n",
330 (char *) jit_info->arena.size);
331 fprintf(stabs, ".ef %d\n", line);
332 fclose(stabs);
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);
338 system(temp);
339 string_cstring_free(temp);
345 =item C<void
346 Parrot_jit_debug(PARROT_INTERP)>
348 Writes the JIT debugging stabs. Just calls C<Parrot_jit_debug_stabs()>.
350 =cut
354 void
355 Parrot_jit_debug(PARROT_INTERP)
357 Parrot_jit_debug_stabs(interp);
360 #endif
365 =back
367 =head1 SEE ALSO
369 F<src/jit_debug.c>, F<src/jit.c>, F<src/jit.h>.
371 =cut
377 * Local variables:
378 * c-file-style: "parrot"
379 * End:
380 * vim: expandtab shiftwidth=4: