forked from pytorch/executorch
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVulkanDelegateHeader.cpp
More file actions
130 lines (105 loc) · 3.53 KB
/
Copy pathVulkanDelegateHeader.cpp
File metadata and controls
130 lines (105 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <executorch/backends/vulkan/runtime/VulkanDelegateHeader.h>
#include <cstring>
#include <executorch/runtime/core/error.h>
#include <executorch/runtime/core/result.h>
#pragma clang diagnostic ignored "-Wdeprecated"
namespace executorch {
namespace backends {
namespace vulkan {
using executorch::runtime::Error;
using executorch::runtime::Result;
namespace {
struct ByteSlice {
size_t offset;
size_t size;
};
constexpr size_t kExpectedSize = 30;
constexpr char kExpectedMagic[4] = {'V', 'H', '0', '0'};
constexpr ByteSlice kMagic = {4, 4};
constexpr ByteSlice kHeaderSize = {8, 2};
constexpr ByteSlice kFlatbufferOffset = {10, 4};
constexpr ByteSlice kFlatbufferSize = {14, 4};
constexpr ByteSlice kBytesOffset = {18, 4};
constexpr ByteSlice kBytesSize = {22, 8};
} // namespace
/// Interprets the 8 bytes at `data` as a little-endian uint64_t.
uint64_t getUInt64LE(const uint8_t* data) {
return (uint64_t)data[0] | ((uint64_t)data[1] << 8) |
((uint64_t)data[2] << 16) | ((uint64_t)data[3] << 24) |
((uint64_t)data[4] << 32) | ((uint64_t)data[5] << 40) |
((uint64_t)data[6] << 48) | ((uint64_t)data[7] << 56);
}
/// Interprets the 4 bytes at `data` as a little-endian uint32_t.
uint32_t getUInt32LE(const uint8_t* data) {
return (uint32_t)data[0] | ((uint32_t)data[1] << 8) |
((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 24);
}
/// Interprets the 2 bytes at `data` as a little-endian uint32_t.
uint32_t getUInt16LE(const uint8_t* data) {
return (uint32_t)data[0] | ((uint32_t)data[1] << 8);
}
bool getBool(const uint8_t* data) {
return data[0] != 0;
}
bool VulkanDelegateHeader::is_valid() const {
if (header_size < kExpectedSize) {
return false;
}
if (flatbuffer_offset < header_size) {
return false;
}
if (flatbuffer_size == 0) {
return false;
}
if (bytes_offset < flatbuffer_offset + flatbuffer_size) {
return false;
}
if (bytes_size < 0) {
return false;
}
return true;
}
Result<VulkanDelegateHeader> VulkanDelegateHeader::parse(
const void* data,
size_t buffer_size) {
// Ensure the buffer is large enough to read all header fields.
// The last field (bytes_size) ends at offset 22 + 8 = 30 = kExpectedSize.
if (buffer_size < kExpectedSize) {
return Error::InvalidArgument;
}
const uint8_t* header_data = (const uint8_t*)data;
const uint8_t* magic_start = header_data + kMagic.offset;
if (std::memcmp(magic_start, kExpectedMagic, kMagic.size) != 0) {
return Error::NotFound;
}
VulkanDelegateHeader header = VulkanDelegateHeader{
getUInt16LE(header_data + kHeaderSize.offset),
getUInt32LE(header_data + kFlatbufferOffset.offset),
getUInt32LE(header_data + kFlatbufferSize.offset),
getUInt32LE(header_data + kBytesOffset.offset),
getUInt64LE(header_data + kBytesSize.offset),
};
if (!header.is_valid()) {
return Error::InvalidArgument;
}
// Validate that header offsets do not extend beyond the buffer.
if (header.flatbuffer_offset > buffer_size ||
header.flatbuffer_size > buffer_size - header.flatbuffer_offset) {
return Error::InvalidArgument;
}
if (header.bytes_offset > buffer_size ||
header.bytes_size > buffer_size - header.bytes_offset) {
return Error::InvalidArgument;
}
return header;
}
} // namespace vulkan
} // namespace backends
} // namespace executorch