1 /*
2 * Copyright (c) 2024 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 "abc2program_compiler.h"
17 #include "abc_class_processor.h"
18 #include "utils/timers.h"
19
20 namespace panda::abc2program {
21
~Abc2ProgramCompiler()22 Abc2ProgramCompiler::~Abc2ProgramCompiler()
23 {
24 if (prog_ != nullptr) {
25 delete prog_;
26 prog_ = nullptr;
27 }
28 }
29
OpenAbcFile(const std::string & file_path)30 bool Abc2ProgramCompiler::OpenAbcFile(const std::string &file_path)
31 {
32 file_ = panda_file::File::Open(file_path);
33 if (file_ == nullptr) {
34 return false;
35 }
36 debug_info_extractor_ = std::make_unique<panda_file::DebugInfoExtractor>(file_.get());
37 return true;
38 }
39
CheckFileVersionIsSupported(std::array<uint8_t,panda_file::File::VERSION_SIZE> min_version,uint8_t target_api_version,std::string target_api_sub_version) const40 bool Abc2ProgramCompiler::CheckFileVersionIsSupported(std::array<uint8_t, panda_file::File::VERSION_SIZE> min_version,
41 uint8_t target_api_version,
42 std::string target_api_sub_version) const
43 {
44 auto target_version = panda_file::GetVersionByApi(target_api_version, target_api_sub_version);
45 if (!target_version.has_value()) {
46 return false;
47 }
48 const auto &file_version = file_->GetHeader()->version;
49 return panda::panda_file::IsVersionLessOrEqual(min_version, file_version) &&
50 panda::panda_file::IsVersionLessOrEqual(file_version, target_version.value());
51 }
52
GetAbcFile() const53 const panda_file::File &Abc2ProgramCompiler::GetAbcFile() const
54 {
55 return *file_;
56 }
57
GetDebugInfoExtractor() const58 const panda_file::DebugInfoExtractor &Abc2ProgramCompiler::GetDebugInfoExtractor() const
59 {
60 return *debug_info_extractor_;
61 }
62
CompileAbcFile()63 pandasm::Program *Abc2ProgramCompiler::CompileAbcFile()
64 {
65 prog_ = new pandasm::Program();
66 // An abc may be generated from serveral kinds of source files.
67 // prog_->lang should not be used for setting any other structure's language such as record.
68 // Since prog_->lang will not be emitted into abc, this will not effect the integraty of generated abc file.
69 prog_->lang = DEFUALT_SOURCE_LANG;
70 auto classes = file_->GetClasses();
71 std::string record_name = "";
72 for (size_t i = 0; i < classes.size(); i++) {
73 panda_file::File::EntityId record_id(classes[i]);
74 CompileAbcClass(record_id, *prog_, record_name);
75 }
76 return prog_;
77 }
78
CompileAbcClass(const panda_file::File::EntityId & record_id,pandasm::Program & program,std::string & record_name)79 void Abc2ProgramCompiler::CompileAbcClass(const panda_file::File::EntityId &record_id,
80 pandasm::Program &program, std::string &record_name)
81 {
82 Abc2ProgramEntityContainer entity_container(*file_, program, *debug_info_extractor_, record_id.GetOffset(),
83 bundle_name_);
84 if (!modify_pkg_name_.empty()) {
85 entity_container.SetModifyPkgName(modify_pkg_name_);
86 }
87 record_name = entity_container.GetFullRecordNameById(record_id);
88 panda::Timer::timerStart(EVENT_COMPILE_ABC_FILE_RECORD, record_name);
89 AbcClassProcessor class_processor(record_id, entity_container);
90 class_processor.FillProgramData();
91 panda::Timer::timerEnd(EVENT_COMPILE_ABC_FILE_RECORD, record_name);
92 }
93
CheckClassId(uint32_t class_id,size_t offset) const94 bool Abc2ProgramCompiler::CheckClassId(uint32_t class_id, size_t offset) const
95 {
96 auto *header = file_->GetHeader();
97 auto class_off = header->class_idx_off + sizeof(uint32_t) * offset;
98 if (class_id > header->file_size) {
99 LOG(FATAL, ABC2PROGRAM) << "> error encountered in record at " << class_off << " (0x" << std::hex
100 << class_off << "). binary file corrupted. record offset (0x" << class_id
101 << ") out of bounds (0x" << header->file_size << ")!";
102 }
103 return !file_->IsExternal(panda_file::File::EntityId(class_id));
104 }
105
106 } // namespace panda::abc2program
107