* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
@ 1999-11-30 6:00 Jason Kim
1999-11-30 10:58 ` Franz Sirl
0 siblings, 1 reply; 15+ messages in thread
From: Jason Kim @ 1999-11-30 6:00 UTC (permalink / raw)
To: Franz.Sirl-kernel, linuxppc-dev, gcc-patches
Agreed, ssh2 code isn't necessarily the cleanest in the world, but then again
the varargs situation in PPC world is a bit peculiar.
typedef struct A {
char foo;
char *bar;
} B[1], C[1];
typedef C D;
void tst(D d1)
{
D d2;
d1 = d2; // this is legal
// d2 = d1; // this is not
}
declaring arrays of fixed size seems a bit strange for a type which will be used
by user code, since it makes d1 and d2 be different types sometimes. Not to
mention, having struct _va_list_tag AS va_list seem to fix the problems neatly.
Is there a technical reason for keeping va_list as an array of 1 element?
(instead of just a single element??)
-jason.
Franz.Sirl-kernel@lauterbach.com wrote:
> Am Mon, 29 Nov 1999 schrieb Jason Kim:
> >There is a problem with va-ppc.h distributed with recent versions ofgcc (2.95
> >and onwards) as well as the older egcs 1.1 releases.
> >
> >va-ppc.h typedefs va_list as an array of 1 element of struct
> >_va_list_tag but this causes problems when va_lists (or pointers to
> >them!) are passed as arguments to functions:
> >
> >e.g.
> >
> >void foo(va_list va1)
> >{
> >va_list va2;
> >va1 = va2;
> >}
>
> The source is wrong, this code is simply non-portable. Use __va_copy(va1, va2)
> or some memcpy trickery to fix the source.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-11-30 6:00 patch for problem with va-ppc.h included with egcs and gcc-2.95.2 Jason Kim
@ 1999-11-30 10:58 ` Franz Sirl
1999-11-30 18:05 ` Jason Kim
1999-11-30 23:28 ` Jason Kim
0 siblings, 2 replies; 15+ messages in thread
From: Franz Sirl @ 1999-11-30 10:58 UTC (permalink / raw)
To: Jason Kim; +Cc: linuxppc-dev, gcc-patches
At 07:00 30.11.99 , Jason Kim wrote:
>Agreed, ssh2 code isn't necessarily the cleanest in the world, but then again
>the varargs situation in PPC world is a bit peculiar.
>
>
>typedef struct A {
> char foo;
> char *bar;
>} B[1], C[1];
>
>typedef C D;
>
>
>void tst(D d1)
>{
> D d2;
> d1 = d2; // this is legal
> // d2 = d1; // this is not
>}
>
>declaring arrays of fixed size seems a bit strange for a type which will
>be used
>by user code, since it makes d1 and d2 be different types sometimes. Not to
>mention, having struct _va_list_tag AS va_list seem to fix the problems
>neatly.
>
>Is there a technical reason for keeping va_list as an array of 1 element?
>(instead of just a single element??)
1. this behaviour is mandated by the ABI
2. it nicely spots a common programming error
I see nothing peculiar about it :-).
BTW, it would be nice if you could fix your spam filter, my last message
was rejected, even though there was no faked IP in it.
Franz.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-11-30 10:58 ` Franz Sirl
@ 1999-11-30 18:05 ` Jason Kim
1999-11-30 23:28 ` Jason Kim
1 sibling, 0 replies; 15+ messages in thread
From: Jason Kim @ 1999-11-30 18:05 UTC (permalink / raw)
To: Franz Sirl, linuxppc-dev@lists.linuxppc.org,
gcc-patches@gcc.gnu.org
> 1. this behaviour is mandated by the ABI
Hmm. I just checked the SYSVR4 ABI, and indeed it lists va_list as a typedef of
1 element array. Oh well. But I notice that va-ppc.h does not define
void *__va_arg(va_list argp, _va_arg_list_type type) which is *required* by the
same ABI <grin>
Do I smell a bug ?? ;)
> 2. it nicely spots a common programming error
Yes, but only in one assignment direction. In any case, it caught the error on
ssh, and I'll post LinuxPPC specific patches to ssh-2.0.13 soonish.
-jason
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-11-30 10:58 ` Franz Sirl
1999-11-30 18:05 ` Jason Kim
@ 1999-11-30 23:28 ` Jason Kim
1999-12-01 15:33 ` Franz Sirl
1 sibling, 1 reply; 15+ messages in thread
From: Jason Kim @ 1999-11-30 23:28 UTC (permalink / raw)
To: Franz Sirl, gcc-patches@gcc.gnu.org,
linuxppc-dev@lists.linuxppc.org
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: letter2 --]
[-- Type: text/plain, Size: 3791 bytes --]
There is an unforseen sideeffect to having va_list be a typedef to an array of
1 element. This strangeness comes up when passing the reference to a va_list
suppose one has the following definition of va_list (as per va-ppc.h)
typedef struct va_tag {
char a;
char *b;
} B[1], C[1];
typedef C va_list;
void bar(va_list* d2)
{
printf("d2 = 0x%x\n", d2);
va_arg(*d2); // this call FAILS
}
void tst(va_list d1)
{
printf("d1 = 0x%x\n", d1);
bar(&d1); // gcc gives warning here. but no way to really ``fix it''
}
int main()
{
va_list d3;
printf("foo\n");
tst(d3);
};
but at bar(), calling va_arg(*d2) fails because it is (incorrectly)
dereferencing a D*, but the desired result is of course doing *(va_tag**d2)
but doing so will fail on hosts that do NOT follow the ABI convention. (such
as Intel x86 and SPARC (!) varags, because they do not define ``va_tag'')
And in truth, the SYSVR4 ABI for PPC doc lists va_list in an example, and does
not anywhere state that va_list MUST be defined as shown in page 6-6. (your
page listing may vary, I got standards docs from google.com)
The va_list definition from the ABI seems a bit of an ad-hoc example, and
besides, when one passes an address of something, one expects to get the
``something'' back if the pointer is dereferenced. The fact that the C
language passes arrays as a pointer to the first item only adds to the
confusion.
Also, in the ANSI C (9x) documentation (``n843''), taking the address of a
va_list is NOT listed as one of the things that will produce an undefined
result. Actually, on page 7.15 (pg246 as seen by acroread), footnote item 198
specifically states ``It is permitted to create a pointer to a va_list and
pass that pointer to another function,.. in which case the original list may
make further use of the original list after the other function returns.''
And from the various varargs.h that I've seen, its rather cumbersome to
automatically determine exactly what type a va_list really is, and whether
dereferencing a va_list* will return an unexpected result (or not).
Not to mention, one of the first things one learns in coding image/signal
processing and matrix math stuff is, to never declare (or pass around) fixed
size arrays, which can result in broken code.
Quite frankly, I don't see a clear reason WHY the ABI shows the sample va_list
as implemented like it is, and since the result is unnecessarily unintuitive
code management which makes it difficult to do something specifically allowed
in the ANSI C standards documentation, and since there is a perfectly easy,
portable solution to this, will you reconsider the patches I sent out?
In case of a battling standards docs, one would think a compiler would chose
the language docs over an ABI doc, don't you think??
-jason.
now the va_arg call fails because app is of type (va_list *) or (
Franz Sirl wrote:
>
> At 07:00 30.11.99 , Jason Kim wrote:
> >Agreed, ssh2 code isn't necessarily the cleanest in the world, but then again
> >the varargs situation in PPC world is a bit peculiar.
> >
> >
> >typedef struct A {
> > char foo;
> > char *bar;
> >} B[1], C[1];
> >
> >typedef C D;
> >
> >
> >void tst(D d1)
> >{
> > D d2;
> > d1 = d2; // this is legal
> > // d2 = d1; // this is not
> >}
> >
> >declaring arrays of fixed size seems a bit strange for a type which will
> >be used
> >by user code, since it makes d1 and d2 be different types sometimes. Not to
> >mention, having struct _va_list_tag AS va_list seem to fix the problems
> >neatly.
> >
> >Is there a technical reason for keeping va_list as an array of 1 element?
> >(instead of just a single element??)
>
> 1. this behaviour is mandated by the ABI
> 2. it nicely spots a common programming error
>
> I see nothing peculiar about it :-).
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-11-30 23:28 ` Jason Kim
@ 1999-12-01 15:33 ` Franz Sirl
1999-12-01 19:18 ` Jason Kim
0 siblings, 1 reply; 15+ messages in thread
From: Franz Sirl @ 1999-12-01 15:33 UTC (permalink / raw)
To: Jason Kim; +Cc: gcc-patches@gcc.gnu.org, linuxppc-dev@lists.linuxppc.org
At 00:28 01.12.99 , Jason Kim wrote:
>Also, in the ANSI C (9x) documentation (``n843''), taking the address of a
>va_list is NOT listed as one of the things that will produce an undefined
>result. Actually, on page 7.15 (pg246 as seen by acroread), footnote item 198
>specifically states ``It is permitted to create a pointer to a va_list and
>pass that pointer to another function,.. in which case the original list may
>make further use of the original list after the other function returns.''
Well, I see this is also in ISO C9x, but unless the standard restricts the
possible types for va_list (I can't find anything about that), you have
still to be aware that any callee gets a reference to the va_list if
va_list is an array and so the usual array handling rules apply, or?
Franz.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-12-01 15:33 ` Franz Sirl
@ 1999-12-01 19:18 ` Jason Kim
1999-12-01 19:41 ` Kevin Hendricks
1999-12-01 19:43 ` David A. Gatwood
0 siblings, 2 replies; 15+ messages in thread
From: Jason Kim @ 1999-12-01 19:18 UTC (permalink / raw)
To: Franz Sirl, linuxppc-dev@lists.linuxppc.org,
gcc-patches@gcc.gnu.org
Franz Sirl wrote:
>
> At 00:28 01.12.99 , Jason Kim wrote:
> >Also, in the ANSI C (9x) documentation (``n843''), taking the address of a
> >va_list is NOT listed as one of the things that will produce an undefined
> >result. Actually, on page 7.15 (pg246 as seen by acroread), footnote item 198
> >specifically states ``It is permitted to create a pointer to a va_list and
> >pass that pointer to another function,.. in which case the original list may
> >make further use of the original list after the other function returns.''
>
> Well, I see this is also in ISO C9x, but unless the standard restricts the
> possible types for va_list (I can't find anything about that), you have
> still to be aware that any callee gets a reference to the va_list if
> va_list is an array and so the usual array handling rules apply, or?
>
This is getting rather silly. So for a coder to use a set of macros
which were standardized for encapsulating portability issues, he has
to develop another set of macros to get past this
C-array-passed-as-pointer ``feature'' to even pretend to have portable
code?
What about double indirection? or triple, for that matter?
Not to mention implementing va_list this way explicitly breaks compatibility
between gcc on ppc and gcc on SPARC, x86, clipper, alpha... etc.. You name it.
Its broken.
Does this make any sense?
Having a fixed size array as a user accessible item (which is TYPEDEF'ed to
resemble a structure, no less) which could be passed around is just a BAD idea
in C/C++. I have yet to hear any concrete reasons (besides just plain
obstinacy) why va_list HAS to be implemented this way.
-jason.
> Franz.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-12-01 19:18 ` Jason Kim
@ 1999-12-01 19:41 ` Kevin Hendricks
1999-12-02 5:20 ` Jason Kim
1999-12-01 19:43 ` David A. Gatwood
1 sibling, 1 reply; 15+ messages in thread
From: Kevin Hendricks @ 1999-12-01 19:41 UTC (permalink / raw)
To: Jason Kim, Franz Sirl, linuxppc-dev@lists.linuxppc.org,
gcc-patches@gcc.gnu.org
Hi,
My 2 cents.
> What about double indirection? or triple, for that matter?
>
> Not to mention implementing va_list this way explicitly breaks compatibility
> between gcc on ppc and gcc on SPARC, x86, clipper, alpha... etc.. You name it.
> Its broken.
va_lists are used heavily in the jdk and pointers to va_lists are passed in
routines. I had to track down each and every time a pointer into a va_list was
passed as a parameter to another routine and fix each one. So there needed to
be ppc specific code if def'd into the Sun source code in mutliple places which
otherwise worked as is on every other platform including sparc, x86, m68k, etc.
This is over and above using va_copy or memcpy trickery as required for the
jdk.
And the worst part about debugging all of this is that the code which
worked for all other platforms simply failed quietly on ppc. So when debugging
a large source code base which you did not write and seems to be portable
across a number of other platforms, silent failures are nasty (unless you
luckily got a seg-fault).
The problem would just get worse with multiple indirection.
If there is any way to change this without beaking backward compatibility with
pre-compiled shared libs and things, I would vote for it.
Comments?
Kevin
>
> Does this make any sense?
>
> Having a fixed size array as a user accessible item (which is TYPEDEF'ed to
> resemble a structure, no less) which could be passed around is just a BAD idea
> in C/C++. I have yet to hear any concrete reasons (besides just plain
> obstinacy) why va_list HAS to be implemented this way.
>
>
> -jason.
>
>
>
> > Franz.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-12-01 19:41 ` Kevin Hendricks
@ 1999-12-02 5:20 ` Jason Kim
1999-12-02 7:15 ` Richard Henderson
1999-12-02 7:27 ` Kevin Buettner
0 siblings, 2 replies; 15+ messages in thread
From: Jason Kim @ 1999-12-02 5:20 UTC (permalink / raw)
To: khendricks, linuxppc-dev@lists.linuxppc.org,
gcc-patches@gcc.gnu.org, David A. Gatwood, Franz Sirl
Kevin Hendricks wrote:
> If there is any way to change this without beaking backward compatibility with
> pre-compiled shared libs and things, I would vote for it.
>
Well, xemacs-21.1.8, Mesa-3.0, gcc-2.95.2, xscreensaver-3.21, gle-2.3 and
ssh-2.0.13 all compile and link against the older dynamic libraries, but use the
va_list definition from my patch. All seem to work fine. They were all compiled
from gcc-2.95.2 and binutils-2.95.?? on an otheriwise standard LinuxPPC 1999 Q3
install on my Apple B&W G3.
It seems that the va_list is more or less isolated from the library interface
issues, as user code that I've seen don't ever pass back va_list to library
code, so having the patch seems to be safe, at least for above packages.
Anybody have any examples of where there IS va_list passage from user code to
existing dynlib code (or vice versa)? I tried a bit, and couldn't find any, and
am thinking that there isn't any. If that is the case, then applying the patch
en-mass
seems harmless way for getting rid of the array based va_list once and for all.
Feedback please.
thanks.
-jason.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-12-02 5:20 ` Jason Kim
@ 1999-12-02 7:15 ` Richard Henderson
1999-12-02 7:27 ` Kevin Buettner
1 sibling, 0 replies; 15+ messages in thread
From: Richard Henderson @ 1999-12-02 7:15 UTC (permalink / raw)
To: Jason Kim
Cc: khendricks, linuxppc-dev@lists.linuxppc.org,
gcc-patches@gcc.gnu.org, David A. Gatwood, Franz Sirl
On Thu, Dec 02, 1999 at 12:20:06AM -0500, Jason Kim wrote:
> Well, xemacs-21.1.8, Mesa-3.0, gcc-2.95.2, xscreensaver-3.21, gle-2.3 and
> ssh-2.0.13 all compile and link against the older dynamic libraries, but
> use the va_list definition from my patch. All seem to work fine.
An interesting happy accident. The PPC SVR4 ABI passes structures
by reference, which at the machine level winds up looking just like
it does when the array decomposes into a pointer.
> Anybody have any examples of where there IS va_list passage from user code to
> existing dynlib code (or vice versa)?
Of course -- vfprintf.
> If that is the case, then applying the patch en-mass
> seems harmless way for getting rid of the array based va_list once
> and for all.
Except that we're not going to do that. We'll stay with the
letter of the PPC SVR4 ABI law, thanks.
Despite what you may think, PPC is not unique in its use of an
array definition for va_list. Whatever changes that might could
be made in gcc doesn't make the code in question any more correct
pedantically, and will continue to break when you go use someone
else's compiler.
r~
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-12-02 5:20 ` Jason Kim
1999-12-02 7:15 ` Richard Henderson
@ 1999-12-02 7:27 ` Kevin Buettner
1999-12-02 16:15 ` Jason Kim
1 sibling, 1 reply; 15+ messages in thread
From: Kevin Buettner @ 1999-12-02 7:27 UTC (permalink / raw)
To: gcc-patches@gcc.gnu.org, linuxppc-dev@lists.linuxppc.org,
Jason Kim
On Dec 2, 12:20am, Jason Kim wrote:
> Anybody have any examples of where there IS va_list passage from
> user code to existing dynlib code (or vice versa)? I tried a bit,
> and couldn't find any, and am thinking that there isn't any. If
> that is the case, then applying the patch en-mass seems harmless way
> for getting rid of the array based va_list once and for all.
How about anything that calls vprintf, vsprintf, or vsnprintf?
A more concrete example: Suppose you've compiled the perl library
to use the old interface and then compile an application which
uses it with your va_list interface. Then suppose the application
calls sv_vsetpvfn() in the perl library. Would it work?
I feel like I'm playing devil's advocate here because I would really
like it if you (or someone) could straighten out the ppc va_list
issues. I've been bitten by problems similar to the ones that you've
encountered more than once over the years. Recently I had to fix a
problem in gdb where it would've been nice to do a va_list copy.
Instead, I restructured the code so that a copy wasn't necessary. It
turned out to be doable in this instance, but I'm aware of some code
in libiberty that can't be restructured so easily. (But for some
reason, it seems to be working now on linux/ppc. I remember a time
when it didn't.)
Kevin
--
Kevin Buettner
kev@primenet.com, kevinb@cygnus.com
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-12-02 7:27 ` Kevin Buettner
@ 1999-12-02 16:15 ` Jason Kim
0 siblings, 0 replies; 15+ messages in thread
From: Jason Kim @ 1999-12-02 16:15 UTC (permalink / raw)
To: Kevin Buettner, linuxppc-dev@lists.linuxppc.org,
gcc-patches@gcc.gnu.org, Franz Sirl, Richard Henderson,
David A. Gatwood
Kevin Buettner wrote:
> How about anything that calls vprintf, vsprintf, or vsnprintf?
Works with my patches. no probs.
> A more concrete example: Suppose you've compiled the perl library
> to use the old interface and then compile an application which
> uses it with your va_list interface. Then suppose the application
> calls sv_vsetpvfn() in the perl library. Would it work?
I'll try this as soon as I hack up some src to test it (sometime today,
hopefully).
(crossed fingers??)
-jason.
>
> I feel like I'm playing devil's advocate here because I would really
> like it if you (or someone) could straighten out the ppc va_list
> issues. I've been bitten by problems similar to the ones that you've
> encountered more than once over the years. Recently I had to fix a
> problem in gdb where it would've been nice to do a va_list copy.
> Instead, I restructured the code so that a copy wasn't necessary. It
> turned out to be doable in this instance, but I'm aware of some code
> in libiberty that can't be restructured so easily. (But for some
> reason, it seems to be working now on linux/ppc. I remember a time
> when it didn't.)
>
> Kevin
>
> --
> Kevin Buettner
> kev@primenet.com, kevinb@cygnus.com
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-12-01 19:18 ` Jason Kim
1999-12-01 19:41 ` Kevin Hendricks
@ 1999-12-01 19:43 ` David A. Gatwood
1999-12-02 2:04 ` Jason Kim
1 sibling, 1 reply; 15+ messages in thread
From: David A. Gatwood @ 1999-12-01 19:43 UTC (permalink / raw)
To: Jason Kim
Cc: Franz Sirl, linuxppc-dev@lists.linuxppc.org,
gcc-patches@gcc.gnu.org
On Wed, 1 Dec 1999, Jason Kim wrote:
> Having a fixed size array as a user accessible item (which is TYPEDEF'ed to
> resemble a structure, no less) which could be passed around is just a BAD idea
> in C/C++. I have yet to hear any concrete reasons (besides just plain
> obstinacy) why va_list HAS to be implemented this way.
Years of legacy binaries that would have to be rebuilt, for one. The fact
that we _just_ had a varargs-related rework of some programs (linux
kernel, mach kernel, etc. come to mind) for gcc 2.95.x is another reason.
Mucking with the way the compiler builds varargs can have really nasty
implications. It should not be changed for trivial reasons. The macros
are there to be used. Attempting to do anything else with varargs breaks
spec, and changing the compiler and everything ever built with it just to
make it easier for coders to be sloppy is a bad idea (tm).
David
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-12-01 19:43 ` David A. Gatwood
@ 1999-12-02 2:04 ` Jason Kim
0 siblings, 0 replies; 15+ messages in thread
From: Jason Kim @ 1999-12-02 2:04 UTC (permalink / raw)
To: David A. Gatwood, gcc-patches@gcc.gnu.org,
linuxppc-dev@lists.linuxppc.org, khendricks@ivey.uwo.ca,
Franz Sirl
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: letter5 --]
[-- Type: text/plain, Size: 3048 bytes --]
David A. Gatwood wrote:
> Years of legacy binaries that would have to be rebuilt, for one. The fact
> that we _just_ had a varargs-related rework of some programs (linux
> kernel, mach kernel, etc. come to mind) for gcc 2.95.x is another reason.
> Mucking with the way the compiler builds varargs can have really nasty
> implications. It should not be changed for trivial reasons. The macros
Hmm. Legacy peeks its ugly head.
Sigh. Ok, so we have one reason for KEEPING va_list as implemented on PPC, but
the thing with legacy stuff is, if you leave it alone, it doesn't get any
better. (Really!)
Funny thing is:
As far as ssh is concerned, its working FINE with my va-ppc.h patches (compiled
with gcc-2.95.2 on LinuxPPC 1999 Q3). Which is a happy accident, I am sure but
an interesting one. (and it prints messages just fine to logs, stdout etc..)
I certainly DID NOT HAVE TO RECOMPILE LIBC ON MY B&W G3.
Hmm, somebody correct me on this if I am wrong, but as far as libc (or other
libs that use va_list) is concerned, are there any places where va_list is
PASSED to-and-from user code to lib code? I don't know of any.
If not, then I believe newly recompiled stuff (such as my ssh) WILL WORK FINE
with the patches I posted, even dynlinking against older libs. (which it is
doing now, as I speak, supporting this xterm running through the ssh pipe!) I
mean, the precompiled [snv]*printf() will use va_list in its implementation,
but the code that uses the older ones are already compiled in, and we don't
actually *pass* the different va_list structures back and forth, right?
I'll recompile xemacs-21.1.8 and gcc-2.95.2 on my LinuxPPC box with my patches
turned ON (through gcc-2.95.2 and binutils-2.9.5.xxx), linking against the
older libs, and let you guys know how it goes. At the risk of foot-in-mouth
syndrome, I'll say now that I suspect it will be *fine*.
> are there to be used. Attempting to do anything else with varargs breaks
> spec,
No. For the issue I am mentioning, the specs are NOT broken by the user
code. The ANSI C (9x) draft doc specifically states that a function *can* pass
around pointers to va_lists to other functions. Just so happens that va_list
is implemented as pointers on most other platforms, and has no issues with
dereferencing (N-indirections of) them, but on PPC, they are implemented as a
fixed size ARRAY, which confuses things.
> and changing the compiler and everything ever built with it just to
> make it easier for coders to be sloppy is a bad idea (tm).
I wouldn't think passing pointers to va_lists is a sloppy, bad idea. It is a
perfectly reasonable way of doing some things.
<grin on>
I am extremely curious as to what was going through the mind of the PPC ABI
doc writers as they were writing up the example va_list implementation.
(whom I am told, (by Franz) are the culprits behind this hilarity)
Perhaps they were high on something, eh?? Perhaps we should draft them to
recompiling our libc and other apps that use va_list for us.
sheesh.
<grin off>
-jason.
> David
^ permalink raw reply [flat|nested] 15+ messages in thread
* patch for problem with va-ppc.h included with egcs and gcc-2.95.2
@ 1999-11-29 21:03 Jason Kim
1999-11-29 22:45 ` Franz Sirl
0 siblings, 1 reply; 15+ messages in thread
From: Jason Kim @ 1999-11-29 21:03 UTC (permalink / raw)
To: gcc-patches, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
There is no ChangeLog here. The original files in GCC (2.95.2) had no
changelog (!)
jason kim.
jwk2@eecs.lehigh.edu
[-- Attachment #2: letter1 --]
[-- Type: text/plain, Size: 1093 bytes --]
There is a problem with va-ppc.h distributed with recent versions of
gcc (2.95 and onwards) as well as the older egcs 1.1 releases.
va-ppc.h typedefs va_list as an array of 1 element of struct
_va_list_tag but this causes problems when va_lists (or pointers to
them!) are passed as arguments to functions:
e.g.
void foo(va_list va1)
{
va_list va2;
va1 = va2;
}
will cause the compilation to fail with incompatible pointer types under
PowerPC linux systems (including LinuxPPC 1999 Q3)
Included with this message are two patches, one for
/usr/lib/gcc-lib/ppc-redhat-linux/egcs-2.91.66/include/va-ppc.h
and a similar patch for gcc/ginclude/va-ppc.h in gcc-2.95.2 (generic)
This patch is needed to compile and run programs that use vararg stuff
extensively such as ssh-2.0.13 on PowerPC based linux systems.
I have tested my patch in a 1999 Q3 version of LinuxPPC and seems to work
fine. (i.e. ssh2 compiled, and ran, and works with no probs)
p.s. gcc-2.95.2 and the latest binutils seems to disagree on what the proper
target name is for linking... more on this as it develops..
[-- Attachment #3: va-ppc.h.patch.linuxppc1999.q3 --]
[-- Type: text/plain, Size: 5944 bytes --]
*** va-ppc.h 1999/11/29 13:33:07 1.1
--- va-ppc.h 1999/11/29 13:39:12
***************
*** 12,18 ****
/* Solaris decided to rename overflow_arg_area to input_arg_area,
so handle it via a macro. */
! #define __va_overflow(AP) (AP)->overflow_arg_area
/* Note that the names in this structure are in the user's namespace, but
that the V.4 abi explicitly states that these names should be used. */
--- 12,18 ----
/* Solaris decided to rename overflow_arg_area to input_arg_area,
so handle it via a macro. */
! #define __va_overflow(AP) (AP).overflow_arg_area
/* Note that the names in this structure are in the user's namespace, but
that the V.4 abi explicitly states that these names should be used. */
*************** typedef struct __va_list_tag {
*** 26,37 ****
char *overflow_arg_area; /* location on stack that holds the next
overflow argument */
char *reg_save_area; /* where r3:r10 and f1:f8, if saved are stored */
! } __va_list[1], __gnuc_va_list[1];
#else /* _SYS_VA_LIST */
typedef __va_list __gnuc_va_list;
! #define __va_overflow(AP) (AP)->input_arg_area
#endif /* not _SYS_VA_LIST */
#endif /* not __GNUC_VA_LIST */
--- 26,37 ----
char *overflow_arg_area; /* location on stack that holds the next
overflow argument */
char *reg_save_area; /* where r3:r10 and f1:f8, if saved are stored */
! } __va_list, __gnuc_va_list;
#else /* _SYS_VA_LIST */
typedef __va_list __gnuc_va_list;
! #define __va_overflow(AP) (AP).input_arg_area
#endif /* not _SYS_VA_LIST */
#endif /* not __GNUC_VA_LIST */
*************** typedef struct {
*** 53,63 ****
a warning about increasing the alignment requirement. */
#define __VA_FP_REGSAVE(AP,TYPE) \
((TYPE *) (void *) (&(((__va_regsave_t *) \
! (AP)->reg_save_area)->__fp_save[(int)(AP)->fpr])))
#define __VA_GP_REGSAVE(AP,TYPE) \
((TYPE *) (void *) (&(((__va_regsave_t *) \
! (AP)->reg_save_area)->__gp_save[(int)(AP)->gpr])))
/* Common code for va_start for both varargs and stdarg. This depends
on the format of rs6000_args in rs6000.h. The fields used are:
--- 53,63 ----
a warning about increasing the alignment requirement. */
#define __VA_FP_REGSAVE(AP,TYPE) \
((TYPE *) (void *) (&(((__va_regsave_t *) \
! (AP).reg_save_area)->__fp_save[(int)(AP).fpr])))
#define __VA_GP_REGSAVE(AP,TYPE) \
((TYPE *) (void *) (&(((__va_regsave_t *) \
! (AP).reg_save_area)->__gp_save[(int)(AP).gpr])))
/* Common code for va_start for both varargs and stdarg. This depends
on the format of rs6000_args in rs6000.h. The fields used are:
*************** typedef struct {
*** 78,86 ****
__extension__ ({ \
register int __words = __va_words - FAKE; \
\
! (AP)->gpr = (__words < 8) ? __words : 8; \
! (AP)->fpr = __va_fregno - 33; \
! (AP)->reg_save_area = ((char *) __builtin_args_info (8)); \
__va_overflow(AP) = ((char *)__builtin_saveregs () \
+ (((__words >= 8) ? __words - 8 : 0) \
* sizeof (long))); \
--- 78,86 ----
__extension__ ({ \
register int __words = __va_words - FAKE; \
\
! (AP).gpr = (__words < 8) ? __words : 8; \
! (AP).fpr = __va_fregno - 33; \
! (AP).reg_save_area = ((char *) __builtin_args_info (8)); \
__va_overflow(AP) = ((char *)__builtin_saveregs () \
+ (((__words >= 8) ? __words - 8 : 0) \
* sizeof (long))); \
*************** __extension__ ({ \
*** 118,151 ****
__extension__ (*({ \
register TYPE *__ptr; \
\
! if (__va_float_p (TYPE) && (AP)->fpr < 8) \
{ \
__ptr = __VA_FP_REGSAVE (AP, TYPE); \
! (AP)->fpr++; \
} \
\
! else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8) \
{ \
__ptr = * __VA_GP_REGSAVE (AP, TYPE *); \
! (AP)->gpr++; \
} \
\
else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \
! && (AP)->gpr + __va_size(TYPE) <= 8 \
&& (!__va_longlong_p(TYPE) \
! || (AP)->gpr + __va_size(TYPE) <= 8)) \
{ \
! if (__va_longlong_p(TYPE) && ((AP)->gpr & 1) != 0) \
! (AP)->gpr++; \
\
__ptr = __VA_GP_REGSAVE (AP, TYPE); \
! (AP)->gpr += __va_size (TYPE); \
} \
\
else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \
! && (AP)->gpr < 8) \
{ \
! (AP)->gpr = 8; \
__ptr = (TYPE *) (void *) (__va_overflow(AP)); \
__va_overflow(AP) += __va_size (TYPE) * sizeof (long); \
} \
--- 118,151 ----
__extension__ (*({ \
register TYPE *__ptr; \
\
! if (__va_float_p (TYPE) && (AP).fpr < 8) \
{ \
__ptr = __VA_FP_REGSAVE (AP, TYPE); \
! (AP).fpr++; \
} \
\
! else if (__va_aggregate_p (TYPE) && (AP).gpr < 8) \
{ \
__ptr = * __VA_GP_REGSAVE (AP, TYPE *); \
! (AP).gpr++; \
} \
\
else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \
! && (AP).gpr + __va_size(TYPE) <= 8 \
&& (!__va_longlong_p(TYPE) \
! || (AP).gpr + __va_size(TYPE) <= 8)) \
{ \
! if (__va_longlong_p(TYPE) && ((AP).gpr & 1) != 0) \
! (AP).gpr++; \
\
__ptr = __VA_GP_REGSAVE (AP, TYPE); \
! (AP).gpr += __va_size (TYPE); \
} \
\
else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \
! && (AP).gpr < 8) \
{ \
! (AP).gpr = 8; \
__ptr = (TYPE *) (void *) (__va_overflow(AP)); \
__va_overflow(AP) += __va_size (TYPE) * sizeof (long); \
} \
[-- Attachment #4: va-ppc.h.patch.gcc-2.95.2 --]
[-- Type: text/plain, Size: 6437 bytes --]
*** va-ppc.h Mon Aug 9 01:55:16 1999
--- va-ppc.fixed.h Mon Nov 29 15:43:17 1999
***************
*** 12,18 ****
/* Solaris decided to rename overflow_arg_area to input_arg_area,
so handle it via a macro. */
! #define __va_overflow(AP) (AP)->overflow_arg_area
/* Note that the names in this structure are in the user's namespace, but
that the V.4 abi explicitly states that these names should be used. */
--- 12,18 ----
/* Solaris decided to rename overflow_arg_area to input_arg_area,
so handle it via a macro. */
! #define __va_overflow(AP) (AP).overflow_arg_area
/* Note that the names in this structure are in the user's namespace, but
that the V.4 abi explicitly states that these names should be used. */
*************** typedef struct __va_list_tag {
*** 26,37 ****
char *overflow_arg_area; /* location on stack that holds the next
overflow argument */
char *reg_save_area; /* where r3:r10 and f1:f8, if saved are stored */
! } __va_list[1], __gnuc_va_list[1];
#else /* _SYS_VA_LIST */
typedef __va_list __gnuc_va_list;
! #define __va_overflow(AP) (AP)->input_arg_area
#endif /* not _SYS_VA_LIST */
#endif /* not __GNUC_VA_LIST */
--- 26,37 ----
char *overflow_arg_area; /* location on stack that holds the next
overflow argument */
char *reg_save_area; /* where r3:r10 and f1:f8, if saved are stored */
! } __va_list, __gnuc_va_list;
#else /* _SYS_VA_LIST */
typedef __va_list __gnuc_va_list;
! #define __va_overflow(AP) (AP).input_arg_area
#endif /* not _SYS_VA_LIST */
#endif /* not __GNUC_VA_LIST */
*************** typedef struct {
*** 53,63 ****
a warning about increasing the alignment requirement. */
#define __VA_FP_REGSAVE(AP,OFS,TYPE) \
((TYPE *) (void *) (&(((__va_regsave_t *) \
! (AP)->reg_save_area)->__fp_save[OFS])))
#define __VA_GP_REGSAVE(AP,OFS,TYPE) \
((TYPE *) (void *) (&(((__va_regsave_t *) \
! (AP)->reg_save_area)->__gp_save[OFS])))
/* Common code for va_start for both varargs and stdarg. We allow all
the work to be done by __builtin_saveregs. It returns a pointer to
--- 53,63 ----
a warning about increasing the alignment requirement. */
#define __VA_FP_REGSAVE(AP,OFS,TYPE) \
((TYPE *) (void *) (&(((__va_regsave_t *) \
! (AP).reg_save_area)->__fp_save[OFS])))
#define __VA_GP_REGSAVE(AP,OFS,TYPE) \
((TYPE *) (void *) (&(((__va_regsave_t *) \
! (AP).reg_save_area)->__gp_save[OFS])))
/* Common code for va_start for both varargs and stdarg. We allow all
the work to be done by __builtin_saveregs. It returns a pointer to
*************** __extension__ (*({ \
*** 110,120 ****
\
if (__va_float_p (TYPE) && sizeof (TYPE) < 16) \
{ \
! unsigned char __fpr = (AP)->fpr; \
if (__fpr < 8) \
{ \
__ptr = __VA_FP_REGSAVE (AP, __fpr, TYPE); \
! (AP)->fpr = __fpr + 1; \
} \
else if (sizeof (TYPE) == 8) \
{ \
--- 110,120 ----
\
if (__va_float_p (TYPE) && sizeof (TYPE) < 16) \
{ \
! unsigned char __fpr = (AP).fpr; \
if (__fpr < 8) \
{ \
__ptr = __VA_FP_REGSAVE (AP, __fpr, TYPE); \
! (AP).fpr = __fpr + 1; \
} \
else if (sizeof (TYPE) == 8) \
{ \
*************** __extension__ (*({ \
*** 132,142 ****
/* Aggregates and long doubles are passed by reference. */ \
else if (__va_aggregate_p (TYPE) || __va_float_p (TYPE)) \
{ \
! unsigned char __gpr = (AP)->gpr; \
if (__gpr < 8) \
{ \
__ptr = * __VA_GP_REGSAVE (AP, __gpr, TYPE *); \
! (AP)->gpr = __gpr + 1; \
} \
else \
{ \
--- 132,142 ----
/* Aggregates and long doubles are passed by reference. */ \
else if (__va_aggregate_p (TYPE) || __va_float_p (TYPE)) \
{ \
! unsigned char __gpr = (AP).gpr; \
if (__gpr < 8) \
{ \
__ptr = * __VA_GP_REGSAVE (AP, __gpr, TYPE *); \
! (AP).gpr = __gpr + 1; \
} \
else \
{ \
*************** __extension__ (*({ \
*** 152,179 ****
/* longlong is aligned. */ \
if (sizeof (TYPE) == 8) \
{ \
! unsigned char __gpr = (AP)->gpr; \
if (__gpr < 7) \
{ \
__gpr += __gpr & 1; \
__ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE); \
! (AP)->gpr = __gpr + 2; \
} \
else \
{ \
unsigned long __addr = (unsigned long) (__va_overflow (AP)); \
__ptr = (TYPE *)((__addr + 7) & -8); \
! (AP)->gpr = 8; \
__va_overflow (AP) = (char *)(__ptr + 1); \
} \
} \
else if (sizeof (TYPE) == 4) \
{ \
! unsigned char __gpr = (AP)->gpr; \
if (__gpr < 8) \
{ \
__ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE); \
! (AP)->gpr = __gpr + 1; \
} \
else \
{ \
--- 152,179 ----
/* longlong is aligned. */ \
if (sizeof (TYPE) == 8) \
{ \
! unsigned char __gpr = (AP).gpr; \
if (__gpr < 7) \
{ \
__gpr += __gpr & 1; \
__ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE); \
! (AP).gpr = __gpr + 2; \
} \
else \
{ \
unsigned long __addr = (unsigned long) (__va_overflow (AP)); \
__ptr = (TYPE *)((__addr + 7) & -8); \
! (AP).gpr = 8; \
__va_overflow (AP) = (char *)(__ptr + 1); \
} \
} \
else if (sizeof (TYPE) == 4) \
{ \
! unsigned char __gpr = (AP).gpr; \
if (__gpr < 8) \
{ \
__ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE); \
! (AP).gpr = __gpr + 1; \
} \
else \
{ \
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
1999-11-29 21:03 Jason Kim
@ 1999-11-29 22:45 ` Franz Sirl
0 siblings, 0 replies; 15+ messages in thread
From: Franz Sirl @ 1999-11-29 22:45 UTC (permalink / raw)
To: Jason Kim, gcc-patches, linuxppc-dev
Am Mon, 29 Nov 1999 schrieb Jason Kim:
>There is a problem with va-ppc.h distributed with recent versions ofgcc (2.95
>and onwards) as well as the older egcs 1.1 releases.
>
>va-ppc.h typedefs va_list as an array of 1 element of struct
>_va_list_tag but this causes problems when va_lists (or pointers to
>them!) are passed as arguments to functions:
>
>e.g.
>
>void foo(va_list va1)
>{
>va_list va2;
>va1 = va2;
>}
The source is wrong, this code is simply non-portable. Use __va_copy(va1, va2)
or some memcpy trickery to fix the source.
>p.s. gcc-2.95.2 and the latest binutils seems to disagree on what the proper
>target name is for linking... more on this as it develops..
You need binutils-2.9.4.0.8 or later for gcc-2.95.
Franz.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~1999-12-02 16:15 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
1999-11-30 6:00 patch for problem with va-ppc.h included with egcs and gcc-2.95.2 Jason Kim
1999-11-30 10:58 ` Franz Sirl
1999-11-30 18:05 ` Jason Kim
1999-11-30 23:28 ` Jason Kim
1999-12-01 15:33 ` Franz Sirl
1999-12-01 19:18 ` Jason Kim
1999-12-01 19:41 ` Kevin Hendricks
1999-12-02 5:20 ` Jason Kim
1999-12-02 7:15 ` Richard Henderson
1999-12-02 7:27 ` Kevin Buettner
1999-12-02 16:15 ` Jason Kim
1999-12-01 19:43 ` David A. Gatwood
1999-12-02 2:04 ` Jason Kim
-- strict thread matches above, loose matches on Subject: below --
1999-11-29 21:03 Jason Kim
1999-11-29 22:45 ` Franz Sirl
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).