diff options
author | Luo Xionghu <xionghu.luo@intel.com> | 2015-10-21 08:43:32 +0800 |
---|---|---|
committer | Yang Rong <rong.r.yang@intel.com> | 2015-10-21 16:04:51 +0800 |
commit | fd557c8c7c6c983bedada014d767cba8740e4549 (patch) | |
tree | dcb32323699ed1214d6cb7885e285bce95f0e176 /src | |
parent | 5796f4201597574d1f3ebf1d6a526d4e3787bc43 (diff) |
use table to define and query binary headers.
currently, we support create program from 4 types of binary: SPIR(BITCODE),
LLVM Compiled Object, LLVM Library and GEN Binary. The detailed formats are
listed in code.
also use table to match or fill gen binary header in backend.
v2: use enum to replace the magic number.
Signed-off-by: Luo Xionghu <xionghu.luo@intel.com>
Reviewed-by: Guo, Yejun <yejun.guo@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/cl_program.c | 57 | ||||
-rw-r--r-- | src/cl_program.h | 8 |
2 files changed, 39 insertions, 26 deletions
diff --git a/src/cl_program.c b/src/cl_program.c index 55c1ee86..98b6d51b 100644 --- a/src/cl_program.c +++ b/src/cl_program.c @@ -166,29 +166,30 @@ error: return err; } -inline cl_bool isBitcodeWrapper(const unsigned char *BufPtr, const unsigned char *BufEnd) -{ - // See if you can find the hidden message in the magic bytes :-). - // (Hint: it's a little-endian encoding.) - return BufPtr != BufEnd && - BufPtr[0] == 0xDE && - BufPtr[1] == 0xC0 && - BufPtr[2] == 0x17 && - BufPtr[3] == 0x0B; -} +#define BINARY_HEADER_LENGTH 5 -inline cl_bool isRawBitcode(const unsigned char *BufPtr, const unsigned char *BufEnd) +static const unsigned char binary_type_header[BHI_MAX][BINARY_HEADER_LENGTH]= \ + {{'B','C', 0xC0, 0xDE}, + {1, 'B', 'C', 0xC0, 0xDE}, + {2, 'B', 'C', 0xC0, 0xDE}, + {0, 'G','E', 'N', 'C'}}; + +LOCAL cl_bool headerCompare(const unsigned char *BufPtr, BINARY_HEADER_INDEX index) { - // These bytes sort of have a hidden message, but it's not in - // little-endian this time, and it's a little redundant. - return BufPtr != BufEnd && - BufPtr[0] == 'B' && - BufPtr[1] == 'C' && - BufPtr[2] == 0xc0 && - BufPtr[3] == 0xde; + bool matched = true; + int length = index == BHI_SPIR ? BINARY_HEADER_LENGTH -1 :BINARY_HEADER_LENGTH; + int i = 0; + for (i = 0; i < length; ++i) + { + matched = matched && (BufPtr[i] == binary_type_header[index][i]); + } + return matched; } -#define isBitcode(BufPtr,BufEnd) (isBitcodeWrapper(BufPtr, BufEnd) || isRawBitcode(BufPtr, BufEnd)) +#define isSPIR(BufPtr) headerCompare(BufPtr, BHI_SPIR) +#define isLLVM_C_O(BufPtr) headerCompare(BufPtr, BHI_COMPIRED_OBJECT) +#define isLLVM_LIB(BufPtr) headerCompare(BufPtr, BHI_LIBRARY) +#define isGenBinary(BufPtr) headerCompare(BufPtr, BHI_GEN_BINARY) LOCAL cl_program cl_program_create_from_binary(cl_context ctx, @@ -216,7 +217,8 @@ cl_program_create_from_binary(cl_context ctx, goto error; } - if (lengths[0] == 0) { + //need at least 4 bytes to check the binary type. + if (lengths[0] == 0 || lengths[0] < 4) { err = CL_INVALID_VALUE; if (binary_status) binary_status[0] = CL_INVALID_VALUE; @@ -229,13 +231,12 @@ cl_program_create_from_binary(cl_context ctx, goto error; } - // TODO: Need to check the binary format here to return CL_INVALID_BINARY. TRY_ALLOC(program->binary, cl_calloc(lengths[0], sizeof(char))); memcpy(program->binary, binaries[0], lengths[0]); program->binary_sz = lengths[0]; program->source_type = FROM_BINARY; - if(isBitcode((unsigned char*)program->binary, (unsigned char*)program->binary+program->binary_sz)) { + if(isSPIR((unsigned char*)program->binary)) { char* typed_binary; TRY_ALLOC(typed_binary, cl_calloc(lengths[0]+1, sizeof(char))); @@ -249,10 +250,10 @@ cl_program_create_from_binary(cl_context ctx, } program->source_type = FROM_LLVM_SPIR; - }else if(isBitcode((unsigned char*)program->binary+1, (unsigned char*)program->binary+program->binary_sz)) { - if(*program->binary == 1){ + }else if(isLLVM_C_O((unsigned char*)program->binary) || isLLVM_LIB((unsigned char*)program->binary)) { + if(*program->binary == BHI_COMPIRED_OBJECT){ program->binary_type = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT; - }else if(*program->binary == 2){ + }else if(*program->binary == BHI_LIBRARY){ program->binary_type = CL_PROGRAM_BINARY_TYPE_LIBRARY; }else{ err= CL_INVALID_BINARY; @@ -266,7 +267,7 @@ cl_program_create_from_binary(cl_context ctx, } program->source_type = FROM_LLVM; } - else if (*program->binary == 0) { + else if (isGenBinary((unsigned char*)program->binary)) { program->opaque = interp_program_new_from_binary(program->ctx->device->device_id, program->binary, program->binary_sz); if (UNLIKELY(program->opaque == NULL)) { err = CL_INVALID_PROGRAM; @@ -277,6 +278,10 @@ cl_program_create_from_binary(cl_context ctx, TRY (cl_program_load_gen_program, program); program->binary_type = CL_PROGRAM_BINARY_TYPE_EXECUTABLE; } + else { + err= CL_INVALID_BINARY; + goto error; + } if (binary_status) binary_status[0] = CL_SUCCESS; diff --git a/src/cl_program.h b/src/cl_program.h index 7af02062..63ad16d2 100644 --- a/src/cl_program.h +++ b/src/cl_program.h @@ -37,6 +37,14 @@ enum { FROM_LLVM_SPIR = 3 }; +typedef enum _BINARY_HEADER_INDEX { + BHI_SPIR = 0, + BHI_COMPIRED_OBJECT = 1, + BHI_LIBRARY = 2, + BHI_GEN_BINARY = 3, /*remember update BHI_MAX if add option.*/ + BHI_MAX, +}BINARY_HEADER_INDEX; + /* This maps an OCL file containing some kernels */ struct _cl_program { DEFINE_ICD(dispatch) |