This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFC] Mips, N32, cc, gcc, and gdb (longish)
- From: Michael Snyder <msnyder at redhat dot com>
- To: Daniel Jacobowitz <drow at mvista dot com>
- Cc: gdb-patches at sources dot redhat dot com, cagney at redhat dot com, kevinb at redhat dot com, echristo at redhat dot com
- Date: Thu, 01 Aug 2002 19:24:16 -0700
- Subject: Re: [RFC] Mips, N32, cc, gcc, and gdb (longish)
- Organization: Red Hat, Inc.
- References: <3D49DCF8.AB4C6718@redhat.com> <20020802015734.GA28572@nevyn.them.org>
Daniel Jacobowitz wrote:
>
> On Thu, Aug 01, 2002 at 06:14:32PM -0700, Michael Snyder wrote:
> > OK, I think I've made this as concise as practical. ;-)
> >
> > In case the difference between Irix cc and gcc does not get
> > fixed (and I mean specifically the difference concerning
> > alignment of small struct arguments), I'd like to discuss
> > "fixing" gdb so that it will work correctly with both.
> >
> > I've found a testcase for this problem in call-ar-st.exp:
> >
> > (gdb) print print_long_arg_list (a, b, c, d, e, f, *struct1,
> > *struct2, *struct3, *struct4, *flags, *flags_combo,
> > *three_char, *five_char, *int_char_combo,
> > *d1, *d2, *d3, *f1, *f2, *f3)
> >
> > This fails (or doesn't) depending on whether a small struct
> > is left-justified or right-justified when it is pushed onto
> > the stack (ie, when it is the 5th or higher argument).
> >
> > The code in mips_push_arguments that controls this is:
> >
> > if (MIPS_STACK_ARGSIZE == 8 &&
> > (typecode == TYPE_CODE_INT ||
> > typecode == TYPE_CODE_PTR ||
> > typecode == TYPE_CODE_FLT) && len <= 4)
> > longword_offset = MIPS_STACK_ARGSIZE - len;
> > else if ((typecode == TYPE_CODE_STRUCT ||
> > typecode == TYPE_CODE_UNION) &&
> > TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE)
> > longword_offset = MIPS_STACK_ARGSIZE - len;
> > }
> >
> > As it is written, it "works" with gcc but fails with cc.
> >
> > Kevin proposed this change to me (I don't remember if
> > he has submitted it yet):
> >
> > ***
> > typecode == TYPE_CODE_UNION) &&
> > ! TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE)
> > longword_offset = MIPS_STACK_ARGSIZE - len;
> > ---
> > typecode == TYPE_CODE_UNION) &&
> > ! TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE
> > ! && tdep->mips_abi != MIPS_ABI_N32)
> > longword_offset = MIPS_STACK_ARGSIZE - len;
> > ***
> >
> > With this change, it "works" with cc, but fails with gcc.
> >
> > I want to discuss the following change, which should
> > make it "work" with both cc and gcc (given the current
> > behavior of both):
> >
> > ***
> > typecode == TYPE_CODE_UNION) &&
> > ! TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE)
> > longword_offset = MIPS_STACK_ARGSIZE - len;
> > ---
> > typecode == TYPE_CODE_UNION) &&
> > ! TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE
> > ! && (gcc_p ||tdep->mips_abi != MIPS_ABI_N32))
> > longword_offset = MIPS_STACK_ARGSIZE - len;
> > ***
> >
> >
> > This of course makes gdb's behavior dependent on which
> > compiler it detects.
> >
> > There is one problem: there is no variable "gcc_p" within
> > the scope of mips_push_arguments, because PUSH_ARGUMENTS
> > does not pass it. So that would need to be solved,
> > possibly by modifying the definition of PUSH_ARGUMENTS.
> >
> > Comments?
>
> Comment - you're on a slippery slope. I know of at least one other
> variation in this area; for structures of less than a word SGI CC
> shifts them in register only for big endian targets, and not for little
> endian (on the old versions of CC which support little endian). There
> comes a point where we just need to get GCC fixed, and I think this is
> it.
Right -- but this thread concerns what to do if that DOESN'T happen.
In answer to your comment, I believe the code currently in GDB
already handles the case you describe, both for CC and for GCC.
So what I'm discussing here will bring stack-passing into line
with register-passing.
However, you may be right that I need to check for endian-ness
in my proposed change. I haven't tested that.
Michael