Re: [PATCH v2 08/29] ktap: add bytecode reader(kernel/trace/ktap/kp_bcread.[c|h])

2014-03-30 Thread Jovi Zhangwei
On Mon, Mar 31, 2014 at 1:17 AM, Andi Kleen  wrote:
>> That's designed for portability initially, it means we can just run bytecode
>> without compile script file everywhere, especially when compilation  is
>> a heavily task for some embedded platform, even though ktap compilation
>> is extremely fast.
>>
>> I doubt maybe there will have this bytecode portability requirement in 
>> future?
>
> Portability should be on the source level.
>
>
That's fine, I will add one endianness flag in bytecode header, kernel
will reject
loading if find endianness doesn't match.

Thanks.

Jovi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 08/29] ktap: add bytecode reader(kernel/trace/ktap/kp_bcread.[c|h])

2014-03-30 Thread Andi Kleen
> That's designed for portability initially, it means we can just run bytecode
> without compile script file everywhere, especially when compilation  is
> a heavily task for some embedded platform, even though ktap compilation
> is extremely fast.
> 
> I doubt maybe there will have this bytecode portability requirement in future?

Portability should be on the source level.

-Andi

-- 
a...@linux.intel.com -- Speaking for myself only.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 08/29] ktap: add bytecode reader(kernel/trace/ktap/kp_bcread.[c|h])

2014-03-30 Thread Jovi Zhangwei
On Sun, Mar 30, 2014 at 10:47 AM, Andi Kleen  wrote:
>> +/* Read debug info of a prototype. */
>> +static void bcread_dbg(BCReadCtx *ctx, ktap_proto_t *pt, int sizedbg)
>> +{
>> + void *lineinfo = (void *)proto_lineinfo(pt);
>> +
>> + bcread_block(ctx, lineinfo, sizedbg);
>> + /* Swap lineinfo if the endianess differs. */
>
>
> Why does this care about endianness? Can't that be handled in the user
> space? And why would the user space create different endianness than
> the host is?
>
That's designed for portability initially, it means we can just run bytecode
without compile script file everywhere, especially when compilation  is
a heavily task for some embedded platform, even though ktap compilation
is extremely fast.

I doubt maybe there will have this bytecode portability requirement in future?

>> + for (i = 0; i < sizekgc; i++, kr++) {
>> + int tp = bcread_uint32(ctx);
>> + if (tp >= BCDUMP_KGC_STR) {
>
> The signedness handling all over this file is a scary.
> What happens if the user puts in negative values or near overflow
> values.
>
> Most likely a lot of these checks should be unsigned
> and need to be audited again (and ideally fuzzed too)
>
>> +
>> + /* Allocate prototype object and initialize its fields. */
>> + pt = (ktap_proto_t *)kp_obj_new(ctx->ks, (int)sizept);
>
> Error check?
>
> Lots of other similar cases.
>
I will take more check in kp_bcread.c file, will fix in next version.

Thanks.

Jovi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 08/29] ktap: add bytecode reader(kernel/trace/ktap/kp_bcread.[c|h])

2014-03-29 Thread Andi Kleen
> +/* Read debug info of a prototype. */
> +static void bcread_dbg(BCReadCtx *ctx, ktap_proto_t *pt, int sizedbg)
> +{
> + void *lineinfo = (void *)proto_lineinfo(pt);
> +
> + bcread_block(ctx, lineinfo, sizedbg);
> + /* Swap lineinfo if the endianess differs. */


Why does this care about endianness? Can't that be handled in the user
space? And why would the user space create different endianness than
the host is?

> + for (i = 0; i < sizekgc; i++, kr++) {
> + int tp = bcread_uint32(ctx);
> + if (tp >= BCDUMP_KGC_STR) {

The signedness handling all over this file is a scary.
What happens if the user puts in negative values or near overflow
values.

Most likely a lot of these checks should be unsigned
and need to be audited again (and ideally fuzzed too)

> +
> + /* Allocate prototype object and initialize its fields. */
> + pt = (ktap_proto_t *)kp_obj_new(ctx->ks, (int)sizept);

Error check?

Lots of other similar cases.


-Andi

-- 
a...@linux.intel.com -- Speaking for myself only.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 08/29] ktap: add bytecode reader(kernel/trace/ktap/kp_bcread.[c|h])

2014-03-29 Thread Jovi Zhangwei
Exposed function:
ktap_proto_t *kp_bcread(ktap_state_t *ks, unsigned char *buff, int len)

Function kp_bcread read bytecode from buff, and return
ktap top-level function prototype.

Signed-off-by: Jovi Zhangwei 
---
 kernel/trace/ktap/kp_bcread.c | 429 ++
 kernel/trace/ktap/kp_bcread.h |   6 +
 2 files changed, 435 insertions(+)
 create mode 100644 kernel/trace/ktap/kp_bcread.c
 create mode 100644 kernel/trace/ktap/kp_bcread.h

diff --git a/kernel/trace/ktap/kp_bcread.c b/kernel/trace/ktap/kp_bcread.c
new file mode 100644
index 000..b51b622
--- /dev/null
+++ b/kernel/trace/ktap/kp_bcread.c
@@ -0,0 +1,429 @@
+/*
+ * Bytecode reader.
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2014 Jovi Zhangwei .
+ *
+ * Adapted from luajit and lua interpreter.
+ * Copyright (C) 2005-2014 Mike Pall.
+ * Copyright (C) 1994-2008 Lua.org, PUC-Rio.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include 
+#include 
+#include 
+#include "ktap.h"
+#include "kp_obj.h"
+#include "kp_vm.h"
+#include "kp_str.h"
+#include "kp_tab.h"
+
+
+/* Context for bytecode reader. */
+typedef struct BCReadCtx {
+   ktap_state_t *ks;
+   int flags;
+   char *start;
+   char *p;
+   char *pe;
+   ktap_str_t *chunkname;
+   ktap_val_t *savetop;
+} BCReadCtx;
+
+
+#define bcread_flags(ctx)  (ctx)->flags
+#define bcread_swap(ctx) \
+   ((bcread_flags(ctx) & BCDUMP_F_BE) != KP_BE*BCDUMP_F_BE)
+#define bcread_oldtop(ctx) (ctx)->savetop
+#define bcread_savetop(ctx)(ctx)->savetop = (ctx)->ks->top;
+
+static inline uint32_t bswap(uint32_t x)
+{
+   return (uint32_t)__builtin_bswap32((int32_t)x);
+}
+
+/* -- Input buffer handling --- */
+
+/* Throw reader error. */
+static void bcread_error(BCReadCtx *ctx, ErrMsg em)
+{
+   kp_error(ctx->ks, "%s\n", err2msg(em));
+}
+
+/* Return memory block from buffer. */
+static inline uint8_t *bcread_mem(BCReadCtx *ctx, int len)
+{
+   uint8_t *p = (uint8_t *)ctx->p;
+   ctx->p += len;
+   kp_assert(ctx->p <= ctx->pe);
+   return p;
+}
+
+/* Copy memory block from buffer. */
+static void bcread_block(BCReadCtx *ctx, void *q, int len)
+{
+   memcpy(q, bcread_mem(ctx, len), len);
+}
+
+/* Read byte from buffer. */
+static inline uint32_t bcread_byte(BCReadCtx *ctx)
+{
+   kp_assert(ctx->p < ctx->pe);
+   return (uint32_t)(uint8_t)*ctx->p++;
+}
+
+/* Read ULEB128 value from buffer. */
+static inline uint32_t bcread_uint32(BCReadCtx *ctx)
+{
+   uint32_t v;
+   bcread_block(ctx, &v, sizeof(uint32_t));
+   kp_assert(ctx->p <= ctx->pe);
+   return v;
+}
+
+/* -- Bytecode reader - */
+
+/* Read debug info of a prototype. */
+static void bcread_dbg(BCReadCtx *ctx, ktap_proto_t *pt, int sizedbg)
+{
+   void *lineinfo = (void *)proto_lineinfo(pt);
+
+   bcread_block(ctx, lineinfo, sizedbg);
+   /* Swap lineinfo if the endianess differs. */
+   if (bcread_swap(ctx) && pt->numline >= 256) {
+   int i, n = pt->sizebc-1;
+   if (pt->numline < 65536) {
+   uint16_t *p = (uint16_t *)lineinfo;
+   for (i = 0; i < n; i++)
+   p[i] = (uint16_t)((p[i] >> 8)|(p[i] << 8));
+   } else {
+   uint32_t *p = (uint32_t *)lineinfo;
+   for (i = 0; i < n; i++)
+   p[i] = bswap(p[i]);
+   }
+   }
+}
+
+/* Find pointer to varinfo. */
+static const void *bcread_varinfo(ktap_proto_t *pt)
+{
+   const uint8_t *p = proto_uvinfo(pt);
+   int n = pt->sizeuv;
+   if (n)
+   while (*p++ || --n) ;
+   return p;
+}
+
+/* Read a single constant key/value of a template table. */
+static int bcread_ktabk(BCReadCtx *ctx, ktap_val_t *o)
+{
+   int tp = bcread_uint32(ctx);
+   if (tp >= BCDUMP_KTAB_STR) {
+   int len = tp - BCDUMP_KTAB_STR;
+   const char *p = (const char *)bcread_mem(ctx, len);
+   ktap_str_t *ts = kp_str_new(ctx->ks, p, len);
+   if (unlikely(!ts))
+   return -ENOMEM;
+
+   set_string(o, ts);
+   } else if (tp == BCDUMP_KTAB_NUM) {
+