• 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_entity_container.h"
17 #include "abc_file_utils.h"
18 #include "file-inl.h"
19 #include "method_data_accessor-inl.h"
20 
21 namespace panda::abc2program {
22 
GetAbcFile() const23 const panda_file::File &Abc2ProgramEntityContainer::GetAbcFile() const
24 {
25     return file_;
26 }
27 
GetProgram() const28 pandasm::Program &Abc2ProgramEntityContainer::GetProgram() const
29 {
30     return program_;
31 }
32 
GetDebugInfoExtractor() const33 const panda_file::DebugInfoExtractor &Abc2ProgramEntityContainer::GetDebugInfoExtractor() const
34 {
35     return debug_info_extractor_;
36 }
37 
GetStringById(const panda_file::File::EntityId & entity_id) const38 std::string Abc2ProgramEntityContainer::GetStringById(const panda_file::File::EntityId &entity_id) const
39 {
40     panda_file::File::StringData sd = file_.GetStringData(entity_id);
41     return (reinterpret_cast<const char *>(sd.data));
42 }
43 
GetFullRecordNameById(const panda_file::File::EntityId & class_id)44 std::string Abc2ProgramEntityContainer::GetFullRecordNameById(const panda_file::File::EntityId &class_id)
45 {
46     uint32_t class_id_offset = class_id.GetOffset();
47     auto it = record_full_name_map_.find(class_id_offset);
48     if (it != record_full_name_map_.end()) {
49         return it->second;
50     }
51     std::string name = GetStringById(class_id);
52     pandasm::Type type = pandasm::Type::FromDescriptor(name);
53     std::string record_full_name = type.GetName();
54     ModifyRecordName(record_full_name);
55     record_full_name_map_.emplace(class_id_offset, record_full_name);
56     return record_full_name;
57 }
58 
59 /**
60  * Support the inter-app hsp dependents bytecode har.
61  * The record name format: <bundleName>&<normalizedImportPath>&<version>
62  * The ohmurl specs that must have bundleName in inter-app package. The records need compile into the inter-app
63  * hsp package. So the recordNames need to add bundleName in front when the abc-file as input for the
64  * inter-app hsp package.
65  */
ModifyRecordName(std::string & record_name)66 void Abc2ProgramEntityContainer::ModifyRecordName(std::string &record_name)
67 {
68     if (!modify_pkg_name_.empty()) {
69         ModifyPkgNameForRecordName(record_name);
70     }
71 
72     if (bundle_name_.empty()) {
73         return;
74     }
75     if (IsSourceFileRecord(record_name)) {
76         record_name = bundle_name_ + record_name;
77     }
78 }
79 
ModifyPkgNameForRecordName(std::string & record_name)80 void Abc2ProgramEntityContainer::ModifyPkgNameForRecordName(std::string &record_name)
81 {
82     std::vector<std::string> pkg_names = Split(modify_pkg_name_, COLON_SEPARATOR);
83     std::string orginal = NORMALIZED_OHMURL_SEPARATOR + pkg_names[ORIGINAL_PKG_NAME_POS];
84     std::string target = NORMALIZED_OHMURL_SEPARATOR + pkg_names[TARGET_PKG_NAME_POS];
85     std::string pkg_name = GetPkgNameFromRecordName(record_name);
86     if (pkg_name == pkg_names[ORIGINAL_PKG_NAME_POS]) {
87         record_name.replace(0, orginal.length(), target);
88     }
89 }
90 
ModifyPkgNameForFieldName(std::string & field_name)91 void Abc2ProgramEntityContainer::ModifyPkgNameForFieldName(std::string &field_name)
92 {
93     if (modify_pkg_name_.empty()) {
94         return;
95     }
96     std::vector<std::string> pkg_names = Split(modify_pkg_name_, COLON_SEPARATOR);
97     std::string orginal = FIELD_NAME_PREFIX + pkg_names[ORIGINAL_PKG_NAME_POS];
98     if (field_name == orginal) {
99         field_name = FIELD_NAME_PREFIX + pkg_names[TARGET_PKG_NAME_POS];
100     }
101 }
102 
IsSourceFileRecord(const std::string & record_name)103 bool Abc2ProgramEntityContainer::IsSourceFileRecord(const std::string& record_name)
104 {
105     return record_name.find(NORMALIZED_OHMURL_SEPARATOR) == 0;
106 }
107 
GetFullMethodNameById(const panda_file::File::EntityId & method_id)108 std::string Abc2ProgramEntityContainer::GetFullMethodNameById(const panda_file::File::EntityId &method_id)
109 {
110     auto method_id_offset = method_id.GetOffset();
111     auto it = method_full_name_map_.find(method_id_offset);
112     if (it != method_full_name_map_.end()) {
113         return it->second;
114     }
115     std::string full_method_name = ConcatFullMethodNameById(method_id);
116     method_full_name_map_.emplace(method_id_offset, full_method_name);
117     return full_method_name;
118 }
119 
ConcatFullMethodNameById(const panda_file::File::EntityId & method_id)120 std::string Abc2ProgramEntityContainer::ConcatFullMethodNameById(const panda_file::File::EntityId &method_id)
121 {
122     panda::panda_file::MethodDataAccessor method_data_accessor(file_, method_id);
123     std::string method_name_raw = GetStringById(method_data_accessor.GetNameId());
124     std::string record_name = GetFullRecordNameById(method_data_accessor.GetClassId());
125     std::stringstream ss;
126     if (AbcFileUtils::IsSystemTypeName(record_name)) {
127         ss << DOT;
128     } else {
129         ss << record_name << DOT;
130     }
131     ss << method_name_raw;
132     return ss.str();
133 }
134 
GetMouleLiteralArrayIdSet() const135 const std::unordered_set<uint32_t> &Abc2ProgramEntityContainer::GetMouleLiteralArrayIdSet() const
136 {
137     return module_literal_array_id_set_;
138 }
139 
GetModuleRequestPhaseIdSet() const140 const std::unordered_set<uint32_t> &Abc2ProgramEntityContainer::GetModuleRequestPhaseIdSet() const
141 {
142     return module_request_phase_id_set_;
143 }
144 
GetUnnestedLiteralArrayIdSet() const145 const std::unordered_set<uint32_t> &Abc2ProgramEntityContainer::GetUnnestedLiteralArrayIdSet() const
146 {
147     return unnested_literal_array_id_set_;
148 }
149 
GetUnprocessedNestedLiteralArrayIdSet()150 std::unordered_set<uint32_t> &Abc2ProgramEntityContainer::GetUnprocessedNestedLiteralArrayIdSet()
151 {
152     return unprocessed_nested_literal_array_id_set_;
153 }
154 
AddModuleLiteralArrayId(uint32_t module_literal_array_id)155 void Abc2ProgramEntityContainer::AddModuleLiteralArrayId(uint32_t module_literal_array_id)
156 {
157     module_literal_array_id_set_.insert(module_literal_array_id);
158 }
159 
160 
AddModuleRequestPhaseId(uint32_t module_request_phase_id)161 void Abc2ProgramEntityContainer::AddModuleRequestPhaseId(uint32_t module_request_phase_id)
162 {
163     module_request_phase_id_set_.insert(module_request_phase_id);
164 }
165 
AddUnnestedLiteralArrayId(uint32_t literal_array_id)166 void Abc2ProgramEntityContainer::AddUnnestedLiteralArrayId(uint32_t literal_array_id)
167 {
168     unnested_literal_array_id_set_.insert(literal_array_id);
169 }
170 
AddProcessedNestedLiteralArrayId(uint32_t nested_literal_array_id)171 void Abc2ProgramEntityContainer::AddProcessedNestedLiteralArrayId(uint32_t nested_literal_array_id)
172 {
173     processed_nested_literal_array_id_set_.insert(nested_literal_array_id);
174 }
175 
TryAddUnprocessedNestedLiteralArrayId(uint32_t nested_literal_array_id)176 void Abc2ProgramEntityContainer::TryAddUnprocessedNestedLiteralArrayId(uint32_t nested_literal_array_id)
177 {
178     if (unnested_literal_array_id_set_.count(nested_literal_array_id)) {
179         return;
180     }
181     if (processed_nested_literal_array_id_set_.count(nested_literal_array_id)) {
182         return;
183     }
184     unprocessed_nested_literal_array_id_set_.insert(nested_literal_array_id);
185 }
186 
GetLiteralArrayIdName(uint32_t literal_array_id)187 std::string Abc2ProgramEntityContainer::GetLiteralArrayIdName(uint32_t literal_array_id)
188 {
189     std::stringstream name;
190     auto cur_record_name = GetFullRecordNameById(panda_file::File::EntityId(current_class_id_));
191     name << cur_record_name << UNDERLINE << literal_array_id;
192     return name.str();
193 }
194 
AddProgramString(const std::string & str) const195 void Abc2ProgramEntityContainer::AddProgramString(const std::string &str) const
196 {
197     program_.strings.insert(str);
198 }
199 
200 }  // namespace panda::abc2program