• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }