• 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 #ifndef ECMASCRIPT_BASE_FILE_HEADER_H
17 #define ECMASCRIPT_BASE_FILE_HEADER_H
18 
19 #include "ecmascript/base/string_helper.h"
20 #include "ecmascript/log_wrapper.h"
21 #include "utils/bit_utils.h"
22 #include <array>
23 #include <stddef.h>
24 #include <stdint.h>
25 
26 namespace panda::ecmascript::base {
27 class FileHeaderBase {
28 public:
29     static constexpr size_t MAGIC_SIZE = 8;
30     static constexpr size_t VERSION_SIZE = 4;
31     static constexpr uint32_t CHECKSUM_END_OFFSET = MAGIC_SIZE + VERSION_SIZE + sizeof(uint32_t);
32     static constexpr std::array<uint8_t, MAGIC_SIZE> MAGIC = {'P', 'A', 'N', 'D', 'A', '\0', '\0', '\0'};
33     using VersionType = std::array<uint8_t, VERSION_SIZE>;
34 
ToVersion(uint32_t versionNumber)35     static VersionType ToVersion(uint32_t versionNumber)
36     {
37         return bit_cast<VersionType>(ReverseBytes(versionNumber));
38     }
39 
ToVersionNumber(const VersionType & version)40     static uint32_t ToVersionNumber(const VersionType &version)
41     {
42         return ReverseBytes(bit_cast<uint32_t>(version));
43     }
44 
VerifyVersion(const char * fileDesc,uint32_t currVersion,uint32_t lastVersion,bool strictMatch)45     static bool VerifyVersion(const char *fileDesc, uint32_t currVersion, uint32_t lastVersion, bool strictMatch)
46     {
47         return VerifyVersion(fileDesc, ToVersion(currVersion), ToVersion(lastVersion), strictMatch);
48     }
49 
50     template <size_t size>
ConvToStr(const std::array<uint8_t,size> & array)51     static std::string ConvToStr(const std::array<uint8_t, size> &array)
52     {
53         std::string ret;
54         for (size_t i = 0; i < size; ++i) {
55             if (i) {
56                 ret += ".";
57             }
58             ret += std::to_string(array.at(i));
59         }
60         return ret;
61     }
62 
VerifyVersion(const char * fileDesc,const VersionType & lastVersion,bool strictMatch)63     bool VerifyVersion(const char *fileDesc, const VersionType &lastVersion, bool strictMatch) const
64     {
65         if (magic_ != MAGIC) {
66             LOG_HOST_TOOL_ERROR << "Magic mismatch, please make sure " << fileDesc
67                                 << " and the source code are matched";
68             LOG_ECMA(ERROR) << "magic error, expected magic is " << ConvToStr(MAGIC) << ", but got "
69                             << ConvToStr(magic_);
70             return false;
71         }
72         if (!VerifyVersion(fileDesc, version_, lastVersion, strictMatch)) {
73             return false;
74         }
75         LOG_ECMA(DEBUG) << "Magic:" << ConvToStr(magic_) << ", version:" << InternalGetVersion();
76         return true;
77     }
78 
CompatibleVerify(const VersionType & expectVersion)79     bool CompatibleVerify(const VersionType &expectVersion) const
80     {
81         return version_ >= expectVersion;
82     }
83 
GetVersion()84     VersionType GetVersion() const
85     {
86         return version_;
87     }
88 
89 protected:
FileHeaderBase(const VersionType & lastVersion)90     explicit FileHeaderBase(const VersionType &lastVersion) : magic_(MAGIC), version_(lastVersion) {}
91 
VerifyVersion(const char * fileDesc,const VersionType & currVersion,const VersionType & lastVersion,bool strictMatch)92     static bool VerifyVersion(const char *fileDesc, const VersionType &currVersion, const VersionType &lastVersion,
93                               bool strictMatch)
94     {
95         bool matched = strictMatch ? (currVersion == lastVersion) : (currVersion <= lastVersion);
96         if (!matched) {
97             LOG_HOST_TOOL_ERROR << fileDesc << " version error, expected version should be "
98                                 << (strictMatch ? "equal to " : "less or equal than ") << ConvToStr(lastVersion)
99                                 << ", but got " << ConvToStr(currVersion);
100             return false;
101         }
102         return true;
103     }
104 
InternalGetVersion()105     std::string InternalGetVersion() const
106     {
107         return ConvToStr(version_);
108     }
109 
InternalSetVersion(const std::string & version)110     bool InternalSetVersion(const std::string &version)
111     {
112         std::vector<std::string> versionNumber = StringHelper::SplitString(version, ".");
113         if (versionNumber.size() != VERSION_SIZE) {
114             LOG_ECMA(ERROR) << "version: " << version << " format error";
115             return false;
116         }
117         for (uint32_t i = 0; i < VERSION_SIZE; i++) {
118             uint32_t result = 0;
119             if (!StringHelper::StrToUInt32(versionNumber[i].c_str(), &result)) {
120                 LOG_ECMA(ERROR) << "version: " << version << " format error";
121                 return false;
122             }
123             version_.at(i) = static_cast<uint8_t>(result);
124         }
125         return true;
126     }
127 
128 private:
129     std::array<uint8_t, MAGIC_SIZE> magic_;
130     VersionType version_;
131 };
132 
133 class FileHeaderElastic : public FileHeaderBase {
134 public:
135     static constexpr uint32_t ENDIAN_VALUE = 0x12345678;
SetChecksum(uint32_t checksum)136     void SetChecksum(uint32_t checksum)
137     {
138         checksum_ = checksum;
139     }
140 
GetChecksum()141     uint32_t GetChecksum() const
142     {
143         return checksum_;
144     }
145 
SetHeaderSize(uint32_t size)146     void SetHeaderSize(uint32_t size)
147     {
148         headerSize_ = size;
149     }
150 
GetHeaderSize()151     uint32_t GetHeaderSize() const
152     {
153         return headerSize_;
154     }
155 
SetFileSize(uint32_t size)156     void SetFileSize(uint32_t size)
157     {
158         fileSize_ = size;
159     }
160 
GetFileSize()161     uint32_t GetFileSize() const
162     {
163         return fileSize_;
164     }
165 
GetEndianTag()166     uint32_t GetEndianTag() const
167     {
168         return endianTag_;
169     }
170 
171 protected:
FileHeaderElastic(const VersionType & lastVersion)172     explicit FileHeaderElastic(const VersionType &lastVersion) : FileHeaderBase(lastVersion) {}
173 
174 private:
175     uint32_t checksum_ {0};
176     uint32_t fileSize_ {0};
177     uint32_t headerSize_ {0};
178     uint32_t endianTag_ {ENDIAN_VALUE};
179 };
180 }  // namespace panda::ecmascript::base
181 #endif  // ECMASCRIPT_BASE_FILE_HEADER_H
182