1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
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
16 #include "literalstrname.h"
17
18 // literal string name is shared between maple compiler and runtime, thus not in namespace maplert
19 // note there is a macor kConstString "_C_STR_" in literalstrname.h
20 // which need to match
21 static const std::string mplConstStr("_C_STR_00000000000000000000000000000000");
22 const uint32_t kMaxBytesLength = 15;
23
24 namespace {
25 const char *kMplDigits = "0123456789abcdef";
26 }
27
28 // Return the hex string of bytes. The result is the combination of prefix "_C_STR_" and hex string of bytes.
29 // The upper 4 bits and lower 4 bits of bytes[i] are transformed to hex form and restored separately in hex string.
GetHexStr(const uint8_t * bytes,uint32_t len)30 std::string LiteralStrName::GetHexStr(const uint8_t *bytes, uint32_t len)
31 {
32 if (bytes == nullptr) {
33 return std::string();
34 }
35 constexpr uint8_t k16BitShift = 4; // 16 is 1 << 4
36 std::string str(mplConstStr, 0, (len << 1) + kConstStringLen);
37 for (unsigned i = 0; i < len; ++i) {
38 str[(i << 1) + kConstStringLen] =
39 kMplDigits[(bytes[i] & 0xf0) >> k16BitShift]; // get the hex value of upper 4 bits of bytes[i]
40 str[(i << 1) + kConstStringLen + 1] =
41 kMplDigits[bytes[i] & 0x0f]; // get the hex value of lower 4 bits of bytes[i]
42 }
43 return str;
44 }
45
46 // Return the hash code of data. The hash code is computed as
47 // s[0] * 31 ^ (len - 1) + s[1] * 31 ^ (len - 2) + ... + s[len - 1],
48 // where s[i] is the value of swapping the upper 8 bits and lower 8 bits of data[i].
CalculateHashSwapByte(const char16_t * data,uint32_t len)49 int32_t LiteralStrName::CalculateHashSwapByte(const char16_t *data, uint32_t len)
50 {
51 constexpr uint32_t k32BitShift = 5; // 32 is 1 << 5
52 constexpr char16_t kByteShift = 8;
53 uint32_t hash = 0;
54 const char16_t *end = data + len;
55 while (data < end) {
56 hash = (hash << k32BitShift) - hash;
57 char16_t val = *data++;
58 hash += (((val << kByteShift) & 0xff00) | ((val >> kByteShift) & 0xff));
59 }
60 return static_cast<int32_t>(hash);
61 }
62
GetLiteralStrName(const uint8_t * bytes,uint32_t len)63 std::string LiteralStrName::GetLiteralStrName(const uint8_t *bytes, uint32_t len)
64 {
65 if (len <= kMaxBytesLength) {
66 return GetHexStr(bytes, len);
67 }
68 return ComputeMuid(bytes, len);
69 }
70
ComputeMuid(const uint8_t * bytes,uint32_t len)71 std::string LiteralStrName::ComputeMuid(const uint8_t *bytes, uint32_t len)
72 {
73 DigestHash digestHash = GetDigestHash(*bytes, len);
74 return GetHexStr(digestHash.bytes, kDigestHashLength);
75 }