diff options
author | Andrew Tridgell <tridge@samba.org> | 2003-11-11 06:53:12 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2003-11-11 06:53:12 +0000 |
commit | 023a8fcb80f13f06c32ad5515e046b2017eaed09 (patch) | |
tree | 9f093329cd88704563e341f9f02f9198845c2692 /source4 | |
parent | bde602b9e1192945d7c0139fd4226b431fc214f2 (diff) | |
download | samba-023a8fcb80f13f06c32ad5515e046b2017eaed09.tar.gz samba-023a8fcb80f13f06c32ad5515e046b2017eaed09.tar.bz2 samba-023a8fcb80f13f06c32ad5515e046b2017eaed09.zip |
fixed the NDR structure alignment rules
still not perfect, but works for all the cases I have seen so far
(This used to be commit ce15cc87fbbe8ee0d383ad115168e9be29fe9efc)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/build/pidl/parser.pm | 22 | ||||
-rw-r--r-- | source4/build/pidl/util.pm | 24 |
2 files changed, 45 insertions, 1 deletions
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm index 14314886dc..90a1998a50 100644 --- a/source4/build/pidl/parser.pm +++ b/source4/build/pidl/parser.pm @@ -56,6 +56,20 @@ sub find_size_var($$) ##################################################################### +# work out the correct alignment for a structure +sub struct_alignment($) +{ + my $s = shift; + my $align = 1; + for my $e (@{$s->{ELEMENTS}}) { + if ($align < util::type_align($e)) { + $align = util::type_align($e); + } + } + return $align; +} + +##################################################################### # parse an array - push side sub ParseArrayPush($$) { @@ -312,11 +326,14 @@ sub ParseStructPush($) $res .= "\tndr_push_save(ndr, &_save1);\n"; } + my $align = struct_alignment($struct); + $res .= "\tNDR_CHECK(ndr_push_align(ndr, $align));\n"; + $res .= "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; foreach my $e (@{$struct->{ELEMENTS}}) { if (defined($struct_len) && $e == $struct_len) { - $res .= "\tNDR_CHECK(ndr_push_align_$e->{TYPE}(ndr));\n"; + $res .= "\tNDR_CHECK(ndr_push_align(ndr, sizeof($e->{TYPE})));\n"; $res .= "\tndr_push_save(ndr, &_save2);\n"; } ParseElementPushScalar($e, "r->", "NDR_SCALARS"); @@ -394,6 +411,9 @@ sub ParseStructPull($) $res .= "\tndr_pull_save(ndr, &_save);\n"; } + my $align = struct_alignment($struct); + $res .= "\tNDR_CHECK(ndr_pull_align(ndr, $align));\n"; + $res .= "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; foreach my $e (@{$struct->{ELEMENTS}}) { ParseElementPullScalar($e, "r->", "NDR_SCALARS"); diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm index 72176abab3..d6c493398c 100644 --- a/source4/build/pidl/util.pm +++ b/source4/build/pidl/util.pm @@ -187,6 +187,30 @@ sub is_scalar_type($) return 0; } +# return the NDR alignment for a type +sub type_align($) +{ + my($e) = shift; + my $type = $e->{TYPE}; + + if ($e->{POINTERS} || array_size($e)) { + # FIXME: we really should recurse here + return 4; + } + + return 4, if ($type eq "uint32"); + return 4, if ($type eq "long"); + return 2, if ($type eq "short"); + return 1, if ($type eq "char"); + return 1, if ($type eq "uint8"); + return 2, if ($type eq "uint16"); + return 4, if ($type eq "NTTIME"); + return 8, if ($type eq "hyper"); + return 2, if ($type eq "wchar_t"); + + return 0; +} + # this is used to determine if the ndr push/pull functions will need # a ndr_flags field to split by buffers/scalars sub is_builtin_type($) |