* ax-gdb.c (gen_var_ref): Likewise.
* findvar.c (read_var_value, symbol_read_needs_frame): Likewise.
* printcmd.c (address_info): Likewise.
* dwarf2loc.c (dwarf_expr_frame_base): Likewise.
* dwarf2read.c (dwarf2_symbol_mark_computed): Likewise.
* symtab.h: Rename struct symbol_ops to struct symbol_computed_ops.
* dwarf2loc.h: Likewise.
* dwarf2loc.c (dwarf2_locexpr_funcs, dwarf2_loclist_funcs): Likewise.
* symtab.h: (struct symbol_register_ops): New struct definition.
(struct symbol): Make "ops" member a union of symbol_computed_ops and
symbol_register_ops callback pointers.
(SYMBOL_REGISTER_OPS): New macro.
* tracepoint.c: Include "objfiles.h".
(scope_info, collect_symbol): Use SYMBOL_REGISTER_OPS register_number
callback to retrieve register numbers.
* ax-gdb.c (gen_var_ref): Likewise.
* findvar.c (read_var_value): Likewise.
* printcmd.c (address_info): Likewise.
* coffread.c (coff_reg_to_regnum): New function.
(coff_register_funcs): New static variable.
(process_coff_symbol): Do not call gdbarch_sdb_reg_to_regnum.
Install SYMBOL_REGISTER_OPS callbacks.
* mdebugread.c (mdebug_reg_to_regnum): New function.
(mdebug_register_funcs): New static variable.
(parse_symbol): Do not call gdbarch_ecoff_reg_to_regnum.
Install SYMBOL_REGISTER_OPS callbacks.
* stabsread.c (stab_reg_to_regnum): New function.
(stab_register_funcs): New static variable.
(define_symbol): Do not call gdbarch_stab_reg_to_regnum.
Install SYMBOL_REGISTER_OPS callbacks.
+2009-06-04 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * symtab.h: Rename SYMBOL_OPS to SYMBOL_COMPUTED_OPS.
+ * ax-gdb.c (gen_var_ref): Likewise.
+ * findvar.c (read_var_value, symbol_read_needs_frame): Likewise.
+ * printcmd.c (address_info): Likewise.
+ * dwarf2loc.c (dwarf_expr_frame_base): Likewise.
+ * dwarf2read.c (dwarf2_symbol_mark_computed): Likewise.
+ * symtab.h: Rename struct symbol_ops to struct symbol_computed_ops.
+ * dwarf2loc.h: Likewise.
+ * dwarf2loc.c (dwarf2_locexpr_funcs, dwarf2_loclist_funcs): Likewise.
+
+ * symtab.h: (struct symbol_register_ops): New struct definition.
+ (struct symbol): Make "ops" member a union of symbol_computed_ops and
+ symbol_register_ops callback pointers.
+ (SYMBOL_REGISTER_OPS): New macro.
+ * tracepoint.c: Include "objfiles.h".
+ (scope_info, collect_symbol): Use SYMBOL_REGISTER_OPS register_number
+ callback to retrieve register numbers.
+ * ax-gdb.c (gen_var_ref): Likewise.
+ * findvar.c (read_var_value): Likewise.
+ * printcmd.c (address_info): Likewise.
+
+ * coffread.c (coff_reg_to_regnum): New function.
+ (coff_register_funcs): New static variable.
+ (process_coff_symbol): Do not call gdbarch_sdb_reg_to_regnum.
+ Install SYMBOL_REGISTER_OPS callbacks.
+ * mdebugread.c (mdebug_reg_to_regnum): New function.
+ (mdebug_register_funcs): New static variable.
+ (parse_symbol): Do not call gdbarch_ecoff_reg_to_regnum.
+ Install SYMBOL_REGISTER_OPS callbacks.
+ * stabsread.c (stab_reg_to_regnum): New function.
+ (stab_register_funcs): New static variable.
+ (define_symbol): Do not call gdbarch_stab_reg_to_regnum.
+ Install SYMBOL_REGISTER_OPS callbacks.
+
2009-06-03 Doug Evans <dje@google.com>
* symfile.c (reread_symbols): Reset psymtabs_addrmap to NULL
this as an lvalue or rvalue, the caller will generate the
right code. */
value->kind = axs_lvalue_register;
- value->u.reg = SYMBOL_VALUE (var);
+ value->u.reg = SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch);
break;
/* A lot like LOC_REF_ARG, but the pointer lives directly in a
because it's just like any other case where the thing
has a real address. */
case LOC_REGPARM_ADDR:
- ax_reg (ax, SYMBOL_VALUE (var));
+ ax_reg (ax, SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch));
value->kind = axs_lvalue_memory;
break;
case LOC_COMPUTED:
/* FIXME: cagney/2004-01-26: It should be possible to
- unconditionally call the SYMBOL_OPS method when available.
+ unconditionally call the SYMBOL_COMPUTED_OPS method when available.
Unfortunately DWARF 2 stores the frame-base (instead of the
function) location in a function's symbol. Oops! For the
moment enable this when/where applicable. */
- SYMBOL_OPS (var)->tracepoint_var_ref (var, ax, value);
+ SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, ax, value);
break;
case LOC_OPTIMIZED_OUT:
}
}
\f
+static int
+coff_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
+{
+ return gdbarch_sdb_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+}
+
+static const struct symbol_register_ops coff_register_funcs = {
+ coff_reg_to_regnum
+};
+
static struct symbol *
process_coff_symbol (struct coff_symbol *cs,
union internal_auxent *aux,
#endif
case C_REG:
SYMBOL_CLASS (sym) = LOC_REGISTER;
- SYMBOL_VALUE (sym) = gdbarch_sdb_reg_to_regnum
- (current_gdbarch, cs->c_value);
+ SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+ SYMBOL_VALUE (sym) = cs->c_value;
add_symbol_to_list (sym, &local_symbols);
break;
case C_REGPARM:
SYMBOL_CLASS (sym) = LOC_REGISTER;
+ SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
SYMBOL_IS_ARGUMENT (sym) = 1;
- SYMBOL_VALUE (sym) = gdbarch_sdb_reg_to_regnum
- (current_gdbarch, cs->c_value);
+ SYMBOL_VALUE (sym) = cs->c_value;
add_symbol_to_list (sym, &local_symbols);
break;
something has gone wrong. */
gdb_assert (framefunc != NULL);
- if (SYMBOL_OPS (framefunc) == &dwarf2_loclist_funcs)
+ if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs)
{
struct dwarf2_loclist_baton *symbaton;
struct frame_info *frame = debaton->frame;
/* The set of location functions used with the DWARF-2 expression
evaluator. */
-const struct symbol_ops dwarf2_locexpr_funcs = {
+const struct symbol_computed_ops dwarf2_locexpr_funcs = {
locexpr_read_variable,
locexpr_read_needs_frame,
locexpr_describe_location,
/* The set of location functions used with the DWARF-2 expression
evaluator and location lists. */
-const struct symbol_ops dwarf2_loclist_funcs = {
+const struct symbol_computed_ops dwarf2_loclist_funcs = {
loclist_read_variable,
loclist_read_needs_frame,
loclist_describe_location,
#if !defined (DWARF2LOC_H)
#define DWARF2LOC_H
-struct symbol_ops;
+struct symbol_computed_ops;
struct objfile;
struct dwarf2_per_cu_data;
struct dwarf2_per_cu_data *per_cu;
};
-extern const struct symbol_ops dwarf2_locexpr_funcs;
-extern const struct symbol_ops dwarf2_loclist_funcs;
+extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
+extern const struct symbol_computed_ops dwarf2_loclist_funcs;
#endif /* dwarf2loc.h */
complaint (&symfile_complaints,
_("Location list used without specifying the CU base address."));
- SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
+ SYMBOL_COMPUTED_OPS (sym) = &dwarf2_loclist_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
else
baton->data = NULL;
}
- SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs;
+ SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
}
we failed to consider one. */
case LOC_COMPUTED:
/* FIXME: cagney/2004-01-26: It should be possible to
- unconditionally call the SYMBOL_OPS method when available.
+ unconditionally call the SYMBOL_COMPUTED_OPS method when available.
Unfortunately DWARF 2 stores the frame-base (instead of the
function) location in a function's symbol. Oops! For the
moment enable this when/where applicable. */
- return SYMBOL_OPS (sym)->read_needs_frame (sym);
+ return SYMBOL_COMPUTED_OPS (sym)->read_needs_frame (sym);
case LOC_REGISTER:
case LOC_ARG:
case LOC_REGISTER:
case LOC_REGPARM_ADDR:
{
- int regno = SYMBOL_VALUE (var);
+ int regno = SYMBOL_REGISTER_OPS (var)
+ ->register_number (var, get_frame_arch (frame));
struct value *regval;
if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR)
case LOC_COMPUTED:
/* FIXME: cagney/2004-01-26: It should be possible to
- unconditionally call the SYMBOL_OPS method when available.
+ unconditionally call the SYMBOL_COMPUTED_OPS method when available.
Unfortunately DWARF 2 stores the frame-base (instead of the
function) location in a function's symbol. Oops! For the
moment enable this when/where applicable. */
- return SYMBOL_OPS (var)->read_variable (var, frame);
+ return SYMBOL_COMPUTED_OPS (var)->read_variable (var, frame);
case LOC_UNRESOLVED:
{
aux symbols are big-endian or little-endian. Return count of
SYMR's handled (normally one). */
+static int
+mdebug_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
+{
+ return gdbarch_ecoff_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+}
+
+static const struct symbol_register_ops mdebug_register_funcs = {
+ mdebug_reg_to_regnum
+};
+
static int
parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
struct section_offsets *section_offsets, struct objfile *objfile)
goto data;
case stLocal: /* local variable, goes into current block */
+ b = top_stack->cur_block;
+ s = new_symbol (name);
+ SYMBOL_VALUE (s) = svalue;
if (sh->sc == scRegister)
{
class = LOC_REGISTER;
- svalue = gdbarch_ecoff_reg_to_regnum (current_gdbarch, svalue);
+ SYMBOL_REGISTER_OPS (s) = &mdebug_register_funcs;
}
else
class = LOC_LOCAL;
- b = top_stack->cur_block;
- s = new_symbol (name);
- SYMBOL_VALUE (s) = svalue;
data: /* Common code for symbols describing data */
SYMBOL_DOMAIN (s) = VAR_DOMAIN;
case scRegister:
/* Pass by value in register. */
SYMBOL_CLASS (s) = LOC_REGISTER;
- svalue = gdbarch_ecoff_reg_to_regnum (current_gdbarch, svalue);
+ SYMBOL_REGISTER_OPS (s) = &mdebug_register_funcs;
break;
case scVar:
/* Pass by reference on stack. */
case scVarRegister:
/* Pass by reference in register. */
SYMBOL_CLASS (s) = LOC_REGPARM_ADDR;
- svalue = gdbarch_ecoff_reg_to_regnum (current_gdbarch, svalue);
+ SYMBOL_REGISTER_OPS (s) = &mdebug_register_funcs;
break;
default:
/* Pass by value on stack. */
static void
address_info (char *exp, int from_tty)
{
+ struct gdbarch *gdbarch;
+ int regno;
struct symbol *sym;
struct minimal_symbol *msymbol;
long val;
printf_filtered ("\" is ");
val = SYMBOL_VALUE (sym);
section = SYMBOL_OBJ_SECTION (sym);
+ gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
switch (SYMBOL_CLASS (sym))
{
case LOC_COMPUTED:
/* FIXME: cagney/2004-01-26: It should be possible to
- unconditionally call the SYMBOL_OPS method when available.
+ unconditionally call the SYMBOL_COMPUTED_OPS method when available.
Unfortunately DWARF 2 stores the frame-base (instead of the
function) location in a function's symbol. Oops! For the
moment enable this when/where applicable. */
- SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout);
+ SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, gdb_stdout);
break;
case LOC_REGISTER:
+ /* GDBARCH is the architecture associated with the objfile the symbol
+ is defined in; the target architecture may be different, and may
+ provide additional registers. However, we do not know the target
+ architecture at this point. We assume the objfile architecture
+ will contain all the standard registers that occur in debug info
+ in that objfile. */
+ regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
+
if (SYMBOL_IS_ARGUMENT (sym))
printf_filtered (_("an argument in register %s"),
- gdbarch_register_name (current_gdbarch, val));
+ gdbarch_register_name (gdbarch, regno));
else
printf_filtered (_("a variable in register %s"),
- gdbarch_register_name (current_gdbarch, val));
+ gdbarch_register_name (gdbarch, regno));
break;
case LOC_STATIC:
break;
case LOC_REGPARM_ADDR:
+ /* Note comment at LOC_REGISTER. */
+ regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
printf_filtered (_("address of an argument in register %s"),
- gdbarch_register_name (current_gdbarch, val));
+ gdbarch_register_name (gdbarch, regno));
break;
case LOC_ARG:
}
}
+static int
+stab_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
+{
+ int regno = gdbarch_stab_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+
+ if (regno >= gdbarch_num_regs (gdbarch)
+ + gdbarch_num_pseudo_regs (gdbarch))
+ {
+ reg_value_complaint (regno,
+ gdbarch_num_regs (gdbarch)
+ + gdbarch_num_pseudo_regs (gdbarch),
+ SYMBOL_PRINT_NAME (sym));
+
+ regno = gdbarch_sp_regnum (gdbarch); /* Known safe, though useless */
+ }
+
+ return regno;
+}
+
+static const struct symbol_register_ops stab_register_funcs = {
+ stab_reg_to_regnum
+};
+
struct symbol *
define_symbol (CORE_ADDR valu, char *string, int desc, int type,
struct objfile *objfile)
/* Parameter which is in a register. */
SYMBOL_TYPE (sym) = read_type (&p, objfile);
SYMBOL_CLASS (sym) = LOC_REGISTER;
+ SYMBOL_REGISTER_OPS (sym) = &stab_register_funcs;
SYMBOL_IS_ARGUMENT (sym) = 1;
- SYMBOL_VALUE (sym) = gdbarch_stab_reg_to_regnum (current_gdbarch, valu);
- if (SYMBOL_VALUE (sym) >= gdbarch_num_regs (current_gdbarch)
- + gdbarch_num_pseudo_regs (current_gdbarch))
- {
- reg_value_complaint (SYMBOL_VALUE (sym),
- gdbarch_num_regs (current_gdbarch)
- + gdbarch_num_pseudo_regs (current_gdbarch),
- SYMBOL_PRINT_NAME (sym));
- SYMBOL_VALUE (sym) = gdbarch_sp_regnum (current_gdbarch);
- /* Known safe, though useless */
- }
+ SYMBOL_VALUE (sym) = valu;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
add_symbol_to_list (sym, &local_symbols);
break;
/* Register variable (either global or local). */
SYMBOL_TYPE (sym) = read_type (&p, objfile);
SYMBOL_CLASS (sym) = LOC_REGISTER;
- SYMBOL_VALUE (sym) = gdbarch_stab_reg_to_regnum (current_gdbarch, valu);
- if (SYMBOL_VALUE (sym) >= gdbarch_num_regs (current_gdbarch)
- + gdbarch_num_pseudo_regs (current_gdbarch))
- {
- reg_value_complaint (SYMBOL_VALUE (sym),
- gdbarch_num_regs (current_gdbarch)
- + gdbarch_num_pseudo_regs (current_gdbarch),
- SYMBOL_PRINT_NAME (sym));
- SYMBOL_VALUE (sym) = gdbarch_sp_regnum (current_gdbarch);
- /* Known safe, though useless */
- }
+ SYMBOL_REGISTER_OPS (sym) = &stab_register_funcs;
+ SYMBOL_VALUE (sym) = valu;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
if (within_function)
{
SYMBOL_LINKAGE_NAME (sym)) == 0)
{
SYMBOL_CLASS (prev_sym) = LOC_REGISTER;
+ SYMBOL_REGISTER_OPS (prev_sym) = &stab_register_funcs;
/* Use the type from the LOC_REGISTER; that is the type
that is actually in that register. */
SYMBOL_TYPE (prev_sym) = SYMBOL_TYPE (sym);
/* Reference parameter which is in a register. */
SYMBOL_TYPE (sym) = read_type (&p, objfile);
SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+ SYMBOL_REGISTER_OPS (sym) = &stab_register_funcs;
SYMBOL_IS_ARGUMENT (sym) = 1;
- SYMBOL_VALUE (sym) = gdbarch_stab_reg_to_regnum (current_gdbarch, valu);
- if (SYMBOL_VALUE (sym) >= gdbarch_num_regs (current_gdbarch)
- + gdbarch_num_pseudo_regs (current_gdbarch))
- {
- reg_value_complaint (SYMBOL_VALUE (sym),
- gdbarch_num_regs (current_gdbarch)
- + gdbarch_num_pseudo_regs (current_gdbarch),
- SYMBOL_PRINT_NAME (sym));
- SYMBOL_VALUE (sym) = gdbarch_sp_regnum (current_gdbarch);
- /* Known safe, though useless */
- }
+ SYMBOL_VALUE (sym) = valu;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
add_symbol_to_list (sym, &local_symbols);
break;
LOC_STATIC,
- /* Value is in register. SYMBOL_VALUE is the register number.
+ /* Value is in register. SYMBOL_VALUE is the register number
+ in the original debug format. SYMBOL_REGISTER_OPS holds a
+ function that can be called to transform this into the
+ actual register number this represents in a specific target
+ architecture (gdbarch).
For some symbol formats (stabs, for some compilers at least),
the compiler generates two symbols, an argument and a register.
LOC_OPTIMIZED_OUT,
/* The variable's address is computed by a set of location
- functions (see "struct symbol_ops" below). */
+ functions (see "struct symbol_computed_ops" below). */
LOC_COMPUTED,
};
-/* The methods needed to implement a symbol class. These methods can
+/* The methods needed to implement LOC_COMPUTED. These methods can
use the symbol's .aux_value for additional per-symbol information.
At present this is only used to implement location expressions. */
-struct symbol_ops
+struct symbol_computed_ops
{
/* Return the value of the variable SYMBOL, relative to the stack
struct axs_value * value);
};
+/* Functions used with LOC_REGISTER and LOC_REGPARM_ADDR. */
+
+struct symbol_register_ops
+{
+ int (*register_number) (struct symbol *symbol, struct gdbarch *gdbarch);
+};
+
/* This structure is space critical. See space comments at the top. */
struct symbol
/* Method's for symbol's of this class. */
/* NOTE: cagney/2003-11-02: See comment above attached to "aclass". */
- const struct symbol_ops *ops;
+ union
+ {
+ /* Used with LOC_COMPUTED. */
+ const struct symbol_computed_ops *ops_computed;
+
+ /* Used with LOC_REGISTER and LOC_REGPARM_ADDR. */
+ const struct symbol_register_ops *ops_register;
+ } ops;
/* An arbitrary data pointer, allowing symbol readers to record
additional information on a per-symbol basis. Note that this data
#define SYMBOL_TYPE(symbol) (symbol)->type
#define SYMBOL_LINE(symbol) (symbol)->line
#define SYMBOL_SYMTAB(symbol) (symbol)->symtab
-#define SYMBOL_OPS(symbol) (symbol)->ops
+#define SYMBOL_COMPUTED_OPS(symbol) (symbol)->ops.ops_computed
+#define SYMBOL_REGISTER_OPS(symbol) (symbol)->ops.ops_register
#define SYMBOL_LOCATION_BATON(symbol) (symbol)->aux_value
\f
/* A partial_symbol records the name, domain, and address class of
#include "user-regs.h"
#include "valprint.h"
#include "gdbcore.h"
+#include "objfiles.h"
#include "ax.h"
#include "ax-gdb.h"
add_memrange (collect, memrange_absolute, offset, len);
break;
case LOC_REGISTER:
- reg = SYMBOL_VALUE (sym);
+ reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, current_gdbarch);
if (info_verbose)
printf_filtered ("LOC_REG[parm] %s: ",
SYMBOL_PRINT_NAME (sym));
char **canonical, *symname, *save_args = args;
struct dict_iterator iter;
int j, count = 0;
+ struct gdbarch *gdbarch;
+ int regno;
if (args == 0 || *args == 0)
error (_("requires an argument (function, line or *addr) to define a scope"));
if (symname == NULL || *symname == '\0')
continue; /* probably botched, certainly useless */
+ gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
+
printf_filtered ("Symbol %s is ", symname);
switch (SYMBOL_CLASS (sym))
{
printf_filtered ("%s", paddress (SYMBOL_VALUE_ADDRESS (sym)));
break;
case LOC_REGISTER:
+ /* GDBARCH is the architecture associated with the objfile
+ the symbol is defined in; the target architecture may be
+ different, and may provide additional registers. However,
+ we do not know the target architecture at this point.
+ We assume the objfile architecture will contain all the
+ standard registers that occur in debug info in that
+ objfile. */
+ regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
+
if (SYMBOL_IS_ARGUMENT (sym))
printf_filtered ("an argument in register $%s",
- gdbarch_register_name
- (current_gdbarch, SYMBOL_VALUE (sym)));
+ gdbarch_register_name (gdbarch, regno));
else
printf_filtered ("a local variable in register $%s",
- gdbarch_register_name
- (current_gdbarch, SYMBOL_VALUE (sym)));
+ gdbarch_register_name (gdbarch, regno));
break;
case LOC_ARG:
printf_filtered ("an argument at stack/frame offset %ld",
SYMBOL_VALUE (sym));
break;
case LOC_REGPARM_ADDR:
+ /* Note comment at LOC_REGISTER. */
+ regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
printf_filtered ("the address of an argument, in register $%s",
- gdbarch_register_name
- (current_gdbarch, SYMBOL_VALUE (sym)));
+ gdbarch_register_name (gdbarch, regno));
break;
case LOC_TYPEDEF:
printf_filtered ("a typedef.\n");
printf_filtered ("optimized out.\n");
continue;
case LOC_COMPUTED:
- SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout);
+ SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, gdb_stdout);
break;
}
if (SYMBOL_TYPE (sym))