Date: Sun, 14 Jul 2002 13:43:37 -0700 From: Luigi Rizzo <luigi@freebsd.org> To: current@freebsd.org Subject: Re: different packing of structs in kernel vs. userland ? Message-ID: <20020714134337.A78891@iguana.icir.org> In-Reply-To: <20020714203642.GD314@crow.dom2ip.de>; from tmoestl@gmx.net on Sun, Jul 14, 2002 at 10:36:42PM %2B0200 References: <20020714011810.A72236@iguana.icir.org> <20020714203642.GD314@crow.dom2ip.de>
index | next in thread | previous in thread | raw e-mail
[i am deliberately not trimming the email in case someone wants to
look at the context]
i am a bit dubious about your explaination -- it also does not
explain why the person reporting this problem "fixed" that
by swapping "timestamp" and "next_rule" in the structure
cheers
luigi
On Sun, Jul 14, 2002 at 10:36:42PM +0200, Thomas Moestl wrote:
> On Sun, 2002/07/14 at 01:18:10 -0700, Luigi Rizzo wrote:
> > Hi,
> > the following message seems to suggest that the compiler
> > (the way it is invoked) packs structures differently
> > when building the kernel and userland.
> >
> > The stize of the structure in question is computed
> > by both kernel and userland app using sizeof(),
> > so there is no assumption on the size of its members,
> > so i believe the only possibility of a mismatch is
> > the one above.
> >
> > Any ideas ?
>
> (Disclaimer: my solution below is untested, so it may all be bogus)
>
> No, you are not accounting for "external" structure padding. Take a
> look:
>
> struct ip_fw {
> struct ip_fw *next; /* linked list of rules */
> u_int16_t act_ofs; /* offset of action in 32-bit units */
> u_int16_t cmd_len; /* # of 32-bit words in cmd */
> u_int16_t rulenum; /* rule number */
> u_int16_t _pad; /* padding */
>
> /* These fields are present in all rules. */
> u_int64_t pcnt; /* Packet counter */
> u_int64_t bcnt; /* Byte counter */
> u_int32_t timestamp; /* tv_sec of last match */
>
> struct ip_fw *next_rule; /* ptr to next rule */
>
> ipfw_insn cmd[1]; /* storage for commands */
> };
>
> On a 64-bit architecture, pointers are obviously 8 bytes in size;
> structure members must or should be on natural borders, depending on
> the architecture.
> So, next_rule will not be on a natural border; 4 bytes of padding will
> be inserted before it. With that, the total structure size would be
> 52.
> The compiler must account for the fact that an array of struct ip_fws
> may be used. For obvious reasons, it can not just insert extra padding
> in the array case; instead, the structure size must be chosen so that
> in this situation, the first member will be on a natural border.
> This results in an extra 4 bytes of "external" padding at the end,
> after the member 'cmd'.
> The macro you use to compute the size in the kernel is:
>
> #define RULESIZE(rule) (sizeof(struct ip_fw) + \
> ((struct ip_fw *)(rule))->cmd_len * 4 - 4)
>
> In the userland code, you start at &foo.cmd and append data
> directly. This means that the padding will also be used to store
> data, so the '- 4' (= sizeof(foo.cmd)) will not always be enough. The
> following definition of RULESIZE (untested) should fix this:
>
> #define RULESIZE(rule) (offsetof(struct ip_fw, cmd) + \
> ((struct ip_fw *)(rule))->cmd_len * 4)
>
> It also removes the explicit 4 for sizeof(ipfw_insn).
>
> - thomas
>
> --
> Thomas Moestl <tmoestl@gmx.net> http://www.tu-bs.de/~y0015675/
> <tmm@FreeBSD.org> http://people.FreeBSD.org/~tmm/
> PGP fingerprint: 1C97 A604 2BD0 E492 51D0 9C0F 1FE6 4F1D 419C 776C
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020714134337.A78891>
