From 0df502fd9da4e1895e1f3719afc51c8edd710c9e Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sat, 19 Nov 2011 11:22:05 -0500 Subject: [PATCH] Detect 32-bit compat applications + 32-bit warning fixes Signed-off-by: Mathieu Desnoyers --- hashtable/hash.c | 81 ++++++++++++++++++++++++++++++++-------- lttng-sessiond/main.c | 4 +- lttng-sessiond/ust-app.c | 18 ++++++++- lttng-sessiond/ust-app.h | 1 + 4 files changed, 86 insertions(+), 18 deletions(-) diff --git a/hashtable/hash.c b/hashtable/hash.c index a3a3152dc..cee40e6ea 100644 --- a/hashtable/hash.c +++ b/hashtable/hash.c @@ -1,6 +1,7 @@ /* * Copyright (C) - Bob Jenkins, May 2006, Public Domain. * Copyright (C) 2011 - David Goulet + * Copyright (C) 2011 - Mathieu Desnoyers * * These are functions for producing 32-bit hashes for hash table lookup. * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() are @@ -40,6 +41,7 @@ #include /* attempt to define endianness */ #include #include +#include /* * My best guess at if you are big-endian or little-endian. This may @@ -151,13 +153,49 @@ c ^= b; c -= rot(b,24); \ } +static __attribute__((unused)) +uint32_t hashword( + const uint32_t *k, /* the key, an array of uint32_t values */ + size_t length, /* the length of the key, in uint32_ts */ + uint32_t initval) /* the previous hash, or an arbitrary value */ +{ + uint32_t a, b, c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + (((uint32_t) length) << 2) + initval; + + /*----------------------------------------- handle most of the key */ + while (length > 3) { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a, b, c); + length -= 3; + k += 3; + } + + /*----------------------------------- handle the last 3 uint32_t's */ + switch (length) { /* all the case statements fall through */ + case 3: c += k[2]; + case 2: b += k[1]; + case 1: a += k[0]; + final(a, b, c); + case 0: /* case 0: nothing left to add */ + break; + } + /*---------------------------------------------- report the result */ + return c; +} + + /* * hashword2() -- same as hashword(), but take two seeds and return two 32-bit * values. pc and pb must both be nonnull, and *pc and *pb must both be * initialized with seeds. If you pass in (*pb)==0, the output (*pc) will be * the same as the return value from hashword(). */ -static void hashword2(const uint32_t *k, size_t length, +static __attribute__((unused)) +void hashword2(const uint32_t *k, size_t length, uint32_t *pc, uint32_t *pb) { uint32_t a, b, c; @@ -389,26 +427,39 @@ static uint32_t hashlittle(const void *key, size_t length, uint32_t initval) return c; } +#if (CAA_BITS_PER_LONG == 64) +/* + * Hash function for number value. + */ +unsigned long hash_key(void *_key, size_t length, unsigned long seed) +{ + union { + uint64_t v64; + uint32_t v32[2]; + } v; + union { + uint64_t v64; + uint32_t v32[2]; + } key; + + assert(length == sizeof(unsigned long)); + v.v64 = (uint64_t) seed; + key.v64 = (uint64_t) _key; + hashword2(key.v32, 2, &v.v32[0], &v.v32[1]); + return v.v64; +} +#else /* * Hash function for number value. */ unsigned long hash_key(void *_key, size_t length, unsigned long seed) { - union { - uint64_t v64; - uint32_t v32[2]; - } v; - union { - uint64_t v64; - uint32_t v32[2]; - } key; - - assert(length == sizeof(unsigned long)); - v.v64 = (uint64_t) seed; - key.v64 = (uint64_t) _key; - hashword2(key.v32, 2, &v.v32[0], &v.v32[1]); - return v.v64; + unsigned long key = (unsigned long) _key; + + assert(length == sizeof(unsigned long)); + return hashword(&key, 1, seed); } +#endif /* * Hash function for string. diff --git a/lttng-sessiond/main.c b/lttng-sessiond/main.c index 3651e6c3e..0acf230e0 100644 --- a/lttng-sessiond/main.c +++ b/lttng-sessiond/main.c @@ -2822,14 +2822,14 @@ static ssize_t cmd_list_channels(int domain, struct ltt_session *session, if (session->kernel_session != NULL) { nb_chan = session->kernel_session->channel_count; } - DBG3("Number of kernel channels %ld", nb_chan); + DBG3("Number of kernel channels %zd", nb_chan); break; case LTTNG_DOMAIN_UST: if (session->ust_session != NULL) { nb_chan = hashtable_get_count( session->ust_session->domain_global.channels); } - DBG3("Number of UST global channels %ld", nb_chan); + DBG3("Number of UST global channels %zd", nb_chan); break; default: *channels = NULL; diff --git a/lttng-sessiond/ust-app.c b/lttng-sessiond/ust-app.c index 356887026..e1d11cfbc 100644 --- a/lttng-sessiond/ust-app.c +++ b/lttng-sessiond/ust-app.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -827,12 +828,27 @@ error: * Using pid and uid (of the app), allocate a new ust_app struct and * add it to the global traceable app list. * - * On success, return 0, else return malloc ENOMEM. + * On success, return 0, else return malloc -ENOMEM, or -EINVAL if app + * bitness is not supported. */ int ust_app_register(struct ust_register_msg *msg, int sock) { struct ust_app *lta; + /* + * Currently support only tracing of application which share the + * same bitness as the consumer. Eventually implement dispatch + * to specific compat32 consumer. + */ + if (msg->bits_per_long != CAA_BITS_PER_LONG) { + ERR("Registration failed: application %s (pid: %d) has " + "%d-bit long, but only " + "%d-bit lttng-consumerd is available.\n", + msg->name, msg->pid, msg->bits_per_long, + CAA_BITS_PER_LONG); + return -EINVAL; + } + lta = zmalloc(sizeof(struct ust_app)); if (lta == NULL) { PERROR("malloc"); diff --git a/lttng-sessiond/ust-app.h b/lttng-sessiond/ust-app.h index e92458e2b..ce18bb2f7 100644 --- a/lttng-sessiond/ust-app.h +++ b/lttng-sessiond/ust-app.h @@ -38,6 +38,7 @@ struct ust_register_msg { pid_t ppid; uid_t uid; gid_t gid; + uint32_t bits_per_long; char name[16]; }; -- 2.34.1