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