* buildsym.c (finish_block): Treat LOC_BASEREG_ARG and

LOC_LOCAL_ARG as arguments so that GDB will know about function
	args declared this way.  Mostly affects dwarf.
	* dwarfread.c (decode_die_type):  Change default type from int to
	void.  This allows GDB to recognize void functions.
	* (new_symbol):  If AT_PROTOTYPED is present, set a flag in the
	type structure.
	* findvar.c (extract_floating store_floating):  Clean up comments
	to reflect reality.
	* gdbtypes.h:  Add TYPE_FLAG_PROTOTYPED so that we can tell if a
	function has a prototype.  Currently, only dwarf supports this.
	* utils.c (floatformat_from_doublest):  Fix logic error with
	converting from double to float.  (It wasn't shifting mant_long if
	it had a hidden bit.)

	* v850-tdep.c:  Add support for function calling.  Fix some
	problems with debugging code w/o debug symbols.
	* config/v850/tm-v850.h:  Ditto.
This commit is contained in:
Stu Grossman
1996-10-15 23:44:13 +00:00
parent 254ef34062
commit ac9548059b
6 changed files with 247 additions and 34 deletions

View File

@ -1,3 +1,25 @@
Tue Oct 15 16:30:07 1996 Stu Grossman (grossman@critters.cygnus.com)
* buildsym.c (finish_block): Treat LOC_BASEREG_ARG and
LOC_LOCAL_ARG as arguments so that GDB will know about function
args declared this way. Mostly affects dwarf.
* dwarfread.c (decode_die_type): Change default type from int to
void. This allows GDB to recognize void functions.
* (new_symbol): If AT_PROTOTYPED is present, set a flag in the
type structure.
* findvar.c (extract_floating store_floating): Clean up comments
to reflect reality.
* gdbtypes.h: Add TYPE_FLAG_PROTOTYPED so that we can tell if a
function has a prototype. Currently, only dwarf supports this.
* utils.c (floatformat_from_doublest): Fix logic error with
converting from double to float. (It wasn't shifting mant_long if
it had a hidden bit.)
start-sanitize-v850
* v850-tdep.c: Add support for function calling. Fix some
problems with debugging code w/o debug symbols.
* config/v850/tm-v850.h: Ditto.
end-sanitize-v850
Tue Oct 15 18:19:42 1996 Ian Lance Taylor <ian@cygnus.com> Tue Oct 15 18:19:42 1996 Ian Lance Taylor <ian@cygnus.com>
* utils.c: Always ensure that size_t is defined. Check * utils.c: Always ensure that size_t is defined. Check
@ -16,8 +38,8 @@ Sun Oct 13 11:38:25 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
Fri Oct 11 15:43:54 1996 Stu Grossman (grossman@critters.cygnus.com) Fri Oct 11 15:43:54 1996 Stu Grossman (grossman@critters.cygnus.com)
* frame.h: Move definition of struct frame_saved_args to before * frame.h: Move definition of struct frame_saved_regs to before
struct frame to make it possible to use frame_saved_args in struct frame to make it possible to use frame_saved_regs in
EXTRA_FRAME_INFO macro. EXTRA_FRAME_INFO macro.
start-sanitize-v850 start-sanitize-v850

View File

@ -268,6 +268,8 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
case LOC_REF_ARG: case LOC_REF_ARG:
case LOC_REGPARM: case LOC_REGPARM:
case LOC_REGPARM_ADDR: case LOC_REGPARM_ADDR:
case LOC_BASEREG_ARG:
case LOC_LOCAL_ARG:
nparams++; nparams++;
break; break;
case LOC_UNDEF: case LOC_UNDEF:
@ -279,9 +281,7 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
case LOC_LABEL: case LOC_LABEL:
case LOC_BLOCK: case LOC_BLOCK:
case LOC_CONST_BYTES: case LOC_CONST_BYTES:
case LOC_LOCAL_ARG:
case LOC_BASEREG: case LOC_BASEREG:
case LOC_BASEREG_ARG:
case LOC_UNRESOLVED: case LOC_UNRESOLVED:
case LOC_OPTIMIZED_OUT: case LOC_OPTIMIZED_OUT:
default: default:
@ -303,6 +303,8 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
case LOC_REF_ARG: case LOC_REF_ARG:
case LOC_REGPARM: case LOC_REGPARM:
case LOC_REGPARM_ADDR: case LOC_REGPARM_ADDR:
case LOC_BASEREG_ARG:
case LOC_LOCAL_ARG:
TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym); TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
iparams++; iparams++;
break; break;
@ -315,9 +317,7 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
case LOC_LABEL: case LOC_LABEL:
case LOC_BLOCK: case LOC_BLOCK:
case LOC_CONST_BYTES: case LOC_CONST_BYTES:
case LOC_LOCAL_ARG:
case LOC_BASEREG: case LOC_BASEREG:
case LOC_BASEREG_ARG:
case LOC_UNRESOLVED: case LOC_UNRESOLVED:
case LOC_OPTIMIZED_OUT: case LOC_OPTIMIZED_OUT:
default: default:

View File

@ -68,6 +68,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
struct frame_info; struct frame_info;
struct frame_saved_regs; struct frame_saved_regs;
struct type; struct type;
struct value;
#endif #endif
#define EXTRA_FRAME_INFO struct frame_saved_regs fsr; #define EXTRA_FRAME_INFO struct frame_saved_regs fsr;
@ -106,3 +107,35 @@ extern CORE_ADDR v850_skip_prologue PARAMS ((CORE_ADDR pc));
extern struct frame_info *v850_pop_frame PARAMS ((struct frame_info *frame)); extern struct frame_info *v850_pop_frame PARAMS ((struct frame_info *frame));
#define POP_FRAME v850_pop_frame (get_current_frame ()) #define POP_FRAME v850_pop_frame (get_current_frame ())
#define CALL_DUMMY { 0 }
#define CALL_DUMMY_START_OFFSET (0)
#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
extern void v850_push_dummy_frame PARAMS ((void));
#define PUSH_DUMMY_FRAME v850_push_dummy_frame ()
#define FIX_CALL_DUMMY(DUMMY1, START_SP, FUNADDR, NARGS, ARGS, VALUE_TYPE, USING_GCC)
#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
#define STACK_ALIGN(x) ((x + 3) & ~3)
extern CORE_ADDR
v850_push_arguments PARAMS ((int nargs, struct value **args, CORE_ADDR sp,
unsigned char struct_return,
CORE_ADDR struct_addr));
#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
(SP) = v850_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)
#define STORE_STRUCT_RETURN(STRUCT_ADDR, SP)
#define CALL_DUMMY_ADDRESS() (entry_point_address ())
extern int v850_pc_in_call_dummy PARAMS ((CORE_ADDR pc));
#define PC_IN_CALL_DUMMY(PC, SP, FP) v850_pc_in_call_dummy (PC)
#define USE_STRUCT_CONVENTION(GCC_P, TYPE) \
(TYPE_NFIELDS (TYPE) > 1 || TYPE_LENGTH (TYPE) > 4)

View File

@ -964,7 +964,7 @@ decode_die_type (dip)
} }
else else
{ {
type = dwarf_fundamental_type (current_objfile, FT_INTEGER); type = dwarf_fundamental_type (current_objfile, FT_VOID);
} }
return (type); return (type);
} }
@ -2957,6 +2957,8 @@ new_symbol (dip, objfile)
case TAG_subroutine: case TAG_subroutine:
SYMBOL_VALUE_ADDRESS (sym) = dip -> at_low_pc; SYMBOL_VALUE_ADDRESS (sym) = dip -> at_low_pc;
SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym)); SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
if (dip -> at_prototyped)
TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
SYMBOL_CLASS (sym) = LOC_BLOCK; SYMBOL_CLASS (sym) = LOC_BLOCK;
if (dip -> die_tag == TAG_global_subroutine) if (dip -> die_tag == TAG_global_subroutine)
{ {

View File

@ -154,6 +154,12 @@ enum type_code
#define TYPE_FLAG_TARGET_STUB (1 << 3) #define TYPE_FLAG_TARGET_STUB (1 << 3)
/* This is a function type which appears to have a prototype. We need this
for function calls in order to tell us if it's necessary to coerce the args,
or to just do the standard conversions. */
#define TYPE_FLAG_PROTOTYPED (1 << 4)
struct type struct type
{ {

View File

@ -1,6 +1,5 @@
/* Target-dependent code for the NEC V850 for GDB, the GNU debugger. /* Target-dependent code for the NEC V850 for GDB, the GNU debugger.
Copyright 1986, 1996 Copyright 1996, Free Software Foundation, Inc.
Free Software Foundation, Inc.
This file is part of GDB. This file is part of GDB.
@ -18,8 +17,6 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ??? Support for calling functions from gdb in sparc64 is unfinished. */
#include "defs.h" #include "defs.h"
#include "frame.h" #include "frame.h"
#include "inferior.h" #include "inferior.h"
@ -28,9 +25,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "value.h" #include "value.h"
#include "bfd.h" #include "bfd.h"
#include "gdb_string.h" #include "gdb_string.h"
#include "gdbcore.h" #include "gdbcore.h"
struct dummy_frame
{
struct dummy_frame *next;
CORE_ADDR fp;
CORE_ADDR sp;
CORE_ADDR rp;
CORE_ADDR pc;
};
static struct dummy_frame *dummy_frame_stack = NULL;
/* This function actually figures out the frame address for a given pc and /* This function actually figures out the frame address for a given pc and
sp. This is tricky on the v850 because we only use an explicit frame sp. This is tricky on the v850 because we only use an explicit frame
@ -49,7 +56,7 @@ v850_init_extra_frame_info (fi)
int framereg; int framereg;
if (fi->next) if (fi->next)
fi->pc = v850_find_callers_reg (fi->next, RP_REGNUM); fi->pc = FRAME_SAVED_PC (fi->next);
/* First, figure out the bounds of the prologue so that we can limit the /* First, figure out the bounds of the prologue so that we can limit the
search to something reasonable. */ search to something reasonable. */
@ -58,6 +65,9 @@ v850_init_extra_frame_info (fi)
{ {
sal = find_pc_line (func_addr, 0); sal = find_pc_line (func_addr, 0);
if (sal.line == 0)
prologue_end = fi->pc;
else
prologue_end = sal.end; prologue_end = sal.end;
} }
else else
@ -108,21 +118,10 @@ v850_init_extra_frame_info (fi)
} }
} }
#if 0 if (PC_IN_CALL_DUMMY (fi->pc, NULL, NULL))
if (!fi->next) fi->frame = dummy_frame_stack->sp;
fi->frame = read_register (framereg); else if (!fi->next && framereg == SP_REGNUM)
else
if (framereg == SP_REGNUM)
fi->frame = fi->next->frame;
else
fi->frame = v850_find_callers_reg (fi, framereg);
if (framereg == SP_REGNUM)
fi->frame -= frameoffset;
#else
if (!fi->next && framereg == SP_REGNUM)
fi->frame = read_register (framereg) - frameoffset; fi->frame = read_register (framereg) - frameoffset;
#endif
for (reg = 0; reg < NUM_REGS; reg++) for (reg = 0; reg < NUM_REGS; reg++)
if (fi->fsr.regs[reg] != 0) if (fi->fsr.regs[reg] != 0)
@ -137,6 +136,24 @@ v850_find_callers_reg (fi, regnum)
struct frame_info *fi; struct frame_info *fi;
int regnum; int regnum;
{ {
/* XXX - Won't work if multiple dummy frames are active */
if (PC_IN_CALL_DUMMY (fi->pc, NULL, NULL))
switch (regnum)
{
case SP_REGNUM:
return dummy_frame_stack->sp;
break;
case FP_REGNUM:
return dummy_frame_stack->fp;
break;
case RP_REGNUM:
return dummy_frame_stack->pc;
break;
case PC_REGNUM:
return dummy_frame_stack->pc;
break;
}
for (; fi; fi = fi->next) for (; fi; fi = fi->next)
if (fi->fsr.regs[regnum] != 0) if (fi->fsr.regs[regnum] != 0)
return read_memory_integer (fi->fsr.regs[regnum], 4); return read_memory_integer (fi->fsr.regs[regnum], 4);
@ -149,13 +166,15 @@ v850_frame_chain (fi)
struct frame_info *fi; struct frame_info *fi;
{ {
CORE_ADDR callers_pc, callers_sp; CORE_ADDR callers_pc, callers_sp;
struct frame_info temp_fi;
CORE_ADDR func_addr, prologue_end, current_pc; CORE_ADDR func_addr, prologue_end, current_pc;
int frameoffset; int frameoffset;
/* First, find out who called us */ /* First, find out who called us */
callers_pc = v850_find_callers_reg (fi, RP_REGNUM); callers_pc = FRAME_SAVED_PC (fi);
if (PC_IN_CALL_DUMMY (callers_pc, NULL, NULL))
return dummy_frame_stack->sp; /* XXX Won't work if multiple dummy frames on stack! */
/* Next, figure out where his prologue is. */ /* Next, figure out where his prologue is. */
@ -163,8 +182,15 @@ v850_frame_chain (fi)
{ {
struct symtab_and_line sal; struct symtab_and_line sal;
/* Stop when the caller is the entry point function */
if (func_addr == entry_point_address ())
return 0;
sal = find_pc_line (func_addr, 0); sal = find_pc_line (func_addr, 0);
if (sal.line == 0)
prologue_end = callers_pc;
else
prologue_end = sal.end; prologue_end = sal.end;
} }
else else
@ -217,11 +243,12 @@ v850_skip_prologue (pc)
sal = find_pc_line (func_addr, 0); sal = find_pc_line (func_addr, 0);
if (sal.end < func_end) if (sal.line != 0 && sal.end < func_end)
return sal.end; return sal.end;
else else
/* The line after the prologue is after the end of the function. In /* Either there's no line info, or the line after the prologue is after
this case, there probably isn't a prologue. */ the end of the function. In this case, there probably isn't a
prologue. */
return pc; return pc;
} }
@ -229,12 +256,60 @@ v850_skip_prologue (pc)
return pc; return pc;
} }
/* All we do here is record SP and FP on the call dummy stack */
void
v850_push_dummy_frame ()
{
struct dummy_frame *dummy_frame;
dummy_frame = xmalloc (sizeof (struct dummy_frame));
dummy_frame->fp = read_register (FP_REGNUM);
dummy_frame->sp = read_register (SP_REGNUM);
dummy_frame->rp = read_register (RP_REGNUM);
dummy_frame->pc = read_register (PC_REGNUM);
dummy_frame->next = dummy_frame_stack;
dummy_frame_stack = dummy_frame;
}
int
v850_pc_in_call_dummy (pc)
CORE_ADDR pc;
{
return dummy_frame_stack
&& pc >= CALL_DUMMY_ADDRESS ()
&& pc <= CALL_DUMMY_ADDRESS () + DECR_PC_AFTER_BREAK;
}
struct frame_info * struct frame_info *
v850_pop_frame (frame) v850_pop_frame (frame)
struct frame_info *frame; struct frame_info *frame;
{ {
int regnum; int regnum;
if (PC_IN_CALL_DUMMY (frame->pc, NULL, NULL))
{
struct dummy_frame *dummy_frame;
dummy_frame = dummy_frame_stack;
if (!dummy_frame)
error ("Can't pop dummy frame!");
dummy_frame_stack = dummy_frame->next;
write_register (FP_REGNUM, dummy_frame->fp);
write_register (SP_REGNUM, dummy_frame->sp);
write_register (RP_REGNUM, dummy_frame->rp);
write_register (PC_REGNUM, dummy_frame->pc);
free (dummy_frame);
flush_cached_frames ();
return NULL;
}
write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
for (regnum = 0; regnum < NUM_REGS; regnum++) for (regnum = 0; regnum < NUM_REGS; regnum++)
@ -246,6 +321,81 @@ v850_pop_frame (frame)
return NULL; return NULL;
} }
/* Put arguments in the right places, and setup return address register (RP) to
point at a convenient place to put a breakpoint. First four args go in
R6->R9, subsequent args go into sp + 16 -> sp + ... Structs are passed by
reference. 64 bit quantities (doubles and long longs) may be split between
the regs and the stack. When calling a function that returns a struct, a
pointer to the struct is passed in as a secret first argument (always in R6).
By the time we get here, stack space has been allocated for the args, but
not for the struct return pointer. */
CORE_ADDR
v850_push_arguments (nargs, args, sp, struct_return, struct_addr)
int nargs;
value_ptr *args;
CORE_ADDR sp;
unsigned char struct_return;
CORE_ADDR struct_addr;
{
int argreg;
int argnum;
argreg = 6;
if (struct_return)
{
write_register (argreg++, struct_addr);
sp -= 4;
}
for (argnum = 0; argnum < nargs; argnum++)
{
int len;
char *val;
char valbuf[4];
if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
&& TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
{
store_address (valbuf, 4, VALUE_ADDRESS (*args));
len = 4;
val = valbuf;
}
else
{
len = TYPE_LENGTH (VALUE_TYPE (*args));
val = (char *)VALUE_CONTENTS (*args);
}
while (len > 0)
if (argreg <= 9)
{
CORE_ADDR regval;
regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
write_register (argreg, regval);
len -= REGISTER_RAW_SIZE (argreg);
val += REGISTER_RAW_SIZE (argreg);
argreg++;
}
else
{
write_memory (sp + argnum * 4, val, 4);
len -= 4;
val += 4;
}
args++;
}
write_register (RP_REGNUM, entry_point_address ());
return sp;
}
void void
_initialize_sparc_tdep () _initialize_sparc_tdep ()