Steven J. Magnani | 2 Dec 06:05 2009

Evil stack behavior when compiling with -O0

I've discovered that when -O0 is used, both microblaze-uclinux-gcc and
microblaze-unknown-uclinux-uclibc-gcc turn this:

  void __attribute__ ((__noreturn__))
  __uClibc_main(int argc, char **argv, char ** envp)
  {
      __uClibc_start_main(argc, argv, envp, NULL, NULL);
  }

into this:

  addik   r1, r1, -28
  swi     r15, r1, 0
  swi     r5, r1, 32      // !
  swi     r6, r1, 36      // !!
  swi     r7, r1, 40      // !!!
  lwi     r5, r1, 32
  lwi     r6, r1, 36
  lwi     r7, r1, 40
  addk    r8, r0, r0
  addk    r9, r0, r0
  brlid   r15, -244       // 74 <__uClibc_start_main>
  or      r0, r0, r0

AFAICT, in this particular case, this ends up destroying the contents of
argv because the stack gets corrupted. Am I missing something?

------------------------------------------------------------------------
 Steven J. Magnani               "I claim this network for MARS!
 www.digidescorp.com              Earthling, return my space modulator!"
(Continue reading)

John Williams | 2 Dec 06:39 2009

Re: Evil stack behavior when compiling with -O0

Hi Steve,

On Wed, Dec 2, 2009 at 3:05 PM, Steven J. Magnani <steve@...> wrote:
> I've discovered that when -O0 is used, both microblaze-uclinux-gcc and
> microblaze-unknown-uclinux-uclibc-gcc turn this:

Where did you find this microblaze-unknown-uclinux-uclibc compiler?

>  void __attribute__ ((__noreturn__))
>  __uClibc_main(int argc, char **argv, char ** envp)
>  {
>      __uClibc_start_main(argc, argv, envp, NULL, NULL);
>  }
>
> into this:
>
>  addik   r1, r1, -28
>  swi     r15, r1, 0
>  swi     r5, r1, 32      // !
>  swi     r6, r1, 36      // !!
>  swi     r7, r1, 40      // !!!

Yeah that doesn't look too good.

What do you get with -O1 and -O2?

Thanks,

John
--

-- 
(Continue reading)

Steve Magnani | 2 Dec 07:18 2009

Re: Evil stack behavior when compiling with -O0

John,

-O1/-O2/-Os are fine. IIRC the args don't get saved to the stack so there is not an issue.

I thought the microblaze-unknown-uclinux-uclibc toolchain came from PetaLogix (one of the 0.40 
releases, or the SVN repository?); I will have to hunt around to see if I can find some 
breadcrumbs.

Steve

-----Original Message-----
From: John Williams <john.williams@...>
To: microblaze-uclinux@...
Date: Wed, 2 Dec 2009 15:39:34 +1000
Subject: Re: [microblaze-uclinux] Evil stack behavior when compiling with -O0

> Hi Steve,
> 
> On Wed, Dec 2, 2009 at 3:05 PM, Steven J. Magnani
> <steve@...> wrote:
> > I've discovered that when -O0 is used, both microblaze-uclinux-gcc
> and
> > microblaze-unknown-uclinux-uclibc-gcc turn this:
> 
> Where did you find this microblaze-unknown-uclinux-uclibc compiler?
> 
> >  void __attribute__ ((__noreturn__))
> >  __uClibc_main(int argc, char **argv, char ** envp)
> >  {
> >      __uClibc_start_main(argc, argv, envp, NULL, NULL);
(Continue reading)

Steven J. Magnani | 2 Dec 18:05 2009

Re: Evil stack behavior when compiling with -O0

> From: John Williams <john.williams@...>
> Date: Wed, 2 Dec 2009 15:39:34 +1000

> > Hi Steve,
> > 
> > On Wed, Dec 2, 2009 at 3:05 PM, Steven J. Magnani
> > <steve@...> wrote:
> > > I've discovered that when -O0 is used, both microblaze-uclinux-gcc
> > and
> > > microblaze-unknown-uclinux-uclibc-gcc turn this:
> > 
> > Where did you find this microblaze-unknown-uclinux-uclibc compiler?

http://www.monstr.eu/toolchain-nommu_gcc412-090529.tar.gz

> > 
> > >  void __attribute__ ((__noreturn__))
> > >  __uClibc_main(int argc, char **argv, char ** envp)
> > >  {
> > >      __uClibc_start_main(argc, argv, envp, NULL, NULL);
> > >  }
> > >
> > > into this:
> > >
> > >  addik   r1, r1, -28
> > >  swi     r15, r1, 0
> > >  swi     r5, r1, 32      // !
> > >  swi     r6, r1, 36      // !!
> > >  swi     r7, r1, 40      // !!!
> > 
(Continue reading)

John Williams | 2 Dec 23:23 2009

Re: Evil stack behavior when compiling with -O0

On Thu, Dec 3, 2009 at 3:05 AM, Steven J. Magnani <steve@...> wrote:
>> From: John Williams <john.williams@...>
>> Date: Wed, 2 Dec 2009 15:39:34 +1000
>
>> > Hi Steve,
>> >
>> > On Wed, Dec 2, 2009 at 3:05 PM, Steven J. Magnani
>> > <steve@...> wrote:
>> > > I've discovered that when -O0 is used, both microblaze-uclinux-gcc
>> > and
>> > > microblaze-unknown-uclinux-uclibc-gcc turn this:
>> >
>> > Where did you find this microblaze-unknown-uclinux-uclibc compiler?
>
> http://www.monstr.eu/toolchain-nommu_gcc412-090529.tar.gz

You'd better ask Michal about it then :)  monstr.eu is his private site

I'm just kidding - if you can reduce the behaviour down to a simple
test case that can be demonstrated without a full uClibc source tree,
we can push it to Xilinx to take a look.  There's been a lot happening
with gcc and binutils the last 6 months, their GCC guy has a gcc 4.5
(ish) tree on the FSF site, and we'll be looking at turning that into
a linux toolchain early next year.  But, there may not be a whole lot
of traction to be had on this older toolchain.

Here's a thought - what happens if you compile your (to be developed)
minimal test case with the vanilla mb-gcc 4.1.1 / 4.1.2 that ships
with Xilinx EDK?

(Continue reading)

Steven J. Magnani | 2 Dec 23:54 2009

Re: Evil stack behavior when compiling with -O0

On Thu, 2009-12-03 at 08:23 +1000, John Williams wrote:
> On Thu, Dec 3, 2009 at 3:05 AM, Steven J. Magnani <steve@...> wrote:
> >> From: John Williams <john.williams@...>
> >> Date: Wed, 2 Dec 2009 15:39:34 +1000
> >
> >> > Hi Steve,
> >> >
> >> > On Wed, Dec 2, 2009 at 3:05 PM, Steven J. Magnani
> >> > <steve@...> wrote:
> >> > > I've discovered that when -O0 is used, both microblaze-uclinux-gcc
> >> > and
> >> > > microblaze-unknown-uclinux-uclibc-gcc turn this:
> >> >
> >> > Where did you find this microblaze-unknown-uclinux-uclibc compiler?
> >
> > http://www.monstr.eu/toolchain-nommu_gcc412-090529.tar.gz
> 
> You'd better ask Michal about it then :)  monstr.eu is his private site
> 
> I'm just kidding - if you can reduce the behaviour down to a simple
> test case that can be demonstrated without a full uClibc source tree,
> we can push it to Xilinx to take a look. 

    void foo(int argc, char**argv)
    {
    }

    int main(int argc, char**argv)
    {
        foo(argc, argv);
(Continue reading)

Steven J. Magnani | 3 Dec 22:19 2009

Re: Evil stack behavior when compiling with -O0

The answer seems to be that the compilers are working the way they're
supposed to; it's uClibc's crt[01].S that are broken. 

The Microblaze ABI, as documented in the datasheet, states:

  "The callee uses the stack area of the caller to store the
   parameters passed to the callee."

So any non-leaf function (function that calls another) must allocate
whatever stack it needs for its own use PLUS enough space for a return
address and parameter registers for any function it calls directly.
Since the max number of parameter registers is 6, each non-leaf function
should reserve a minimum of 28 bytes.

The crt[01].S in uClibc don't reserve any part of the stack before
calling __uClibc_main(); they leave the stack pointer where the kernel
set it. So when __uClibc_main goes to save its parameters, it does so in
a region that's beyond the program stack. 

The solution is to add a "addi r1, r1, -28" to the _start code before
branching to __uClibc_main.

Thanks to Xilinx Tech Support for responding so quickly and
knowledgeably.

------------------------------------------------------------------------
 Steven J. Magnani               "I claim this network for MARS!
 www.digidescorp.com              Earthling, return my space modulator!"

 #include <standard.disclaimer>
(Continue reading)

Vasanth Asokan | 3 Dec 19:49 2009

RE: Evil stack behavior when compiling with -O0

Hi Steven,

> -----Original Message-----
> From: owner-microblaze-uclinux@... [mailto:owner-
> microblaze-uclinux@...] On Behalf Of Steven J.
Magnani
> Sent: Tuesday, December 01, 2009 9:06 PM
> To: microblaze-uclinux@...
> Subject: [microblaze-uclinux] Evil stack behavior when compiling with
-O0
> 
> I've discovered that when -O0 is used, both microblaze-uclinux-gcc and
> microblaze-unknown-uclinux-uclibc-gcc turn this:
> 
>   void __attribute__ ((__noreturn__))
>   __uClibc_main(int argc, char **argv, char ** envp)
>   {
>       __uClibc_start_main(argc, argv, envp, NULL, NULL);
>   }
> 
> into this:
> 
>   addik   r1, r1, -28
>   swi     r15, r1, 0
>   swi     r5, r1, 32      // !
>   swi     r6, r1, 36      // !!
>   swi     r7, r1, 40      // !!!
>   lwi     r5, r1, 32
>   lwi     r6, r1, 36
>   lwi     r7, r1, 40
(Continue reading)


Gmane