1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-28 01:58:17 +03:00

r10737: Fix some alignment issues

(This used to be commit 2b4270a2e965eb5c6fe0b25d22d2977e60bb7d43)
This commit is contained in:
Jelmer Vernooij 2005-10-05 19:41:53 +00:00 committed by Gerald (Jerry) Carter
parent 4bbb584ff0
commit f72dee9e39
2 changed files with 70 additions and 43 deletions

View File

@ -27,6 +27,23 @@ sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); }
#TODO:
# - Add some security checks (array sizes, memory alloc == NULL, etc)
# - Don't add seperate _p and _d functions if there is no deferred data
# - [string]
# - subcontext()
# - DATA_BLOB
sub Align($$)
{
my ($a,$b) = @_;
# Only align if previous element was smaller then current one
if ($$a < $b) {
pidl "if (!prs_align_custom(ps, $b))";
pidl "\treturn False;";
pidl "";
}
$$a = $b;
}
sub DeclareArrayVariables
{
@ -50,12 +67,19 @@ sub DeclareArrayVariables
pidl "" if $output;
}
sub ParseElementLevelData($$$$$$)
sub ParseElementLevelData($$$$$$$)
{
my ($e,$l,$nl,$env,$varname,$what) = @_;
my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
my @args = ($e,$l,$varname,$what);
if (defined($e->{ALIGN})) {
Align($align, $e->{ALIGN});
} else {
# Default to 4
Align($align, 4);
}
# See if we need to add a level argument because we're parsing a union
foreach (@{$e->{LEVELS}}) {
push (@args, ParseExpr("level_$e->{NAME}", $env))
@ -69,9 +93,9 @@ sub ParseElementLevelData($$$$$$)
pidl "\treturn False;";
}
sub ParseElementLevelArray($$$$$$)
sub ParseElementLevelArray($$$$$$$)
{
my ($e,$l,$nl,$env,$varname,$what) = @_;
my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
if ($l->{IS_ZERO_TERMINATED}) {
fatal($e, "[string] attribute not supported for Samba3 yet");
@ -85,12 +109,14 @@ sub ParseElementLevelArray($$$$$$)
if ($what == PRIMITIVES) {
# Fetch headers
if ($l->{IS_CONFORMANT} and not $l->{IS_SURROUNDING}) {
Align($align, 4);
pidl "if (!prs_uint32(\"size_$e->{NAME}\", ps, depth, &" . ParseExpr("size_$e->{NAME}", $env) . "))";
pidl "\treturn False;";
pidl "";
}
if ($l->{IS_VARYING}) {
Align($align, 4);
pidl "if (!prs_uint32(\"offset_$e->{NAME}\", ps, depth, &" . ParseExpr("offset_$e->{NAME}", $env) . "))";
pidl "\treturn False;";
pidl "";
@ -115,26 +141,34 @@ sub ParseElementLevelArray($$$$$$)
my $i = "i_$e->{NAME}_$l->{LEVEL_INDEX}";
pidl "for ($i=0; $i<$len;$i++) {";
indent;
ParseElementLevel($e,$nl,$env,$varname."[$i]",$what);
ParseElementLevel($e,$nl,$env,$varname."[$i]",$what,$align);
deindent;
pidl "}";
}
sub ParseElementLevelSwitch($$$$$$)
sub ParseElementLevelSwitch($$$$$$$)
{
my ($e,$l,$nl,$env,$varname,$what) = @_;
my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
ParseElementLevel($e,$nl,$env,$varname,$what);
ParseElementLevel($e,$nl,$env,$varname,$what,$align);
}
sub ParseElementLevelPtr($$$$$$)
sub ParseElementLevelPtr($$$$$$$)
{
my ($e,$l,$nl,$env,$varname,$what) = @_;
my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
if ($what == PRIMITIVES) {
pidl "if (!prs_uint32(\"ptr_$e->{NAME}\", ps, depth, &" . ParseExpr("ptr_$e->{NAME}", $env) . "))";
pidl "\treturn False;";
pidl "";
if ($l->{POINTER_TYPE} eq "ref" and
$l->{LEVEL} eq "TOP") {
pidl "if (!" . ParseExpr("ptr_$e->{NAME}", $env) . ")";
pidl "\treturn False;";
pidl "";
} else {
Align($align, 4);
pidl "if (!prs_uint32(\"ptr_$e->{NAME}\", ps, depth, &" . ParseExpr("ptr_$e->{NAME}", $env) . "))";
pidl "\treturn False;";
pidl "";
}
}
if ($l->{POINTER_TYPE} eq "relative") {
@ -145,24 +179,25 @@ sub ParseElementLevelPtr($$$$$$)
if ($what == DEFERRED) {
pidl "if (" . ParseExpr("ptr_$e->{NAME}", $env) . ") {";
indent;
ParseElementLevel($e,$nl,$env,$varname,PRIMITIVES);
ParseElementLevel($e,$nl,$env,$varname,DEFERRED);
ParseElementLevel($e,$nl,$env,$varname,PRIMITIVES,$align);
ParseElementLevel($e,$nl,$env,$varname,DEFERRED,$align);
deindent;
pidl "}";
$$align = 0;
}
}
sub ParseElementLevelSubcontext($$$$$$)
sub ParseElementLevelSubcontext($$$$$$$)
{
my ($e,$l,$nl,$env,$varname,$what) = @_;
my ($e,$l,$nl,$env,$varname,$what,$align) = @_;
fatal($e, "subcontext() not supported for Samba 3");
#FIXME
}
sub ParseElementLevel($$$$$)
sub ParseElementLevel($$$$$$)
{
my ($e,$l,$env,$varname,$what) = @_;
my ($e,$l,$env,$varname,$what,$align) = @_;
{
DATA => \&ParseElementLevelData,
@ -170,14 +205,14 @@ sub ParseElementLevel($$$$$)
POINTER => \&ParseElementLevelPtr,
SWITCH => \&ParseElementLevelSwitch,
ARRAY => \&ParseElementLevelArray
}->{$l->{TYPE}}->($e,$l,GetNextLevel($e,$l),$env,$varname,$what);
}->{$l->{TYPE}}->($e,$l,GetNextLevel($e,$l),$env,$varname,$what,$align);
}
sub ParseElement($$$)
sub ParseElement($$$$)
{
my ($e,$env,$what) = @_;
my ($e,$env,$what,$align) = @_;
ParseElementLevel($e, $e->{LEVELS}[0], $env, ParseExpr($e->{NAME}, $env), $what);
ParseElementLevel($e, $e->{LEVELS}[0], $env, ParseExpr($e->{NAME}, $env), $what, $align);
}
sub InitLevel($$$$)
@ -264,9 +299,6 @@ sub ParseStruct($$$)
pidl "";
pidl "prs_debug(ps, depth, desc, \"$pfn\");";
pidl "depth++;";
pidl "if (!prs_align_custom(ps, $s->{ALIGN}))";
pidl "\treturn False;";
pidl "";
if ($s->{SURROUNDING_ELEMENT}) {
pidl "if (!prs_uint32(\"size_$s->{SURROUNDING_ELEMENT}->{NAME}\", ps, depth, &" . ParseExpr("size_$s->{SURROUNDING_ELEMENT}->{NAME}", $env) . "))";
@ -274,8 +306,9 @@ sub ParseStruct($$$)
pidl "";
}
my $align = 0;
foreach (@{$s->{ELEMENTS}}) {
ParseElement($_, $env, PRIMITIVES);
ParseElement($_, $env, PRIMITIVES, \$align);
pidl "";
}
@ -293,12 +326,10 @@ sub ParseStruct($$$)
pidl "";
pidl "prs_debug(ps, depth, desc, \"$dfn\");";
pidl "depth++;";
pidl "if (!prs_align_custom(ps, $s->{ALIGN}))";
pidl "\treturn False;";
pidl "";
$align = 0;
foreach (@{$s->{ELEMENTS}}) {
ParseElement($_, $env, DEFERRED);
ParseElement($_, $env, DEFERRED, \$align);
pidl "";
}
@ -344,9 +375,6 @@ sub ParseUnion($$$)
pidl "{";
indent;
DeclareArrayVariables($u->{ELEMENTS});
pidl "if (!prs_align_custom(ps, $u->{ALIGN}))";
pidl "\treturn False;";
pidl "";
if (has_property($u, "nodiscriminant")) {
pidl "if (!prs_uint32(\"switch_value\", ps, depth, &v->switch_value))";
@ -365,8 +393,8 @@ sub ParseUnion($$$)
if ($_->{TYPE} ne "EMPTY") {
pidl "depth++;";
my $env = UnionGenerateEnvElement($_);
ParseElement($_, $env, PRIMITIVES);
ParseElement($_, $env, DEFERRED);
my $align = 0;
ParseElement($_, $env, PRIMITIVES, \$align);
pidl "depth--;";
}
pidl "break;";
@ -385,9 +413,6 @@ sub ParseUnion($$$)
pidl "{";
indent;
DeclareArrayVariables($u->{ELEMENTS});
pidl "if (!prs_align_custom(ps, $u->{ALIGN}))";
pidl "\treturn False;";
pidl "";
pidl "switch (level) {";
indent;
@ -398,7 +423,8 @@ sub ParseUnion($$$)
if ($_->{TYPE} ne "EMPTY") {
pidl "depth++;";
my $env = UnionGenerateEnvElement($_);
ParseElement($_, $env, DEFERRED);
my $align = 0;
ParseElement($_, $env, DEFERRED, \$align);
pidl "depth--;";
}
pidl "break;";
@ -452,9 +478,10 @@ sub CreateFnDirection($$$$)
pidl "prs_debug(ps, depth, desc, \"$fn\");";
pidl "depth++;";
my $align = 0;
foreach (@$es) {
ParseElement($_, $env, PRIMITIVES);
ParseElement($_, $env, DEFERRED);
ParseElement($_, $env, PRIMITIVES, \$align);
ParseElement($_, $env, DEFERRED, \$align);
pidl "";
}

View File

@ -100,7 +100,7 @@ sub dissect_string($$$)
my $t = lc(decl_string($e));
return "prs_$t(True, \"$e->{NAME}\", ps, depth, &$n)";
return "smb_io_$t(\"$e->{NAME}\", &$n, 1, ps, depth)";
}
my $known_types =