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