1// Copyright (c) 2015-2016 The Khronos Group Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "source/spirv_constant.h"
16#include "test/unit_spirv.h"
17
18namespace spvtools {
19namespace {
20
21class BinaryHeaderGet : public ::testing::Test {
22 public:
23  BinaryHeaderGet() { memset(code, 0, sizeof(code)); }
24
25  virtual void SetUp() {
26    code[0] = static_cast<uint32_t>(spv::MagicNumber);
27    code[1] = static_cast<uint32_t>(spv::Version);
28    code[2] = SPV_GENERATOR_CODEPLAY;
29    code[3] = 1;  // NOTE: Bound
30    code[4] = 0;  // NOTE: Schema; reserved
31    code[5] = 0;  // NOTE: Instructions
32
33    binary.code = code;
34    binary.wordCount = 6;
35  }
36  spv_const_binary_t get_const_binary() {
37    return spv_const_binary_t{binary.code, binary.wordCount};
38  }
39  virtual void TearDown() {}
40
41  uint32_t code[6];
42  spv_binary_t binary;
43};
44
45TEST_F(BinaryHeaderGet, Default) {
46  spv_endianness_t endian;
47  spv_const_binary_t const_bin = get_const_binary();
48  ASSERT_EQ(SPV_SUCCESS, spvBinaryEndianness(&const_bin, &endian));
49
50  spv_header_t header;
51  ASSERT_EQ(SPV_SUCCESS, spvBinaryHeaderGet(&const_bin, endian, &header));
52
53  ASSERT_EQ(static_cast<uint32_t>(spv::MagicNumber), header.magic);
54  // Expect SPIRV-Headers updated to SPIR-V 1.6.
55  ASSERT_EQ(0x00010600u, header.version);
56  ASSERT_EQ(static_cast<uint32_t>(SPV_GENERATOR_CODEPLAY), header.generator);
57  ASSERT_EQ(1u, header.bound);
58  ASSERT_EQ(0u, header.schema);
59  ASSERT_EQ(&code[5], header.instructions);
60}
61
62TEST_F(BinaryHeaderGet, InvalidCode) {
63  spv_const_binary_t my_binary = {nullptr, 0};
64  spv_header_t header;
65  ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
66            spvBinaryHeaderGet(&my_binary, SPV_ENDIANNESS_LITTLE, &header));
67}
68
69TEST_F(BinaryHeaderGet, InvalidPointerHeader) {
70  spv_const_binary_t const_bin = get_const_binary();
71  ASSERT_EQ(SPV_ERROR_INVALID_POINTER,
72            spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, nullptr));
73}
74
75TEST_F(BinaryHeaderGet, TruncatedHeader) {
76  for (uint8_t i = 1; i < SPV_INDEX_INSTRUCTION; i++) {
77    binary.wordCount = i;
78    spv_const_binary_t const_bin = get_const_binary();
79    ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
80              spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, nullptr));
81  }
82}
83
84TEST_F(BinaryHeaderGet, VersionNonZeroHighByte) {
85  spv_header_t header;
86  code[1] = 0xFF010300;
87  spv_const_binary_t const_bin = get_const_binary();
88  ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
89            spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
90}
91
92TEST_F(BinaryHeaderGet, VersionNonZeroLowByte) {
93  spv_header_t header;
94  code[1] = 0x000103F0;
95  spv_const_binary_t const_bin = get_const_binary();
96  ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
97            spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
98}
99
100TEST_F(BinaryHeaderGet, VersionTooLow) {
101  spv_header_t header;
102  code[1] = 0x00000300;
103  spv_const_binary_t const_bin = get_const_binary();
104  ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
105            spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
106}
107
108TEST_F(BinaryHeaderGet, VersionTooHigh) {
109  spv_header_t header;
110  code[1] = 0x000F0300;
111  spv_const_binary_t const_bin = get_const_binary();
112  ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
113            spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
114}
115
116}  // namespace
117}  // namespace spvtools
118