From fc93b2bdc2ced1d46fefb91fe79391afded8e504 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 29 Sep 2010 21:02:13 -0400 Subject: [PATCH] Use statically known types, use hash for formats Signed-off-by: Mathieu Desnoyers --- formats/ctf/ctf.c | 52 +++++++++++++++++++++++ formats/ctf/types/bitfield.c | 78 ++++++++++++++++++++++++++++++++++ formats/ctf/types/float.c | 20 ++++----- formats/ctf/types/integer.c | 8 ++-- formats/registry.c | 69 ++++++++++++++++++++++++++++++ include/babeltrace/compiler.h | 8 ++++ include/babeltrace/ctf/types.h | 38 ++++++++--------- include/babeltrace/format.h | 67 +++++++++++++++++++++++++++++ include/babeltrace/types.h | 45 +++++++++++++++++++- types/integer.c | 44 +++++++++++++++++++ types/types.c | 12 ------ 11 files changed, 394 insertions(+), 47 deletions(-) create mode 100644 formats/ctf/ctf.c create mode 100644 formats/ctf/types/bitfield.c create mode 100644 formats/registry.c create mode 100644 include/babeltrace/format.h create mode 100644 types/integer.c diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c new file mode 100644 index 00000000..d128b9ac --- /dev/null +++ b/formats/ctf/ctf.c @@ -0,0 +1,52 @@ +/* + * BabelTrace - Common Trace Format (CTF) + * + * Format registration. + * + * Copyright (c) 2010 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +void __attribute__((constructor)) ctf_init(void); + +static const struct format ctf_format = { + .uint_read = ctf_uint_read, + .int_read = ctf_int_read, + .uint_write = ctf_uint_write, + .int_write = ctf_int_write, + .bitfield_unsigned_read = ctf_bitfield_unsigned_read, + .bitfield_signed_read = ctf_bitfield_signed_read, + .bitfield_unsigned_write = ctf_bitfield_unsigned_write, + .bitfield_signed_write = ctf_bitfield_signed_write, + .float_copy = ctf_float_copy, + .string_copy = ctf_string_copy, + .enum_uint_to_quark = ctf_enum_uint_to_quark, + .enum_int_to_quark = ctf_enum_int_to_quark, + .enum_quark_to_uint = ctf_enum_quark_to_uint, + .enum_quark_to_int = ctf_enum_quark_to_int, +}; + +void ctf_init(void) +{ + int ret; + + ctf_format->name = g_quark_from_static_string("ctf"); + ret = bt_register_format(&ctf_format); + assert(!ret); +} diff --git a/formats/ctf/types/bitfield.c b/formats/ctf/types/bitfield.c new file mode 100644 index 00000000..38c8b884 --- /dev/null +++ b/formats/ctf/types/bitfield.c @@ -0,0 +1,78 @@ +/* + * Common Trace Format + * + * Bitfields read/write functions. + * + * Copyright (c) 2010 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +uint64_t ctf_bitfield_unsigned_read(const unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order) +{ + uint64_t v; + + if (byte_order == LITTLE_ENDIAN) + ctf_bitfield_read_le(ptr, start, len, &v); + else + ctf_bitfield_read_be(ptr, start, len, &v); + return v; +} + +int64_t ctf_bitfield_signed_read(const unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order) +{ + int64_t v; + + if (byte_order == LITTLE_ENDIAN) + ctf_bitfield_read_le(ptr, start, len, &v); + else + ctf_bitfield_read_be(ptr, start, len, &v); + return v; +} + +size_t ctf_bitfield_unsigned_write(unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order, uint64_t v) +{ + if (!ptr) + goto end; + if (byte_order == LITTLE_ENDIAN) + ctf_bitfield_write_le(ptr, start, len, v); + else + ctf_bitfield_write_be(ptr, start, len, v); +end: + return len; +} + +size_t ctf_bitfield_signed_write(unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order, int64_t v) +{ + if (!ptr) + goto end; + if (byte_order == LITTLE_ENDIAN) + ctf_bitfield_write_le(ptr, start, len, v); + else + ctf_bitfield_write_be(ptr, start, len, v); +end: + return len; +} diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c index ce094747..db753dfb 100644 --- a/formats/ctf/types/float.c +++ b/formats/ctf/types/float.c @@ -72,8 +72,8 @@ struct pos_len { size_t sign_start, exp_start, mantissa_start, len; }; -void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest, - const unsigned char *src, const struct ctf_float *src) +void ctf_float_copy(unsigned char *destp, const struct type_class_float *dest, + const unsigned char *src, const struct type_class_float *src) { struct pos_len destpos, srcpos; union { @@ -81,8 +81,8 @@ void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest, long long s; } tmp; - destpos.len = dest.exp_len + dest.mantissa_len; - if (dest.byte_order == LITTLE_ENDIAN) { + destpos.len = dest->exp_len + dest->mantissa_len; + if (dest->byte_order == LITTLE_ENDIAN) { destpos.sign_start = destpos.len - 1; destpos.exp_start = destpos.sign_start - dest->exp_len; destpos.mantissa_start = 0; @@ -92,8 +92,8 @@ void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest, destpos.mantissa_start = destpos.exp_start + dest->exp_len; } - srcpos.len = src.exp_len + src.mantissa_len; - if (src.byte_order == LITTLE_ENDIAN) { + srcpos.len = src->exp_len + src->mantissa_len; + if (src->byte_order == LITTLE_ENDIAN) { srcpos.sign_start = srcpos.len - 1; srcpos.exp_start = srcpos.sign_start - src->exp_len; srcpos.mantissa_start = 0; @@ -124,7 +124,7 @@ void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest, dest->byte_order, tmp.s); } -double ctf_double_read(const unsigned char *ptr, const struct ctf_float *src) +double ctf_double_read(const unsigned char *ptr, const struct type_class_float *src) { union doubleIEEE754 u; struct ctf_float dest = { @@ -137,7 +137,7 @@ double ctf_double_read(const unsigned char *ptr, const struct ctf_float *src) return u.v; } -size_t ctf_double_write(unsigned char *ptr, const struct ctf_float *dest, +size_t ctf_double_write(unsigned char *ptr, const struct type_class_float *dest, double v) { union doubleIEEE754 u; @@ -156,7 +156,7 @@ end: } long double ctf_ldouble_read(const unsigned char *ptr, - const struct ctf_float *src) + const struct type_class_float *src) { union ldoubleIEEE754 u; struct ctf_float dest = { @@ -169,7 +169,7 @@ long double ctf_ldouble_read(const unsigned char *ptr, return u.v; } -size_t ctf_ldouble_write(unsigned char *ptr, const struct ctf_float *dest, +size_t ctf_ldouble_write(unsigned char *ptr, const struct type_class_float *dest, long double v) { union ldoubleIEEE754 u; diff --git a/formats/ctf/types/integer.c b/formats/ctf/types/integer.c index cd81b17a..316a0888 100644 --- a/formats/ctf/types/integer.c +++ b/formats/ctf/types/integer.c @@ -25,7 +25,7 @@ #include #include -uint64_t uint_read(const uint8_t *ptr, size_t len, int byte_order) +uint64_t ctf_uint_read(const uint8_t *ptr, size_t len, int byte_order) { int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */ @@ -63,7 +63,7 @@ uint64_t uint_read(const uint8_t *ptr, size_t len, int byte_order) } } -int64_t int_read(const uint8_t *ptr, size_t len, int byte_order) +int64_t ctf_int_read(const uint8_t *ptr, size_t len, int byte_order) { int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */ @@ -101,7 +101,7 @@ int64_t int_read(const uint8_t *ptr, size_t len, int byte_order) } } -size_t uint_write(uint8_t *ptr, size_t len, int byte_order, uint64_t v) +size_t ctf_uint_write(uint8_t *ptr, size_t len, int byte_order, uint64_t v) { int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */ @@ -129,7 +129,7 @@ end: return len; } -size_t int_write(uint8_t *ptr, size_t len, int byte_order, int64_t v) +size_t ctf_int_write(uint8_t *ptr, size_t len, int byte_order, int64_t v) { int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */ diff --git a/formats/registry.c b/formats/registry.c new file mode 100644 index 00000000..83e0aa0e --- /dev/null +++ b/formats/registry.c @@ -0,0 +1,69 @@ +/* + * BabelTrace + * + * Format Registry + * + * Copyright (c) 2010 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +static int init_done; +void __attribute__((constructor)) format_init(void); +void __attribute__((destructor)) format_finalize(void); + +/* + * Format registry hash table contains the registered formats. Format + * registration is typically performed by a format plugin. + * TODO: support plugin unload (unregistration of formats). + */ +GHashTable *format_registry; + +struct format *bt_lookup_format(GQuark qname) +{ + if (!init_done) + return NULL; + return g_hash_table_lookup(format_registry, + (gconstpointer) (unsigned long) qname) +} + +int bt_register_format(const struct format *format) +{ + if (!init_done) + format_init(); + + if (bt_lookup_format(qname)) + return -EEXIST; + + g_hash_table_insert(format_registry, + (gconstpointer) (unsigned long) format->name, + format); + return 0; +} + +void format_init(void) +{ + format_registry = g_hash_table_new(g_direct_hash, g_direct_equal); + assert(format_registry); + init_done = 1; +} + +int format_finalize(void) +{ + g_hash_table_destroy(format_registry); +} diff --git a/include/babeltrace/compiler.h b/include/babeltrace/compiler.h index 7850ded6..c8bb4db5 100644 --- a/include/babeltrace/compiler.h +++ b/include/babeltrace/compiler.h @@ -3,4 +3,12 @@ #define MAYBE_BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2 * !!(cond)])) +#ifndef container_of +#define container_of(ptr, type, member) \ + ({ \ + const typeof(((type *)NULL)->member) * __ptr = (ptr); \ + (type *)((char *)__ptr - offsetof(type, member)); \ + }) +#endif + #endif /* _BABELTRACE_COMPILER_H */ diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h index 276152db..894dda24 100644 --- a/include/babeltrace/ctf/types.h +++ b/include/babeltrace/ctf/types.h @@ -40,30 +40,28 @@ int64_t ctf_int_read(const unsigned char *ptr, int byte_order, size_t len); size_t ctf_uint_write(unsigned char *ptr, int byte_order, size_t len, uint64_t v); size_t ctf_int_write(unsigned char *ptr, int byte_order, size_t len, int64_t v); -/* - * ctf-types-bitfield.h declares: - * - * ctf_bitfield_unsigned_read - * ctf_bitfield_signed_read - * ctf_bitfield_unsigned_write - * ctf_bitfield_signed_write - */ -#include +uint64_t ctf_bitfield_unsigned_read(const unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order); +int64_t ctf_bitfield_signed_read(const unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order); +size_t ctf_bitfield_unsigned_write(unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order, uint64_t v); +size_t ctf_bitfield_signed_write(unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order, int64_t v); -double ctf_double_read(const unsigned char *ptr, const struct ctf_float *src) -size_t ctf_double_write(unsigned char *ptr, const struct ctf_float *dest, +double ctf_double_read(const unsigned char *ptr, const struct type_class_float *src) +size_t ctf_double_write(unsigned char *ptr, const struct type_class_float *dest, double v); long double ctf_ldouble_read(const unsigned char *ptr, - const struct ctf_float *src) -size_t ctf_ldouble_write(unsigned char *ptr, const struct ctf_float *dest, + const struct type_class_float *src) +size_t ctf_ldouble_write(unsigned char *ptr, const struct type_class_float *dest, long double v); -struct ctf_float { - size_t exp_len; - size_t mantissa_len; /* Including sign bit */ - int byte_order; -}; -void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest, - const unsigned char *srcp, const struct ctf_float *src); +void ctf_float_copy(unsigned char *destp, const struct type_class_float *dest, + const unsigned char *srcp, const struct type_class_float *src); size_t ctf_string_copy(unsigned char *dest, const unsigned char *src); diff --git a/include/babeltrace/format.h b/include/babeltrace/format.h new file mode 100644 index 00000000..4981f122 --- /dev/null +++ b/include/babeltrace/format.h @@ -0,0 +1,67 @@ +#ifndef _BABELTRACE_FORMAT_H +#define _BABELTRACE_FORMAT_H + +/* + * BabelTrace + * + * Trace Format Header + * + * Copyright (c) 2010 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +struct format { + GQuark name; + + uint64_t (*uint_read)(const uint8_t *ptr, size_t len, int byte_order); + int64_t (*int_read)(const uint8_t *ptr, size_t len, int byte_order); + size_t (*uint_write)(uint8_t *ptr, size_t len, int byte_order, uint64_t v); + size_t (*int_write)(uint8_t *ptr, size_t len, int byte_order, int64_t v); + + uint64_t (*bitfield_unsigned_read)(const unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order); + int64_t (*bitfield_signed_read)(const unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order); + size_t (*bitfield_unsigned_write)(unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order, uint64_t v); + size_t (*bitfield_signed_write)(unsigned char *ptr, + unsigned long start, unsigned long len, + int byte_order, int64_t v); + + + void (*float_copy)(unsigned char *destp, const struct type_class_float *dest, + const unsigned char *srcp, const struct type_class_float *src); + + size_t (*string_copy)(unsigned char *dest, const unsigned char *src); + + GQuark (*enum_uint_to_quark)(const struct enum_table *table, uint64_t v); + GQuark (*enum_int_to_quark)(const struct enum_table *table, uint64_t v); + uint64_t (*enum_quark_to_uint)(size_t len, int byte_order, GQuark q); + int64_t (*enum_quark_to_int)(size_t len, int byte_order, GQuark q); +}; + +struct format *bt_lookup_format(GQuark qname); +int bt_register_format(const struct format *format); + +/* TBD: format unregistration */ + +#endif /* _BABELTRACE_FORMAT_H */ diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 23fec0fc..f8c3c8aa 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -4,7 +4,7 @@ /* * BabelTrace * - * Type header + * Type Header * * Copyright (c) 2010 Mathieu Desnoyers * @@ -23,4 +23,47 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + +struct type_class { + GQuark name; /* type name */ + size_t alignment; /* type alignment, in bits */ + /* + * Type copy function. Knows how to find the child type_class from the + * parent type_class. + */ + size_t (*copy)(unsigned char *dest, const struct format *fdest, + const unsigned char *src, const struct format *fsrc, + const struct type_class *type_class); +}; + +struct type_class_integer { + struct type_class p; + size_t len; /* length, in bits. */ + int byte_order; /* byte order */ + int signedness; +}; + +struct type_class_bitfield { + struct type_class_integer p; + size_t start_offset; /* offset from base address, in bits */ +}; + +struct type_class_float { + struct type_class p; + size_t mantissa_len; + size_t exp_len; + int byte_order; +}; + +struct type_class_enum { + struct type_class_bitfield; /* inherit from bitfield */ + struct enum_table *table; +}; + +struct type_class_struct { + struct type_class p; + /* TODO */ +}; + #endif /* _BABELTRACE_TYPES_H */ diff --git a/types/integer.c b/types/integer.c new file mode 100644 index 00000000..9b92ce35 --- /dev/null +++ b/types/integer.c @@ -0,0 +1,44 @@ +/* + * BabelTrace - Integer Type Converter + * + * Copyright (c) 2010 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +size_t copy_integer(unsigned char *dest, const struct format *fdest, + const unsigned char *src, const struct format *fsrc, + const struct type_class *type_class) +{ + struct type_class_integer *int_class = + container_of(type_class, struct type_class_integer, p); + + if (!int_class->signedness) { + uint64_t v; + + v = fsrc->uint_read(src, int_class->byte_order, int_class->len); + return fdest->uint_write(dest, int_class->byte_order, + int_class->len, v); + } else { + int64_t v; + + v = fsrc->int_read(src, int_class->byte_order, int_class->len); + return fdest->int_write(dest, int_class->byte_order, + int_class->len, v); + } +} diff --git a/types/types.c b/types/types.c index 28242d23..7aeb74aa 100644 --- a/types/types.c +++ b/types/types.c @@ -24,18 +24,6 @@ #include #include -struct type_class { - GQuark qname; - void (*read)(); - size_t (*write)(); -}; - -struct type { - struct type_class *class; - size_t alignment; /* type alignment, in bits */ - ssize_t len; /* type length, in bits. -1 for dynamic size. */ -}; - /* * Type class hash table contains the registered type classes. Type class * registration is typically performed by a plugin. -- 2.34.1