[Xcb] [PATCH v2] c_client.py: Add padding after full_sequence for certain XGE events.
Josh Triplett
josh at joshtriplett.org
Mon Dec 30 00:07:38 PST 2013
On Mon, Dec 30, 2013 at 12:03:19AM -0800, Kenneth Graunke wrote:
> On 12/29/2013 08:50 PM, Kenneth Graunke wrote:
> > With the advent of the Present extension, some events (such as
> > PresentCompleteNotify) now use native 64-bit types on the wire.
> >
> > For XGE events, we insert an extra "uint32_t full_sequence" field
> > immediately after the first 32 bytes of data. Normally, this causes the
> > subsequent fields to be shifted over by 4 bytes, and the structure to
> > grow in size by 4 bytes. Everything works fine.
> >
> > However, if event contains 64-bit extended fields, this may result in
> > the compiler adding an extra 4 bytes of padding so that those fields
> > remain properly aligned on 64-bit boundaries. This causes the structure
> > to grow by 8 bytes, not 4. Unfortunately, XCB doesn't realize this.
> > read_packet() fails to malloc enough memory to hold the event, and the
> > event processing code uses the wrong offsets.
> >
> > To correct this, we add an additional uint32_t field (called "pad_fs")
> > just after full_sequence.
> >
> > This breaks the ABI for 32-bit systems, but any affected code would have
> > been completely broken on 64-bit systems. Thus, it's unlikely that
> > anyone will be affected.
> >
> > v2: Check for /any/ extended fields where size == 8, not just the first.
> > Also, only look for fields whose type is classified as "simple" to
> > avoid triggering on struct fields whose size happens to add up to 8
> > (such as pairs of uint32_t values).
> >
> > Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> > ---
> > src/c_client.py | 8 ++++++++
> > 1 file changed, 8 insertions(+)
> >
> > Keith,
> >
> > You're right, of course - we have to look at all the extended fields,
> > not just the first one.
> >
> > With that fixed, this patch now affects:
> > - xcb_present_complete_notify_event_t (same as v1)
> > - xcb_present_redirect_notify_event_t (new in v2)
> >
> > diff --git a/src/c_client.py b/src/c_client.py
> > index 99fd307..937b4c7 100644
> > --- a/src/c_client.py
> > +++ b/src/c_client.py
> > @@ -2911,6 +2911,14 @@ def c_event(self, name):
> > full_sequence = Field(tcard32, tcard32.name, 'full_sequence', False, True, True)
> > idx = self.fields.index(field)
> > self.fields.insert(idx + 1, full_sequence)
> > +
> > + # If the event contains any 64-bit extended fields, they need
> > + # to remain aligned on a 64-bit boundary. Adding full_sequence
> > + # broke that; add an additional 32-bit pad to fix it.
> > + if True in (f.type.size == 8 and f.type.is_simple for f in self.fields[(idx+2):]):
> > + pad_fs = Field(tcard32, tcard32.name, 'pad_fs', False, True, True)
> > + self.fields.insert(idx + 2, pad_fs)
> > +
> > break
> >
> > _c_type_setup(self, name, ('event',))
> >
>
> Scratch this, I failed to account for the extra field when malloc'ing,
> so it doesn't actually fix the problem. I could've sworn I tested it,
> but apparently was still running a different version. Sorry for the noise.
For that matter, you're inserting padding even if it would turn out that
a subsequent 64-bit field is already properly aligned.
- Josh Triplett
More information about the Xcb
mailing list