david@CSVAX.CALTECH.EDU (David Hull) (03/16/89)
In the process of porting gdb 3.1 to the Intergraph CLIPPER, I found
the following bug in the function print_frame_args() in printcmd.c:
The CLIPPER C compiler (written by Green Hills) tries to pass the
first two arguments to a function in registers. If the declared
type of the argument is narrower than the type it was passed as,
the argument is narrowed by copying it to a local variable, which
is below the frame pointer on the stack. Thus its symbol value is
negative. print_frame_args() will not print arguments with
negative symbol values. Also, the function parameters are not
necessarily ordered by symbol value, as print_frame_args()
assumes. It turns out that, on the CLIPPER at least, the symbols
for the arguments are always in the correct order in the symbol
table (I think this is true for all COFF-format files). My
solution was to have a special version of print_frame_args() for
the CLIPPER. Since I think that it will work for all COFF
machines, the new code is enabled with COFF_FORMAT. If I'm wrong,
please let me know.
In a related problem, print_frame_nameless_args() didn't always
print a leading comma when it should. I added a new argument
to tell it whether it needs to.
-David
---------------------------------------
David Hull TRW Inc. Redondo Beach, CA
...!{uunet,cit-vax,trwrb}!wiley!david
david%wiley.uucp@csvax.caltech.edu
*** orig/printcmd.c Thu Feb 16 15:23:26 1989
--- printcmd.c Tue Mar 14 14:18:17 1989
***************
*** 1159,1164 ****
--- 1159,1224 ----
static void print_frame_nameless_args ();
+ #ifdef COFF_FORMAT
+
+ void
+ print_frame_args (func, fi, num, stream)
+ struct symbol *func;
+ struct frame_info *fi;
+ int num;
+ FILE *stream;
+ {
+ struct block *b;
+ int nsyms = 0;
+ int first = 1;
+ register int i;
+ register int last_offset = FRAME_ARGS_SKIP;
+ register struct symbol *sym;
+ register value val;
+ register CORE_ADDR addr = FRAME_ARGS_ADDRESS (fi);
+
+ if (func)
+ {
+ b = SYMBOL_BLOCK_VALUE (func);
+ nsyms = BLOCK_NSYMS (b);
+ }
+
+ for (i = 0; i < nsyms; i++)
+ {
+ QUIT;
+ sym = BLOCK_SYM (b, i);
+ if ((SYMBOL_CLASS (sym) != LOC_ARG) &&
+ (SYMBOL_CLASS (sym) != LOC_REGPARM))
+ continue;
+
+ /* Print the next arg. */
+ if (SYMBOL_CLASS (sym) == LOC_REGPARM)
+ val = value_from_register (SYMBOL_TYPE (sym),
+ SYMBOL_VALUE (sym),
+ FRAME_INFO_ID (fi));
+ else
+ val = value_at (SYMBOL_TYPE (sym), addr + SYMBOL_VALUE (sym));
+
+ if (! first)
+ fprintf (stream, ", ");
+ fprintf (stream, "%s=", SYMBOL_NAME (sym));
+ value_print (val, stream, 0);
+ first = 0;
+ if ((SYMBOL_CLASS (sym) == LOC_ARG) && (SYMBOL_VALUE (sym) >= 0))
+ last_offset = SYMBOL_VALUE (sym) + TYPE_LENGTH (SYMBOL_TYPE (sym));
+
+ /* Round up address of next arg to multiple of size of int. */
+ last_offset
+ = ((last_offset + sizeof (int) - 1) / sizeof (int)) * sizeof (int);
+ }
+ if (num >= 0 && num * sizeof (int) + FRAME_ARGS_SKIP > last_offset)
+ print_frame_nameless_args (addr, last_offset,
+ num * sizeof (int) + FRAME_ARGS_SKIP,
+ first, stream);
+ }
+
+ #else /* not COFF_FORMAT */
+
void
print_frame_args (func, fi, num, stream)
struct symbol *func;
***************
*** 1216,1222 ****
&& last_offset != (SYMBOL_VALUE (sym) / sizeof (int)) * sizeof (int))
{
print_frame_nameless_args (addr, last_offset, SYMBOL_VALUE (sym),
! stream);
first = 0;
}
/* Print the next arg. */
--- 1276,1282 ----
&& last_offset != (SYMBOL_VALUE (sym) / sizeof (int)) * sizeof (int))
{
print_frame_nameless_args (addr, last_offset, SYMBOL_VALUE (sym),
! first, stream);
first = 0;
}
/* Print the next arg. */
***************
*** 1235,1244 ****
if (SYMBOL_CLASS (sym) == LOC_ARG)
last_offset = SYMBOL_VALUE (sym) + TYPE_LENGTH (SYMBOL_TYPE (sym));
else
! {
! last_regparm = SYMBOL_VALUE (sym) + 1;
! last_offset += TYPE_LENGTH (SYMBOL_TYPE (sym));
! }
/* Round up address of next arg to multiple of size of int. */
last_offset
--- 1295,1301 ----
if (SYMBOL_CLASS (sym) == LOC_ARG)
last_offset = SYMBOL_VALUE (sym) + TYPE_LENGTH (SYMBOL_TYPE (sym));
else
! last_regparm = SYMBOL_VALUE (sym) + 1;
/* Round up address of next arg to multiple of size of int. */
last_offset
***************
*** 1247,1267 ****
}
if (num >= 0 && num * sizeof (int) + FRAME_ARGS_SKIP > last_offset)
print_frame_nameless_args (addr, last_offset,
! num * sizeof (int) + FRAME_ARGS_SKIP, stream);
}
static void
! print_frame_nameless_args (argsaddr, start, end, stream)
CORE_ADDR argsaddr;
int start;
int end;
FILE *stream;
{
while (start < end)
{
QUIT;
! if (start != FRAME_ARGS_SKIP)
fprintf (stream, ", ");
fprintf (stream, "%d",
read_memory_integer (argsaddr + start, sizeof (int)));
start += sizeof (int);
--- 1304,1329 ----
}
if (num >= 0 && num * sizeof (int) + FRAME_ARGS_SKIP > last_offset)
print_frame_nameless_args (addr, last_offset,
! num * sizeof (int) + FRAME_ARGS_SKIP,
! first, stream);
}
+ #endif /* not COFF_FORMAT */
+
static void
! print_frame_nameless_args (argsaddr, start, end, first, stream)
CORE_ADDR argsaddr;
int start;
int end;
+ int first;
FILE *stream;
{
while (start < end)
{
QUIT;
! if (!first)
fprintf (stream, ", ");
+ first = 0;
fprintf (stream, "%d",
read_memory_integer (argsaddr + start, sizeof (int)));
start += sizeof (int);