This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Fwd: error in variable dereferencing
Thibaud GUERIN writes:
> On 4/21/06, Andrew Haley <aph@gcc.gnu.org> wrote:
> > Thibaud GUERIN writes:
> > > On 4/20/06, Andrew Haley <aph@redhat.com> wrote:
> > > > Thibaud GUERIN writes:
> > > > >
> > > > >
> > > > > Not clear in the first message, (and maybe not in this one too..), sorry
> > > > >
> > > > >
> > > > > This asm inline was something like a "test/patch code".
> > > > >
> > > > > I try to have a simple :
> > > > >
> > > > > char **ap = (char **)(&fmt);
> > > >
> > > > > so i try by my self... to do :
> > > > >
> > > > > ap = &fmt;
> > > > > *ap = fmt;
> > > > >
> > > > > in asm inline.... (dirty i know...)
> > > > >
> > > > > problem is :
> > > > > With this asm code in the binary *s is equal to fmt
> > > > > Without this asm code in the binary *s isn't equal to fmt
> > > > >
> > > > >
> > > > > All the 's' variable stuffs are from my debug...
> > > > > Again :
> > > > > My only aim is to have an 'ap = &fmt' valid (->ap = &fmt AND *ap = fmt)
> > > >
> > > > So why not do the obvious
> > > >
> > > > const char **ap = &fmt ;
> > > >
> > > > ?
> > >
> > > because i need to do some :
> > > ap++;
> > > to get the next args in stack, as my end aim is to do re-write a printf...
> >
> > So why not use va_list? That's what va_list is for.
> >
> > > > > The resulting asm was here to help you to understand wath's wrong ....
> > > > > I'm looking for some days now without answer...
> > > >
> > > > You're still not explaining yourself. You have a const char* arg that
> > > > you are trying to alter, but instead of doing it the obvious way with
> > > > an assignment, you're taking the address of the arg, casting the
> > > > resulting pointer to a different pointer type, and then overwriting
> > > > the arg through the resulting pointer.
> > > >
> > > > What's the point of all this?
> > >
> > > i'm not trying to alter an (const char*) but to get the args in my
> > > stack by getting some pointers on it, as in all va_args fonctions....
> >
> > Trying to do all this stuff behind the compiler's back is likely to
> > break things. Use va_list.
>
> quote :
> I'm compiling with (to run on my VM):
> -std=gnu99 -Wall -Werror -nostdinc -Wstrict-aliasing=2 -fno-builtin
> -I../include -I../
>
> no-builtin ....
>
> I'm doing that because the va_list wasn't working too... (i come to
> that dirty code by simplifing the code to found the root of the
> problem)
OK, so now I know what you're _really_ trying to do. It took some
work, but we're here now.
> And my final aim is to have a printf without any deps form any parent
> system (no use of standard includes, ....)
Fair enough. va_list and its friends can't be written in C, which is
why gcc provides builtin functions for them. The standard ones look
like this:
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
#define va_copy(d,s) __builtin_va_copy(d,s)
Now, if you know absolutely for sure that your args are pushed onto
the stack in order without any holes, you might be able to get around
this.
void pkludge (char *s, ...) __attribute__((noinline));
void pkludge (char *s, ...)
{
void **p = &s;
printf ("%d\n", *(int *)++p);
printf ("%d\n", *(int *)++p);
}
This isn't legal C, though, and trying to do things like this behind
gcc's back is asking for trouble. The _real_ solution is to find out
why gcc's builtins are not working.
Andrew.