Commit a02845e8 authored by Michael Beck's avatar Michael Beck
Browse files

added initial stabs debugging support

parent bf1c0196
#ifndef __BE_DBGOUT_H__
#define __BE_DBGOUT_H__
/**
* Debug output support.
*
* @author Michael Beck
* @date 11.9.2006
* @cvsid $Id$
*/
typedef struct dbg_handle dbg_handle;
/**
* Debug operations.
*/
typedef struct debug_ops {
/** close the stabs handler. */
void (*close)(dbg_handle *h);
/** begin a new file */
void (*begin)(dbg_handle *handle, const char *filename);
/** prints the stabs for a function */
void (*method)(dbg_handle *h, entity *ent);
/** prints a line number */
void (*line)(dbg_handle *h, unsigned lineno, const char *address);
} debug_ops;
/** The base class of all debug implementations. */
struct dbg_handle {
const debug_ops *ops;
};
/** close a debug handler. */
void be_dbg_close(dbg_handle *h);
/** begin a new file */
void be_dbg_begin(dbg_handle *handle, const char *filename);
/** debug for a function */
void be_dbg_method(dbg_handle *h, entity *ent);
/** debug for line number */
void be_dbg_line(dbg_handle *h, unsigned lineno, const char *address);
/** Opens a stabs handler. */
dbg_handle *be_stabs_open(FILE *out);
#endif /* __BE_DBGOUT_H__ */
......@@ -65,6 +65,7 @@
#include "bestat.h"
#include "beverify.h"
#include "beprofile.h"
#include "be_dbgout.h"
/* options visible for anyone */
static be_options_t be_options = {
......@@ -289,12 +290,14 @@ static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle)
env->phi_handler = be_phi_handler_new(env->arch_env);
arch_env_push_irn_handler(env->arch_env, env->phi_handler);
env->db_handle = be_stabs_open(file_handle);
return env;
}
static void be_done_env(be_main_env_t *env)
{
env->arch_env->isa->impl->done(env->arch_env->isa);
be_dbg_close(env->db_handle);
be_phi_handler_free(env->phi_handler);
obstack_free(&env->obst, NULL);
}
......@@ -398,8 +401,9 @@ static void initialize_birg(be_irg_t *birg, ir_graph *irg, be_main_env_t *env)
* and call the architecture specific code generator.
*
* @param file_handle the file handle the output will be written to
* @param cup_name name of the compilation unit
*/
static void be_main_loop(FILE *file_handle, const char *asm_file_name)
static void be_main_loop(FILE *file_handle, const char *cup_name)
{
int i;
arch_isa_t *isa;
......@@ -441,6 +445,8 @@ static void be_main_loop(FILE *file_handle, const char *asm_file_name)
isa = arch_env_get_isa(env.arch_env);
be_dbg_begin(env.db_handle, cup_name);
/* we might need 1 birg more for instrumentation constructor */
num_birgs = get_irp_n_irgs();
birgs = alloca(sizeof(birgs[0]) * (num_birgs + 1));
......@@ -457,7 +463,7 @@ static void be_main_loop(FILE *file_handle, const char *asm_file_name)
Beware: '\0' is already included in sizeof(suffix)
*/
memset(prof_filename, 0, sizeof(prof_filename));
strncpy(prof_filename, asm_file_name, sizeof(prof_filename) - sizeof(suffix));
strncpy(prof_filename, cup_name, sizeof(prof_filename) - sizeof(suffix));
strcat(prof_filename, suffix);
/*
......@@ -712,7 +718,7 @@ static void be_main_loop(FILE *file_handle, const char *asm_file_name)
}
/* Main interface to the frontend. */
void be_main(FILE *file_handle, const char *asm_file_name)
void be_main(FILE *file_handle, const char *cup_name)
{
#ifdef WITH_LIBCORE
lc_timer_t *t = NULL;
......@@ -744,7 +750,7 @@ void be_main(FILE *file_handle, const char *asm_file_name)
set_visit_pseudo_irgs(0);
be_node_init();
be_main_loop(file_handle, asm_file_name);
be_main_loop(file_handle, cup_name);
#ifdef WITH_LIBCORE
if (be_options.timing == BE_TIME_ON) {
......
/**
* Stabs support.
*
* @author Michael Beck
* @date 11.9.2006
* @cvsid $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include "entity.h"
#include "xmalloc.h"
#include "be_dbgout.h"
/* stabs types */
enum stabs_types {
NIL = 0,
N_GSYM = 32, /**< global symbol */
N_FUN = 36, /**< procedure */
N_STSYM = 38, /**< Initialized static variable */
N_LCSYM = 40, /**< uninitialized static var */
N_RSYM = 64, /**< global register variable */
N_SLINE = 68,
N_SO = 100, /**< name and path of the source file */
N_LSYM = 128, /**< local symbol */
N_PSYM = 160, /**< parameters to a function */
N_LBRAC = 192, /**< left brace */
N_RBRAC = 224, /**< right brace */
};
/**
* The stabs handle.
*/
typedef struct stabs_handle {
dbg_handle base; /**< the base class */
FILE *f; /**< the file write to */
entity *cur_ent;
} stabs_handle;
/**
* Returns the stabs type number of a Firm type.
*/
static unsigned get_type_number(ir_type *tp) {
return 0;
} /* get_type_number */
/**
* begin a new file
*/
static void stabs_begin(dbg_handle *handle, const char *filename) {
stabs_handle *h = (stabs_handle *)handle;
fprintf(h->f, ".stabs \"%s\",%d,0,0,.Ltext0\n", filename, N_SO);
} /* stabs_begin */
/**
* prints a line number
*/
static void stabs_line(dbg_handle *handle, unsigned lineno, const char *address) {
stabs_handle *h = (stabs_handle *)handle;
fprintf(h->f, ".stabn %d, 0, %u, %s-%s\n", N_SLINE, lineno, address, get_entity_ld_name(h->cur_ent));
} /* stabs_line */
/**
* prints the stabs for a function
*/
static void stabs_method(dbg_handle *handle, entity *ent) {
stabs_handle *h = (stabs_handle *)handle;
ir_type *tp;
unsigned type_num;
h->cur_ent = ent;
tp = get_entity_type(ent);
if (get_method_n_ress(tp) > 0)
tp = get_method_res_type(tp, 0);
else
tp = NULL;
type_num = get_type_number(tp);
fprintf(h->f, ".stabs \"%s:%c%u\",%u,0,0,%s\n",
get_entity_name(ent),
get_entity_visibility(ent) == visibility_external_visible ? 'F' : 'f',
type_num,
N_FUN,
get_entity_ld_name(ent));
} /* stabs_method */
/* close the stabs handler */
static void stabs_close(dbg_handle *handle) {
stabs_handle *h = (stabs_handle *)handle;
free(h);
} /* stabs_close */
/** The stabs operations. */
static const debug_ops stabs_ops = {
stabs_close,
stabs_begin,
stabs_method,
stabs_line,
};
/* Opens a stabs handler */
dbg_handle *be_stabs_open(FILE *out) {
stabs_handle *h = xmalloc(sizeof(*h));
h->base.ops = &stabs_ops;
h->f = out;
return &h->base;
} /* stabs_open */
/** close a debug handler. */
void be_dbg_close(dbg_handle *h) {
if (h->ops->close)
h->ops->close(h);
} /* be_dbg_close */
/**
* begin a new file
*/
void be_dbg_begin(dbg_handle *h, const char *filename) {
if (h->ops->begin)
h->ops->begin(h, filename);
} /* be_dbg_begin */
/** debug for a function */
void be_dbg_method(dbg_handle *h, entity *ent) {
if (h->ops->method)
h->ops->method(h, ent);
} /* be_dbg_method */
/** debug for line number */
void be_dbg_line(dbg_handle *h, unsigned lineno, const char *address) {
if (h->ops->line)
h->ops->line(h, lineno, address);
} /* be_dbg_line */
......@@ -23,6 +23,7 @@
#include "../besched_t.h"
#include "../benode_t.h"
#include "../be_dbgout.h"
#include "ia32_emitter.h"
#include "gen_ia32_emitter.h"
......@@ -1986,6 +1987,26 @@ static void ia32_register_emitters(void) {
#undef IA32_EMIT
}
static unsigned last_line = -1;
static const char *last_file = NULL;
static unsigned num = -1;
static void ia32_emit_dbg(const ir_node *irn, ia32_emit_env_t *env) {
dbg_info *db = get_irn_dbg_info(irn);
unsigned lineno;
const char *fname = be_retrieve_dbg_info(db, &lineno);
if (fname && last_line != lineno) {
char name[64];
FILE *F = env->out;
snprintf(name, sizeof(name), ".Ld%u", ++num);
last_line = lineno;
be_dbg_line(env->cg->birg->main_env->db_handle, lineno, name);
fprintf(F, "%s:\n", name);
}
}
/**
* Emits code for a node.
*/
......@@ -1998,6 +2019,7 @@ static void ia32_emit_node(const ir_node *irn, void *env) {
if (op->ops.generic) {
void (*emit)(const ir_node *, void *) = (void (*)(const ir_node *, void *))op->ops.generic;
ia32_emit_dbg(irn, emit_env);
(*emit)(irn, env);
}
else {
......@@ -2108,12 +2130,14 @@ static void ia32_gen_block(ir_node *block, void *env) {
/**
* Emits code for function start.
*/
static void ia32_emit_func_prolog(FILE *F, ir_graph *irg, cpu_support cpu) {
static void ia32_emit_func_prolog(FILE *F, ir_graph *irg, ia32_emit_env_t *emit_env) {
entity *irg_ent = get_irg_entity(irg);
const char *irg_name = get_entity_ld_name(irg_ent);
cpu_support cpu = emit_env->isa->opt_arch;
fprintf(F, "\n");
ia32_switch_section(F, SECTION_TEXT);
be_dbg_method(emit_env->cg->birg->main_env->db_handle, irg_ent);
ia32_emit_align_func(F, cpu);
if (get_entity_visibility(irg_ent) == visibility_external_visible) {
fprintf(F, ".globl %s\n", irg_name);
......@@ -2165,7 +2189,7 @@ void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg) {
ia32_register_emitters();
ia32_emit_func_prolog(F, irg, emit_env.isa->opt_arch);
ia32_emit_func_prolog(F, irg, &emit_env);
irg_block_walk_graph(irg, ia32_gen_labels, NULL, &emit_env);
if ((cg->opt & IA32_OPT_EXTBB) && cg->blk_sched) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment