support to use LOC_BASEREG rather than SYMBOL_BASEREG_VALID.
* dwarfread.c: Use LOC_BASEREG where appropriate.
* Various: Support LOC_BASEREG and LOC_BASEREG_ARG.
* frame.h, symtab.h, findvar.c (read_var_value): Change basereg
support to use LOC_BASEREG rather than SYMBOL_BASEREG_VALID.
- * dwarfread: Use LOC_BASEREG where appropriate.
+ * dwarfread.c: Use LOC_BASEREG where appropriate.
* Various: Support LOC_BASEREG and LOC_BASEREG_ARG.
* coffread.c (init_lineno, init_stringtab): Don't check whether
case LOC_REGPARM:
case LOC_LOCAL:
case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
if (innermost_block == 0 ||
contained_in (block_found,
innermost_block))
case LOC_REGPARM:
case LOC_LOCAL:
case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
if (innermost_block == NULL
|| contained_in (block_found, innermost_block))
{
/*
-FIXME: Figure out how to get the frame pointer register number in the
-execution environment of the target. Remove R_FP kludge
-
FIXME: Do we need to generate dependencies in partial symtabs?
(Perhaps we don't need to).
"DIE @ 0x%x \"%s\", array not row major; not handled correctly", 0, 0
};
-#ifndef R_FP /* FIXME */
-#define R_FP 14 /* Kludge to get frame pointer register number */
-#endif
-
typedef unsigned int DIE_REF; /* Reference to a DIE */
#ifndef GCC_PRODUCER
static int dbroff; /* Relative offset from start of .debug section */
static char *lnbase; /* Base pointer to line section */
static int isreg; /* Kludge to identify register variables */
-static int offreg; /* Kludge to identify basereg references */
+/* Kludge to identify basereg references. Nonzero if we have an offset
+ relative to a basereg. */
+static int offreg;
+/* Which base register is it relative to? */
+static int basereg;
/* This value is added to each symbol value. FIXME: Generalize to
the section_offsets structure used by dbxread (once this is done,
break;
case OP_BASEREG:
/* push value of register (number) */
- /* Actually, we compute the value as if register has 0 */
+ /* Actually, we compute the value as if register has 0, so the
+ value ends up being the offset from that register. */
offreg = 1;
- regno = target_to_host (loc, loc_value_size, GET_UNSIGNED,
- current_objfile);
+ basereg = target_to_host (loc, loc_value_size, GET_UNSIGNED,
+ current_objfile);
loc += loc_value_size;
- if (regno == R_FP)
- {
- stack[++stacki] = 0;
- }
- else
- {
- stack[++stacki] = 0;
-
- complain (&basereg_not_handled, DIE_ID, DIE_NAME, regno);
- }
+ stack[++stacki] = 0;
break;
case OP_ADDR:
/* push address (relocated address) */
}
else if (offreg)
{
- SYMBOL_CLASS (sym) = LOC_LOCAL;
+ SYMBOL_CLASS (sym) = LOC_BASEREG;
+ SYMBOL_BASEREG (sym) = basereg;
}
else
{
{
SYMBOL_CLASS (sym) = LOC_REGPARM;
}
+ else if (offreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
+ SYMBOL_BASEREG (sym) = basereg;
+ }
else
{
SYMBOL_CLASS (sym) = LOC_ARG;
case LOC_REF_ARG:
case LOC_REGPARM:
case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
if (innermost_block == 0 ||
contained_in (block_found,
innermost_block))
case LOC_REGPARM:
case LOC_LOCAL:
case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
case LOC_CONST:
case LOC_CONST_BYTES:
return NAME;
printf ("an argument in register %s", reg_names[val]);
break;
- case LOC_REGPARM_ADDR:
- printf ("address of an argument in register %s", reg_names[val]);
- break;
-
+ case LOC_REGPARM_ADDR:
+ printf ("address of an argument in register %s", reg_names[val]);
+ break;
+
case LOC_ARG:
- if (SYMBOL_BASEREG_VALID (sym))
- {
- printf ("an argument at offset %ld from register %s",
- val, reg_names[basereg]);
- }
- else
- {
- printf ("an argument at offset %ld", val);
- }
+ printf ("an argument at offset %ld", val);
break;
case LOC_LOCAL_ARG:
- if (SYMBOL_BASEREG_VALID (sym))
- {
- printf ("an argument at offset %ld from register %s",
- val, reg_names[basereg]);
- }
- else
- {
- printf ("an argument at frame offset %ld", val);
- }
+ printf ("an argument at frame offset %ld", val);
break;
case LOC_LOCAL:
- if (SYMBOL_BASEREG_VALID (sym))
- {
- printf ("a local variable at offset %ld from register %s",
- val, reg_names[basereg]);
- }
- else
- {
- printf ("a local variable at frame offset %ld", val);
- }
+ printf ("a local variable at frame offset %ld", val);
break;
case LOC_REF_ARG:
printf ("a reference argument at offset %ld", val);
break;
+ case LOC_BASEREG:
+ printf ("a variable at offset %ld from register %s",
+ val, reg_names[basereg]);
+ break;
+
+ case LOC_BASEREG_ARG:
+ printf ("an argument at offset %ld from register %s",
+ val, reg_names[basereg]);
+ break;
+
case LOC_TYPEDEF:
printf ("a typedef");
break;
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
break;
/* Other types of symbols we just skip over. */
SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
SYMBOL_CLASS (sym) != LOC_REF_ARG &&
SYMBOL_CLASS (sym) != LOC_REGPARM &&
- SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR)
+ SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
+ SYMBOL_CLASS (sym) != LOC_BASEREG_ARG)
{
break;
}
LOC_LOCAL_ARG,
+ /* Value is at SYMBOL_VALUE offset from the current value of
+ register number SYMBOL_BASEREG. This exists mainly for the same
+ things that LOC_LOCAL and LOC_ARG do; but we need to do this
+ instead because on 88k DWARF gives us the offset from the
+ frame/stack pointer, rather than the offset from the "canonical
+ frame address" used by COFF, stabs, etc., and we don't know how
+ to convert between these until we start examining prologues.
+
+ Note that LOC_BASEREG is much less general than a DWARF expression. */
+
+ LOC_BASEREG,
+
+ /* Same as LOC_BASEREG but it is an argument. */
+
+ LOC_BASEREG_ARG,
+
/* The variable does not actually exist in the program.
The value is ignored. */
union
{
- /* for OP_BASEREG in DWARF location specs */
- struct
- {
- short regno_valid; /* 0 == regno invalid; !0 == regno valid */
- short regno; /* base register number {0, 1, 2, ...} */
- } basereg;
+ /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */
+ short basereg;
}
aux_value;
#define SYMBOL_CLASS(symbol) (symbol)->class
#define SYMBOL_TYPE(symbol) (symbol)->type
#define SYMBOL_LINE(symbol) (symbol)->line
-#define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg.regno
-
-/* If we want to do baseregs using this approach we should have a
- LOC_BASEREG (and LOC_BASEREG_ARG) rather than changing the meaning
- of LOC_LOCAL, LOC_ARG, etc. based on SYMBOL_BASEREG_VALID. But
- this approach provides just a small fraction of the expressiveness
- of a DWARF location, so it does less than we might want. On the
- other hand, it may do more than we need; FRAME_LOCALS_ADDRESS,
- LOC_REGPARM_ADDR, and similar things seem to handle most of the
- cases which actually come up. */
-
-#if 0
-/* This currently fails because some symbols are not being initialized
- to zero on allocation, and no code is currently setting this value. */
-#define SYMBOL_BASEREG_VALID(symbol) (symbol)->aux_value.basereg.regno_valid
-#else
-#define SYMBOL_BASEREG_VALID(symbol) 0
-#endif
-
+#define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg
\f
/* A partial_symbol records the name, namespace, and address class of
symbols whose types we have not parsed yet. For functions, it also