Index: libspe2/spebase/default_libea_handler.c =================================================================== --- /dev/null +++ libspe2/spebase/default_libea_handler.c @@ -0,0 +1,187 @@ +#define _GNU_SOURCE + +#include "default_libea_handler.h" +#include "handler_utils.h" +#include +#include +#include +#include +#include +#include +#include + +typedef union { + unsigned long long all64; + unsigned int by32[2]; +} addr64; + + +int (*default_libea_funcs[SPE_LIBEA_NR_OPCODES]) (char *, unsigned long) = { + [SPE_LIBEA_UNUSED] = NULL, + [SPE_LIBEA_CALLOC] = default_libea_handler_calloc, + [SPE_LIBEA_FREE] = default_libea_handler_free, + [SPE_LIBEA_MALLOC] = default_libea_handler_malloc, + [SPE_LIBEA_REALLOC] = default_libea_handler_realloc, +}; + +/** + * default_libea_handler_calloc + * @ls: base pointer to local store area. + * @opdata: LIBEA call opcode & data. + * + * LIBEA library operation, per: upcoming RFC based on POSIX,C99 + * implementing: + * + * void *calloc(size_t mnemb, size_t size); + * + * 'addr' (returned) is treated as a 64b EA pointer + * rather than LS offset. On powerpc32 ABI (which is ILP-32), this + * is handled as a 32b EA pointer. + */ +int default_libea_handler_calloc(char *ls, unsigned long opdata) +{ + DECL_2_ARGS(); + DECL_RET(); + size_t nmemb; + size_t size; + void* calloc_addr; + addr64 ret2; + + nmemb = (size_t) arg0->slot[0]; + size = (size_t) arg1->slot[0]; + + calloc_addr = calloc(nmemb, size); + + ret2.all64 = (unsigned long long) (unsigned long) calloc_addr; + + PUT_LS_RC(ret2.by32[0], ret2.by32[1], 0, errno); + return 0; + +} + +/** + * default_libea_handler_free + * @ls: base pointer to local store area. + * @opdata: LIBEA call opcode & data. + * + * LIBEA library operation, per: upcoming RFC based on POSIX,C99 + * implementing: + * + * void free(void* ptr); + * + * 'ptr' is treated as a 64b EA pointer + * rather than LS offset. On powerpc32 ABI (which is ILP-32), this + * is handled as a 32b EA pointer. + */ +int default_libea_handler_free(char *ls, unsigned long opdata) +{ + DECL_1_ARGS(); + addr64 ptr; + + ptr.by32[0] = arg0->slot[0]; + ptr.by32[1] = arg0->slot[1]; + + free((void *) ((unsigned long) ptr.all64)); + + return 0; + +} + +/** + * default_libea_handler_malloc + * @ls: base pointer to local store area. + * @opdata: LIBEA call opcode & data. + * + * LIBEA library operation, per: upcoming RFC based on POSIX,C99 + * implementing: + * + * void *malloc(size_t size); + * + * 'ret' (returned) is treated as a 64b EA pointer + * rather than LS offset. On powerpc32 ABI (which is ILP-32), this + * is handled as a 32b EA pointer. + */ +int default_libea_handler_malloc(char *ls, unsigned long opdata) +{ + DECL_1_ARGS(); + DECL_RET(); + size_t size; + void* malloc_addr; + addr64 ret2; + + size = (size_t) arg0->slot[0]; + + malloc_addr = malloc(size); + + ret2.all64 = (unsigned long long) (unsigned long) malloc_addr; + + PUT_LS_RC(ret2.by32[0], ret2.by32[1], 0, errno); + return 0; + +} + +/** + * default_libea_handler_realloc + * @ls: base pointer to local store area. + * @opdata: LIBEA call opcode & data. + * + * LIBEA library operation, per: upcoming RFC based on POSIX,C99 + * implementing: + * + * void *realloc(void* ptr, size_t size); + * + * 'ptr' and 'ret' (returned) are treated as 64b EA pointers + * rather than LS offsets. On powerpc32 ABI (which is ILP-32), this + * is handled as a 32b EA pointer. + */ +int default_libea_handler_realloc(char *ls, unsigned long opdata) +{ + DECL_2_ARGS(); + DECL_RET(); + addr64 ptr; + size_t size; + void* realloc_addr; + addr64 ret2; + + ptr.by32[0] = arg0->slot[0]; + ptr.by32[0] = arg0->slot[1]; + + size = (size_t) arg1->slot[0]; + + realloc_addr = realloc((void *) ((unsigned long)ptr.all64), size); + + ret2.all64 = (unsigned long long) (unsigned long) realloc_addr; + + PUT_LS_RC(ret2.by32[0], ret2.by32[1], 0, errno); + return 0; + +} + +/** + * default_libea_handler + * @ls: base pointer to local store area. + * @opdata: POSIX.1 call opcode & data. + * + * Default POSIX.1 call dispatch function. + */ +int default_libea_handler(char *base, unsigned long offset) +{ + int op, opdata; + + if (!base) { + DEBUG_PRINTF("%s: mmap LS required.\n", __func__); + return 1; + } + offset = (offset & LS_ADDR_MASK) & ~0x1; + opdata = *((int *)((char *) base + offset)); + op = SPE_LIBEA_OP(opdata); + if ((op <= 0) || (op >= SPE_LIBEA_NR_OPCODES)) { + DEBUG_PRINTF("%s: Unhandled type opdata=%08x op=%08x\n", __func__, + opdata, SPE_LIBEA_OP(opdata)); + return 1; + } + + default_libea_funcs[op] (base, opdata); + + return 0; +} Index: libspe2/spebase/default_libea_handler.h =================================================================== --- /dev/null +++ libspe2/spebase/default_libea_handler.h @@ -0,0 +1,23 @@ + +#define SPE_LIBEA_CLASS 0x2104 + +#define SPE_LIBEA_UNUSED 0x00 +#define SPE_LIBEA_CALLOC 0x01 +#define SPE_LIBEA_FREE 0x02 +#define SPE_LIBEA_MALLOC 0x03 +#define SPE_LIBEA_REALLOC 0x04 +#define SPE_LIBEA_NR_OPCODES 0x05 + +extern int default_libea_handler(char *ls, unsigned long args); +extern int default_libea_handler_calloc(char *ls, unsigned long args); +extern int default_libea_handler_free(char *ls, unsigned long args); +extern int default_libea_handler_malloc(char *ls, unsigned long args); +extern int default_libea_handler_realloc(char *ls, unsigned long args); + +#define SPE_LIBEA_OP_SHIFT 24 +#define SPE_LIBEA_OP_MASK 0xff +#define SPE_LIBEA_DATA_MASK 0xffffff +#define SPE_LIBEA_OP(_v) (((_v) >> SPE_LIBEA_OP_SHIFT) & SPE_LIBEA_OP_MASK) +#define SPE_LIBEA_DATA(_v) ((_v) & SPE_LIBEA_DATA_MASK) + + Index: libspe2/spebase/Makefile =================================================================== --- libspe2.orig/spebase/Makefile +++ libspe2/spebase/Makefile @@ -29,8 +29,8 @@ libspebase_SO := libspebase.so.${MAJOR_V libspebase_SONAME := libspebase.so.${MAJOR_VERSION} libspebase_OBJS := create.o elf_loader.o load.o run.o image.o lib_builtin.o \ - default_c99_handler.o default_posix1_handler.o dma.o mbox.o \ - accessors.o info.o + default_c99_handler.o default_posix1_handler.o default_libea_handler.o \ + dma.o mbox.o accessors.o info.o CFLAGS += -I.. CFLAGS += -D_ATFILE_SOURCE Index: libspe2/spebase/lib_builtin.c =================================================================== --- libspe2.orig/spebase/lib_builtin.c +++ libspe2/spebase/lib_builtin.c @@ -24,12 +24,13 @@ #include "lib_builtin.h" #include "default_c99_handler.h" #include "default_posix1_handler.h" +#include "default_libea_handler.h" /*Default SPE library call handlers for 21xx stop-and-signal. */ static void *handlers[] = { default_c99_handler, default_posix1_handler, - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,default_libea_handler ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,