Subject: Re: egcs & sparc.
To: None <port-sparc@netbsd.org, tech-toolchain@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-toolchain
Date: 10/30/1998 14:05:09
[Replying to multiple messages here.]

> Ah yes. Inappropriate casting of a `struct sockaddr' pointer to a
> `struct sockaddr_in' pointer..   This is not the fault of egcs.

You beat me to it; I was about to say the same thing.  A struct
sockaddr_in needs stricter alignment than a struct sockaddr, so it is
not safe to take an object declared as a struct sockaddr, cast it to
struct sockaddr_in (or more precisely cast the pointer), and expect it
to work.

> Hmm.  This seems unfortunate as this seems likely to be a common
> idiom (likely used in application code as well....)...

Most application code I've seen declares the appropriate AF-specific
struct and then casts it to the generic type, perhaps later casting it
back.  Provided the final type requires no stricter alignment than the
initial type, you're OK.  (Well, not in a strict language-lawyer sense,
but rather in a practical sense with NetBSD.)

> So, what's the right thing to do if you're not supposed to cast
> struct sockaddr * to struct sockaddr_in *?

There's nothing at all wrong with that - *provided* that the actual
object to which the pointer points is really a struct sockaddr_in, and
in particular is aligned appropriately for a struct sockaddr_in.

In this case, the object was a union of a struct sockaddr and an array
of shorts.  The latter requires 2-byte alignment on the SPARC, and the
generic struct sockaddr has no restrictions (as of sys/socket.h 1.37 at
least), so the compiler quite justifiably chose to align it on a 2-byte
boundary.  With gcc, it seems that it happened to land on a 4-byte
boundary and thus "work"; with egcs, it seems not.

Either the union should include a struct sockaddr_in (and any other
such types it may get cast to), or it should be declared with an
appropriate __aligned__ attribute.

> ...Besides, casting sockaddr to sockaddr_in should be Just Fine;
> after all, if one is aligned, the other most certainly should be.

Ah, there's the problem: "aligned" for a struct sockaddr (2 bytes) is
less strict than "aligned" for a struct sockadr_in (4 bytes).

					der Mouse

			       mouse@rodents.montreal.qc.ca
		     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B