diff options
Diffstat (limited to 'src/kbuffer-parse.c')
-rw-r--r-- | src/kbuffer-parse.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/src/kbuffer-parse.c b/src/kbuffer-parse.c index 7499950..390a789 100644 --- a/src/kbuffer-parse.c +++ b/src/kbuffer-parse.c @@ -6,6 +6,9 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdbool.h> + +#include <sys/utsname.h> #include "kbuffer.h" @@ -14,6 +17,9 @@ #define COMMIT_MASK ((1 << 27) - 1) +/* Absolute time stamps do not have the 5 MSB, take from the real time stamp */ +#define TS_MSB (0xf8ULL << 56) + enum { KBUFFER_FL_HOST_BIG_ENDIAN = (1<<0), KBUFFER_FL_BIG_ENDIAN = (1<<1), @@ -156,6 +162,24 @@ static int calc_index(struct kbuffer *kbuf, void *ptr) static int __next_event(struct kbuffer *kbuf); +/* + * Just because sizeof(long) is 4 bytes, doesn't mean the OS isn't + * 64bits + */ +static bool host_is_32bit(void) +{ + struct utsname buf; + int ret; + + ret = uname(&buf); + if (ret < 0) { + /* Oh well, just assume it is 32 bit */ + return true; + } + /* If the uname machine value contains 64, assume the kernel is 64 bit */ + return strstr(buf.machine, "64") == NULL; +} + /** * kbuffer_alloc - allocat a new kbuffer * @size; enum to denote size of word @@ -172,6 +196,10 @@ kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian) switch (size) { case KBUFFER_LSIZE_4: break; + case KBUFFER_LSIZE_SAME_AS_HOST: + if (sizeof(long) != 8 && host_is_32bit()) + break; + /* fallthrough */ case KBUFFER_LSIZE_8: flags |= KBUFFER_FL_LONG_8; break; @@ -181,6 +209,7 @@ kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian) switch (endian) { case KBUFFER_ENDIAN_LITTLE: + case KBUFFER_ENDIAN_SAME_AS_HOST: break; case KBUFFER_ENDIAN_BIG: flags |= KBUFFER_FL_BIG_ENDIAN; @@ -195,8 +224,11 @@ kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian) kbuf->flags = flags; - if (host_is_bigendian()) + if (host_is_bigendian()) { + if (endian == KBUFFER_ENDIAN_SAME_AS_HOST) + flags |= KBUFFER_FL_BIG_ENDIAN; kbuf->flags |= KBUFFER_FL_HOST_BIG_ENDIAN; + } if (do_swap(kbuf)) { kbuf->read_8 = __read_8_sw; @@ -347,7 +379,7 @@ static unsigned int translate_data(struct kbuffer *kbuf, void *data, void **rptr, unsigned long long *delta, int *length) { - unsigned long long extend; + unsigned long long extend, msb = 0; unsigned int type_len_ts; unsigned int type_len; @@ -362,13 +394,15 @@ translate_data(struct kbuffer *kbuf, void *data, void **rptr, *length = read_4(kbuf, data); break; - case KBUFFER_TYPE_TIME_EXTEND: case KBUFFER_TYPE_TIME_STAMP: + msb = kbuf->timestamp & TS_MSB; + /* fall through */ + case KBUFFER_TYPE_TIME_EXTEND: extend = read_4(kbuf, data); data += 4; extend <<= TS_SHIFT; extend += *delta; - *delta = extend; + *delta = extend | msb; *length = 0; break; |