From 5e84eb9a475a10410b6ad56c029ef1023fa44d9c Mon Sep 17 00:00:00 2001 From: Dan Hipschman Date: Thu, 13 Sep 2007 18:04:32 -0700 Subject: [PATCH] widl: Add padding to the end of complex structures. --- dlls/rpcrt4/tests/server.c | 11 +++++++++++ dlls/rpcrt4/tests/server.idl | 8 ++++++++ tools/widl/parser.y | 3 +++ tools/widl/typegen.c | 36 ++++++++++++++++++++++++++++++++++++ tools/widl/typegen.h | 1 + 5 files changed, 59 insertions(+) diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index cd214682926..879e0d10c3b 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -344,6 +344,12 @@ s_sum_aligns(aligns_t *a) return a->c + a->i + a->s + a->d; } +int +s_sum_padded(padded_t *p) +{ + return p->i + p->c; +} + void s_stop(void) { @@ -392,6 +398,7 @@ basic_tests(void) static aligns_t aligns = {3, 4, 5, 6.0}; pints_t pints; ptypes_t ptypes; + padded_t padded; int i1, i2, i3, *pi2, *pi3, **ppi3; double u, v; float s, t; @@ -465,6 +472,10 @@ basic_tests(void) ok(enum_ord(E4) == 4, "RPC enum_ord\n"); ok(sum_aligns(&aligns) == 18.0, "RPC sum_aligns\n"); + + padded.i = -3; + padded.c = 8; + ok(sum_padded(&padded) == 5, "RPC sum_padded\n"); } static void diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl index 3ee40ae45ba..d84637c0898 100644 --- a/dlls/rpcrt4/tests/server.idl +++ b/dlls/rpcrt4/tests/server.idl @@ -200,5 +200,13 @@ interface IServer double sum_aligns(aligns_t *a); + typedef struct + { + int i; + char c; + } padded_t; + + int sum_padded(padded_t *p); + void stop(void); } diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 5b4c5ff860c..5d99c5a70fc 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -1679,6 +1679,9 @@ static int get_struct_type(var_list_t *fields) int has_variance = 0; var_t *field; + if (get_padding(fields)) + return RPC_FC_BOGUS_STRUCT; + if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry ) { type_t *t = field->type; diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index f0c298baf07..02b2cbcf6a6 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -726,6 +726,29 @@ static size_t union_memsize(const var_list_t *fields, unsigned int *pmaxa) return maxs; } +int get_padding(const var_list_t *fields) +{ + unsigned short offset = 0; + int salign = -1; + const var_t *f; + + if (!fields) + return 0; + + LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry) + { + type_t *ft = f->type; + unsigned int align = 0; + size_t size = type_memsize(ft, &align); + if (salign == -1) + salign = align; + offset = (offset + (align - 1)) & ~(align - 1); + offset += size; + } + + return ((offset + (salign - 1)) & ~(salign - 1)) - offset; +} + size_t type_memsize(const type_t *t, unsigned int *align) { size_t size = 0; @@ -1518,6 +1541,8 @@ static void write_struct_members(FILE *file, const type_t *type, { const var_t *field; unsigned short offset = 0; + int salign = -1; + int padding; if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) { @@ -1526,6 +1551,8 @@ static void write_struct_members(FILE *file, const type_t *type, { unsigned int align = 0; size_t size = type_memsize(ft, &align); + if (salign == -1) + salign = align; if ((align - 1) & offset) { unsigned char fc = 0; @@ -1549,6 +1576,15 @@ static void write_struct_members(FILE *file, const type_t *type, } } + padding = ((offset + (salign - 1)) & ~(salign - 1)) - offset; + if (padding) + { + print_file(file, 2, "0x%x,\t/* FC_STRUCTPAD%d */\n", + RPC_FC_STRUCTPAD1 + padding - 1, + padding); + *typestring_offset += 1; + } + write_end(file, typestring_offset); } diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h index eefecd79e8f..448e5035180 100644 --- a/tools/widl/typegen.h +++ b/tools/widl/typegen.h @@ -55,3 +55,4 @@ size_t type_memsize(const type_t *t, unsigned int *align); int decl_indirect(const type_t *t); void write_parameters_init(FILE *file, int indent, const func_t *func); void print(FILE *file, int indent, const char *format, va_list ap); +int get_padding(const var_list_t *fields); -- 2.11.4.GIT