-/**
- * Stabs support.
+/*
+ * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
*
- * @author Michael Beck
- * @date 11.9.2006
- * @cvsid $Id$
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
*/
+/**
+ * @file
+ * @brief Stabs support.
+ * @author Michael Beck
+ * @date 11.9.2006
+ * @version $Id$
+ */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <assert.h>
+#include "obst.h"
#include "irprog.h"
-#include "entity.h"
#include "irgraph.h"
-#include "typewalk.h"
#include "tv.h"
#include "xmalloc.h"
#include "pmap.h"
typedef struct stabs_handle {
dbg_handle base; /**< the base class */
FILE *f; /**< the file write to */
- entity *cur_ent; /**< current method entity */
+ ir_entity *cur_ent; /**< current method entity */
const be_stack_layout_t *layout; /**< current stack layout */
unsigned next_type_nr; /**< next type number */
pmap *type_map; /**< a map from type to type number */
const char *main_file; /**< name of the main source file */
- const char *curr_file; /**< name of teh current source file */
+ const char *curr_file; /**< name of the current source file */
} stabs_handle;
/**
return num;
} /* get_type_number */
+/**
+ * Map a given Type to void by assigned the type number 0.
+ */
+static void map_to_void(stabs_handle *h, ir_type *tp) {
+ pmap_insert(h->type_map, tp, INT_TO_PTR(0));
+}
+
/**
* generate the void type.
*/
* @param h the stabs handle
* @param tp the type
*/
-static void gen_primitive_type(stabs_handle *h, ir_type *tp)
-{
+static void gen_primitive_type(stabs_handle *h, ir_type *tp) {
ir_mode *mode = get_type_mode(tp);
unsigned type_num;
SET_TYPE_READY(tp);
if (mode == mode_T) {
- /* jack and FirmJC compiler use mode_T for the void type.
+ /* firmcc, jack and the FirmJC compiler use mode_T for the void type.
Ignore it here as it's name is remapped to "void". */
+ map_to_void(h, tp);
return;
} /* if */
fprintf(h->f, ";\",%d,0,0,0\n", N_LSYM);
} /* gen_enum_type */
+/**
+ * print a pointer type
+ */
+void print_pointer_type(stabs_handle *h, ir_type *tp, int local) {
+ unsigned type_num = local ? h->next_type_nr++ : get_type_number(h, tp);
+ ir_type *el_tp = get_pointer_points_to_type(tp);
+ unsigned el_num = get_type_number(h, el_tp);
+
+ fprintf(h->f, "%u=*%u", type_num, el_num);
+}
+
/**
* Generates a pointer type
*
*/
static void gen_pointer_type(wenv_t *env, ir_type *tp) {
stabs_handle *h = env->h;
- unsigned type_num = get_type_number(h, tp);
ir_type *el_tp = get_pointer_points_to_type(tp);
- unsigned el_num = get_type_number(h, el_tp);
SET_TYPE_READY(tp);
if (! IS_TYPE_READY(el_tp))
waitq_put(env->wq, el_tp);
- fprintf(h->f, "\t.stabs\t\"%s:t%u=*%u\",%d,0,0,0\n",
- get_type_name(tp), type_num, el_num, N_LSYM);
+
+ fprintf(h->f, "\t.stabs\t\"%s:t", get_type_name(tp));
+ print_pointer_type(h, tp, 0);
+ fprintf(h->f, "\",%d,0,0,0\n", N_LSYM);
} /* gen_pointer_type */
+/**
+ * print an array type
+ */
+static void print_array_type(stabs_handle *h, ir_type *tp, int local) {
+ ir_type *etp = get_array_element_type(tp);
+ int i, n = get_array_n_dimensions(tp);
+ unsigned type_num = local ? h->next_type_nr++ : get_type_number(h, tp);
+ int *perm;
+
+ fprintf(h->f, "%u=a", type_num);
+ NEW_ARR_A(int, perm, n);
+ for (i = 0; i < n; ++i) {
+ perm[i] = get_array_order(tp, i);
+ }
+
+ for (i = 0; i < n; ++i) {
+ int dim = perm[i];
+
+ if (is_Const(get_array_lower_bound(tp, dim)) && is_Const(get_array_upper_bound(tp, dim))) {
+ long min = get_array_lower_bound_int(tp, dim);
+ long max = get_array_upper_bound_int(tp, dim);
+
+ /* FIXME r1 must be integer type, but seems to work for now */
+ fprintf(h->f, "r1;%ld;%ld;", min, max-1);
+ }
+ }
+
+ type_num = get_type_number(h, etp);
+ fprintf(h->f, "%d", type_num);
+}
+
+/**
+ * Generates an array type
+ *
+ * @param env the walker environment
+ * @param tp the type
+ */
+static void gen_array_type(wenv_t *env, ir_type *tp) {
+ stabs_handle *h = env->h;
+ ir_type *etp = get_array_element_type(tp);
+
+ SET_TYPE_READY(tp);
+ if (! IS_TYPE_READY(etp))
+ waitq_put(env->wq, etp);
+
+ fprintf(h->f, "\t.stabs\t\"%s:t", get_type_name(tp));
+
+ print_array_type(h, tp, 0);
+
+ fprintf(h->f, "\",%d,0,0,0\n", N_LSYM);
+} /* gen_array_type */
+
/**
* Generates a struct/union type
*
get_type_name(tp), type_num, desc, get_type_size_bytes(tp));
for (i = 0, n = get_compound_n_members(tp); i < n; ++i) {
- entity *ent = get_compound_member(tp, i);
- ir_type *mtp = get_entity_type(ent);
+ ir_entity *ent = get_compound_member(tp, i);
+ ir_type *mtp = get_entity_type(ent);
int ofs, size;
if (! IS_TYPE_READY(mtp))
waitq_put(env->wq, mtp);
- ofs = get_entity_offset_bits(ent);
+ ofs = get_entity_offset(ent);
if (is_Struct_type(mtp) && get_type_mode(mtp) != NULL) {
/* this structure is a bitfield, skip */
int i, n;
for (i = 0, n = get_struct_n_members(mtp); i < n; ++i) {
- entity *ent = get_struct_member(mtp, i);
+ ir_entity *ent = get_struct_member(mtp, i);
ir_type *tp = get_entity_type(ent);
int bofs;
type_num = get_type_number(h, tp);
size = get_type_size_bits(tp);
- bofs = ofs + get_entity_offset_bits(ent);
+ bofs = (ofs + get_entity_offset(ent)) * 8 + get_entity_offset_bits_remainder(ent);
/* name:type, bit offset from the start of the struct', number of bits in the element. */
fprintf(h->f, "%s:%u,%d,%d;", get_entity_name(ent), type_num, bofs, size);
}
} else {
/* no bitfield */
- type_num = get_type_number(h, mtp);
- size = get_type_size_bits(mtp);
+ fprintf(h->f, "%s:", get_entity_name(ent));
- /* name:type, bit offset from the start of the struct', number of bits in the element. */
- fprintf(h->f, "%s:%u,%d,%d;", get_entity_name(ent), type_num, ofs, size);
+ if (is_Array_type(mtp)) {
+ /* use a local array definition */
+ print_array_type(h, mtp, 1);
+ } else if (is_Pointer_type(mtp)) {
+ /* use local pointer definition */
+ print_pointer_type(h, mtp, 1);
+ } else {
+ type_num = get_type_number(h, mtp);
+
+ /* name:type, bit offset from the start of the struct', number of bits in the element. */
+ fprintf(h->f, "%u", type_num);
+ }
+ size = get_type_size_bits(mtp);
+ fprintf(h->f, ",%d,%d;", ofs * 8, size);
}
}
fprintf(h->f, ";\",%d,0,0,0\n", N_LSYM);
} /* gen_struct_type */
-/**
- * Generates an array type
- *
- * @param env the walker environment
- * @param tp the type
- */
-static void gen_array_type(wenv_t *env, ir_type *tp) {
- stabs_handle *h = env->h;
- unsigned type_num = get_type_number(h, tp);
- int i, n = get_array_n_dimensions(tp);
- ir_type *etp = get_array_element_type(tp);
- int *perm;
-
- SET_TYPE_READY(tp);
- if (! IS_TYPE_READY(etp))
- waitq_put(env->wq, etp);
-
- NEW_ARR_A(int, perm, n);
- for (i = 0; i < n; ++i) {
- perm[i] = get_array_order(tp, i);
- }
- fprintf(h->f, "\t.stabs\t\"%s:t%u=a", get_type_name(tp), type_num);
-
- for (i = 0; i < n; ++i) {
- int dim = perm[i];
- long min = get_array_lower_bound_int(tp, dim);
- long max = get_array_upper_bound_int(tp, dim);
-
- /* FIXME r1 must be integer type, but seems to work for now */
- fprintf(h->f, "r1;%ld;%ld;", min, max-1);
- }
-
- type_num = get_type_number(h, etp);
- fprintf(h->f, "%d\",%d,0,0,0\n", type_num, N_LSYM);
-} /* gen_array_type */
-
/**
* Generates a method type
*
static void stabs_include_begin(dbg_handle *handle, const char *filename) {
stabs_handle *h = (stabs_handle *)handle;
if (h->main_file != h->curr_file)
- stabs_include_end(h);
+ stabs_include_end(handle);
h->curr_file = filename;
fprintf(h->f, "\t.stabs\t\"%s\",%d,0,0,0\n", filename, N_SOL);
} /* stabs_include_begin */
/**
* dump the stabs for a method begin
*/
-static void stabs_method_begin(dbg_handle *handle, entity *ent, const be_stack_layout_t *layout) {
+static void stabs_method_begin(dbg_handle *handle, ir_entity *ent, const be_stack_layout_t *layout) {
stabs_handle *h = (stabs_handle *)handle;
ir_type *mtp, *rtp;
unsigned type_num;
unsigned type_num = get_type_number(h, ptp);
char buf[16];
int ofs = 0;
- entity *stack_ent;
+ ir_entity *stack_ent;
if (! name) {
snprintf(buf, sizeof(buf), "arg%d", i);
it transmitted on the stack, else in a register */
stack_ent = layout->param_map[i];
if (stack_ent) {
- ofs = get_entity_offset_bytes(stack_ent) + between_size;
+ ofs = get_entity_offset(stack_ent) + between_size;
+ }
+ fprintf(h->f, "\t.stabs\t\"%s:p", name);
+ if (is_Array_type(ptp)) {
+ /* use a local array definition */
+ print_array_type(h, ptp, 1);
+ } else if (is_Pointer_type(ptp)) {
+ /* use local pointer definition */
+ print_pointer_type(h, ptp, 1);
+ } else {
+ type_num = get_type_number(h, ptp);
+
+ /* name:type, bit offset from the start of the struct', number of bits in the element. */
+ fprintf(h->f, "%u", type_num);
}
- fprintf(h->f, "\t.stabs\t\"%s:p%u\",%d,0,0,%d\n", name, type_num, N_PSYM, ofs);
+
+ fprintf(h->f, "\",%d,0,0,%d\n", N_PSYM, ofs);
}
} /* stabs_method_begin */
*/
static void stabs_method_end(dbg_handle *handle) {
stabs_handle *h = (stabs_handle *)handle;
- entity *ent = h->cur_ent;
+ ir_entity *ent = h->cur_ent;
const be_stack_layout_t *layout = h->layout;
const char *ld_name = get_entity_ld_name(ent);
int i, n, frame_size;
/* create entries for automatic variables on the stack */
frame_size = get_type_size_bytes(layout->frame_type);
for (i = 0, n = get_compound_n_members(layout->frame_type); i < n; ++i) {
- entity *ent = get_compound_member(layout->frame_type, i);
+ ir_entity *ent = get_compound_member(layout->frame_type, i);
ir_type *tp;
int ofs;
unsigned type_num;
if (is_Method_type(tp))
continue;
type_num = get_type_number(h, tp);
- ofs = -frame_size + get_entity_offset_bytes(ent);
+ ofs = -frame_size + get_entity_offset(ent);
fprintf(h->f, "\t.stabs\t\"%s:%u\",%d,0,0,%d\n",
get_entity_name(ent), type_num, N_LSYM, ofs);
/**
* dump a variable in the global type
*/
-static void stabs_variable(dbg_handle *handle, struct obstack *obst, entity *ent) {
+static void stabs_variable(dbg_handle *handle, struct obstack *obst, ir_entity *ent) {
stabs_handle *h = (stabs_handle *)handle;
unsigned tp_num = get_type_number(h, get_entity_type(ent));
char buf[1024];
} /* be_dbg_main_program */
/** debug for a method begin */
-void be_dbg_method_begin(dbg_handle *h, entity *ent, const be_stack_layout_t *layout) {
+void be_dbg_method_begin(dbg_handle *h, ir_entity *ent, const be_stack_layout_t *layout) {
if (h && h->ops->method_begin)
h->ops->method_begin(h, ent, layout);
} /* be_dbg_method_begin */
} /* be_dbg_types */
/** dump a global */
-void be_dbg_variable(dbg_handle *h, struct obstack *obst, entity *ent) {
+void be_dbg_variable(dbg_handle *h, struct obstack *obst, ir_entity *ent) {
if (h && h->ops->variable)
h->ops->variable(h, obst, ent);
} /* be_dbg_variable */