If the size is not constant the array has to be allocated in some
way in the output and so there must be a specification for the
output (as default is write into the C structure all data).
The only exceptions are when the length is constant (in this case
a constant length array in the C structure is used) or a pointer
(in this case the pointer allocate the array).
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Victor Toso <victortoso@redhat.com>
This syntax was only used in protocol 1 which has been removed
time ago.
Beside not being used it's confusing and prone to errors,
array size is specified using 2 identifiers, one reporting
bytes and the other number of items, one used for marshalling,
the other for demarshalling.
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
We want to obsolete from enumeration values, currently CELT.
The removal of check in has_attr is not an issue, as the attributes
are already checked by fix_attributes calls.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Victor Toso <victortoso@redhat.com>
This rule remove possible integer overflows.
Current code generated is not affected by these integer overflows
as the computations are done using 64 bit but better safe then sorry.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Julien Rope <jrope@redhat.com>
Make sure that guard do no change building out-of-tree or
with Meson.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Uri Lublin <uril@redhat.com>
Check that combination of fields for an array does not
lead to unsafe code.
check_valid method came from generate_c_declaration with
some more check and it's use in demarshaller to validate
the array if the structure is not generated.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Victor Toso <victortoso@redhat.com>
Output attributes are the attributes that specify how to store
that field in the C structure.
There can be only one output type specified.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Victor Toso <victortoso@redhat.com>
This check make sure that output fields for member with @end (arrays)
are declared as empty arrays in output C structure.
This avoids output fields to be declared as pointer or other
invalid types.
The check is a compile time check so no code in object file
is generated.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Uri Lublin <uril@redhat.com>
Just style, they do the same thing, but is more coherent
with the rest of the code.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Uri Lublin <uril@redhat.com>
member = None is set before the if/else condition.
In the else code, when member is set it is checked
and if not-None it breaks out of the loop.
If the code is still in the loop for sure member is None.
Found by covscan.
Signed-off-by: Uri Lublin <uril@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
Allows to specify a @declare attribute for messages and structure
that can generate the needed C structures.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
The option is used to add a suffix to public functions, not a
prefix.
Currently the option is not used (it was used to generate protocol
1 code).
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
This option was used in protocol 1 to generate 64 bit pointers.
A pointer in the protocol is an offset in the current message.
This allows the possibility to have messages with pointers with more
than 4GB. This feature was removed and not used in protocol 2.
The reason this feature was correctly removed in protocol 2 is that
having 64 bit pointers in the protocol would require messages larger
than 4GB which would cause:
- huge latency as a single message would take more than 4 seconds
to be send in a 10Gb connection;
- huge memory requirements.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
Does not make sense to specify the same field to have 2
different C implementation at the same time.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
@ptr_array is supposed to change the destination to an array
of pointer to items. This for a raw buffer does not make sense
but check if user specifies this combination.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
c_type() method is supposed to return the type to use for
C structure field. But the name is not a C type but a
protocol name.
Return the type name of the aliased type (for instance
uint32_t for a uint32 type).
This does not change the generated code.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
Although on the platform we support size_t and uintptr_t are
the same, on some platform the size_t can (in theory) be smaller
than the necessary integer to store a pointer.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
Code generated for demarshallers define and declare some types and
functions.
However these types and functions are also declared separately in other
headers (currently spice-common/client_demarshallers.h and
spice/server/demarshallers.h) resulting in potential ABI mismatch if the
different declarations do not match.
Using a common header shared between generated code and code using
these functions prevent potentially multiple different declarations.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
The idea in version 1 of the protocol was to extend it using the minor
version. However this was replaced by the usage of capabilities and the
minor attribute (which was not much used in version 1) was abandoned in
version 2.
This patch create a big difference in the code generated but only because
the minor version was passed between all possible functions as argument.
Note that exported functions retain the minor argument for compatibility
reasons.
The demarshaller code export directly spice_get_client_channel_parser or
spice_get_server_channel_parser functions which returns internal module
functions which parse message of specific channels.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
This attribute was used only in SPICE version 1.
The intention was use fixed size for switch type in the protocol.
However this does not bring any improvement, just increase network
bytes used.
Generated code does not change.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
This attribute was used only in SPICE version 1.
Its usage was confusing, and was replaced by the simple usage of
array size.
Generated code does not change.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
If this attribute was specified during marshaller the field was
marshalled twice.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
Python 3 puts its .pyc files in a __pycache__ subdirectory, This commit
adds these to DISTCLEANFILES. My main motivation for doing this is so
that git.mk can then properly add them to .gitignore.
Acked-by: Victor Toso <victortoso@redhat.com>
In a comparison with current autotools build system, meson/ninja
provides a huge improvement in build speed, while keeping the same
functionalities currently available and being considered more user
friendly.
The new system coexists within the same repository with the current one,
so we can do more extensive testing of its functionality before deciding
if the old system can be removed, or for some reason, has to stay for
good.
- Meson: https://mesonbuild.com
This is the equivalent of autogen/configure step in autotools. It
generates the files that will be used by ninja to actually build the
source code.
The project has received lots of traction recently, with many GNOME
projects willing to move to this new build system. The following wiki
page has more details of the status of the many projects being ported:
https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting
Meson has a python-like syntax, easy to read, and the documentation
on the project is very complete, with a dedicated page on how to port
from autotools, explaining how most common use cases can be
implemented using meson.
http://mesonbuild.com/Porting-from-autotools.html
Other important sources of information:
http://mesonbuild.com/howtox.htmlhttp://mesonbuild.com/Syntax.htmlhttp://mesonbuild.com/Reference-manual.html
- Ninja: https://ninja-build.org
Ninja is the equivalent of make in an autotools setup, which actually
builds the source code. It has being used by large and complex
projects such as Google Chrome, Android and LLVM. There is not much to
say about ninja (other than it is much faster than make) because we
won't interact directly with it as much, as meson does the middle man
job here. The reasoning for creating ninja in the first place is
explained on the following post:
http://neugierig.org/software/chromium/notes/2011/02/ninja.html
Also its manual provides more in-depth information about the design
principles:
https://ninja-build.org/manual.html
- Basic workflow:
Meson package is available for most if not all distros, so, taking
Fedora as an example, we only need to run:
# dnf -y install meson ninja-build.
With Meson, building in-tree is not possible at all, so we need to
pass a directory as argument to meson where we want the build to be
done. This has the advantage of creating builds with different options
under the same parent directory, e.g.:
$ meson ./build --prefix=/usr
$ meson ./build-extra -Dextra-checks=true -Dalignment-checks=true
After configuration is done, we call ninja to actually do the build.
$ ninja -C ./build
$ ninja -C ./build install
Ninja defaults to parallel builds, and this can be changed with the -j
flag.
$ ninja -j 10 -C ./build
- Hacking:
* meson.build: Mandatory for the project root and usually found under
each directory you want something to be built.
* meson_options.txt: Options that can interfere with the result of the
build.
Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
Make sure there are not 2 messages with the same value in the
same channel.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
Make sure there are not 2 messages with the same name in the
same channel.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
Code that handled client and server messages check was the same, just
changed some variable names.
Instead use a class to store same information and reuse the code.
This allows easier extension of the 2 path of code.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Lukáš Hrázký <lhrazky@redhat.com>
Even though commit df4ec5c318 commented
out most of smartcard code which triggered this error, it still might
happen if a new message is added with an array member.
The reason is a missing declaration of mem_size, which is fixed simply
by checking if the attribute 'nocopy' is present.
The error log follows:
generated_server_demarshallers.c: In function ‘parse_msgc_smartcard_reader_add’:
generated_server_demarshallers.c:1985:30: error: ‘mem_size’ undeclared (first use in this function); did you mean ‘nw_size’?
data = (uint8_t *)malloc(mem_size);
^~~~~~~~
nw_size
This patch also updates test-marshallers so that this bug is triggered.
The diff between generated demarshallers with the patch applied follows:
--- tests/generated_test_demarshallers.c.old 2018-05-17 14:35:29.234056487 -0300
+++ tests/generated_test_demarshallers.c 2018-05-17 14:35:40.554031295 -0300
@@ -286,6 +286,7 @@ static uint8_t * parse_msg_main_ArrayMes
uint8_t *start = message_start;
uint8_t *data = NULL;
uint64_t nw_size;
+ uint64_t mem_size;
uint8_t *in, *end;
uint64_t name__nw_size;
uint64_t name__nelements;
@@ -298,6 +299,7 @@ static uint8_t * parse_msg_main_ArrayMes
}
nw_size = 0 + name__nw_size;
+ mem_size = sizeof(SpiceMsgMainArrayMessage);
/* Check if message fits in reported side */
if (nw_size > (uintptr_t) (message_end - start)) {
Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
Make code safe using both 32 and 64 bit machine.
Consider that this code can be compiled for machines with 32 bit.
There are some arrays length which are 32 bit.
If size_t this can cause easily an overflow. For instance message_len
sending SPICE_MSG_NOTIFY messages are 32 bit and code add a small
constant (currently 24) before doing the test for size. Now passing
(uint32_t) -20 as message_len would lead to a size of 4 after the
addition. This overflow does not happen on 64 bit machine as the length
is converted to size_t.
There are also some array length where some item are bigger than 1 byte.
For instance SPICE_MAIN_CHANNELS_LIST message have a number of channels
and each channel is composed by 2 bytes. Now the code generated try to do
length * 2 where length is still a 32 bit so if we put a value like
0x80000002u we get 4 as length. This will cause an overflow as code will
allocate very few bytes but try to fill with a huge number of elements.
This overflow happen in both 32 and 64 bit machine.
To avoid all these possible overflows this patch use only 64 bit for
nelements (number of elements), nw_size (network size) and mem_size
(memory size needed) checking the sizes to avoid other overflows
(like pointers conversions under 32 bit machines).
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe de Dinechin <dinechin@redhat.com>
When testing out some experimental protocol changes, I managed to
trigger the following error:
GEN generated_client_demarshallers.c
Traceback (most recent call last):
File "../../../spice-common/spice_codegen.py", line 267, in <module>
demarshal.write_protocol_parser(writer, proto, True)
File "/home/jjongsma/work/spice/spice-common/python_modules/demarshal.py", line 1270, in write_protocol_parser
parsers[channel.value] = (channel.channel_type, write_channel_parser(writer, channel.channel_type, is_server))
File "/home/jjongsma/work/spice/spice-common/python_modules/demarshal.py", line 1163, in write_channel_parser
func = write_msg_parser(helpers, ids[i].message_type)
File "/home/jjongsma/work/spice/spice-common/python_modules/demarshal.py", line 1061, in write_msg_parser
num_pointers = message.get_num_pointers()
File "/home/jjongsma/work/spice/spice-common/python_modules/ptypes.py", line 855, in get_num_pointers
count = count + m.get_num_pointers()
File "/home/jjongsma/work/spice/spice-common/python_modules/ptypes.py", line 662, in get_num_pointers
return self.member_type.get_num_pointers()
File "/home/jjongsma/work/spice/spice-common/python_modules/ptypes.py", line 507, in get_num_pointers
if self.is_constant_length(self):
TypeError: is_constant_length() takes exactly 1 argument (2 given)
Calling a member function will implicitly pass 'self' as the first
argument, but we were also explicitly passing it as an argument
(self.is_constant_length(self)). This resulted in the above error.
Acked-by: Lukáš Hrázký <lhrazky@redhat.com>
Instead of assuming that the system can safely do unaligned access
to memory use packed structures to allow the compiler generate
best code possible.
A packed structure tells the compiler to not leave padding inside it
and that the structure can be unaligned so any field can be unaligned
having to generate proper access code based on architecture.
For instance ARM7 can use unaligned access but not for 64 bit
numbers (currently these accesses are emulated by Linux kernel
with obvious performance consequences).
This changes the current methods from:
#ifdef WORDS_BIGENDIAN
#define read_uint32(ptr) ((uint32_t)SPICE_BYTESWAP32(*((uint32_t *)(ptr))))
#define write_uint32(ptr, val) *(uint32_t *)(ptr) = SPICE_BYTESWAP32((uint32_t)val)
#else
#define read_uint32(ptr) (*((uint32_t *)(ptr)))
#define write_uint32(ptr, val) (*((uint32_t *)(ptr))) = val
#endif
to:
#include <spice/start-packed.h>
typedef struct SPICE_ATTR_PACKED {
uint32_t v;
} uint32_unaligned_t;
#include <spice/end-packed.h>
#ifdef WORDS_BIGENDIAN
#define read_uint32(ptr) ((uint32_t)SPICE_BYTESWAP32(((uint32_unaligned_t *)(ptr))->v))
#define write_uint32(ptr, val) ((uint32_unaligned_t *)(ptr))->v = SPICE_BYTESWAP32((uint32_t)val)
#else
#define read_uint32(ptr) (((uint32_unaligned_t *)(ptr))->v)
#define write_uint32(ptr, val) (((uint32_unaligned_t *)(ptr))->v) = val
#endif
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
Python 2.6 does not have a flags parameter.
This is needed for RHEL 6.8.
Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit adds autogeneration of a generated_client_marshallers.h
header, which is then included in client_marshallers.h
This allows to remove the SpiceMessageMarshallers struct from this file,
which has to match what the generated code expects.
Acked-by: Frediano Ziglio <fziglio@redhat.com>
Until now, the same header guard was used for all generated .h files.
Now the header guard name is based on the name of the file being
generated so that it's different for each .h file.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
Not supported by code so trigger an error to avoid invalid usages
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>