Re: [PATCH v2 08/29] ktap: add bytecode reader(kernel/trace/ktap/kp_bcread.[c|h])
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])
> 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])
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])
> +/* 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])
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) { +