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