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 "metadata/metadata_builder.h"
17 #include <cstring>
18 #include "securec.h"
19 #include "ast/ast_array_type.h"
20 #include "ast/ast_map_type.h"
21 #include "util/logger.h"
22
23 #define ALIGN8(v) (((v) + 7) & ~7)
24
25 namespace OHOS {
26 namespace Idl {
27 std::string MetadataBuilder::tag_ = "MetadataBuilder";
Build()28 std::shared_ptr<MetaComponent> MetadataBuilder::Build()
29 {
30 if (!module_->IsValid()) {
31 Logger::E(tag_.c_str(), "The module is not validate.");
32 return nullptr;
33 }
34
35 size_ = CalculateMetadataSize();
36 if (size_ > 0) {
37 void* metadata = calloc(size_, 1);
38 if (metadata == nullptr) {
39 Logger::E(tag_.c_str(), "Out of memory.");
40 return nullptr;
41 }
42 metaComponent_.reset(
43 new(metadata) MetaComponent, [](MetaComponent* p) { free(p); });
44
45 WriteMetadata(reinterpret_cast<uintptr_t>(metadata));
46 } else {
47 return nullptr;
48 }
49
50 return metaComponent_;
51 }
52
CalculateMetadataSize()53 size_t MetadataBuilder::CalculateMetadataSize()
54 {
55 baseAddr_ = 0;
56 CalculateMetaComponent(module_);
57 return baseAddr_;
58 }
59
CalculateMetaComponent(AST * module)60 void MetadataBuilder::CalculateMetaComponent(AST* module)
61 {
62 size_t namespaceNumber = module->GetNamespaceNumber();
63 size_t sequenceableNumber = module->GetSequenceableDefNumber();
64 size_t interfaceNumber = module->GetInterfaceDefNumber();
65 size_t typeNumber = module->GetTypeNumber();
66
67 // begin address
68 baseAddr_ = ALIGN8(baseAddr_);
69 stringPool_.Add(module_->GetName());
70 // namespaces_'s address
71 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaComponent));
72 // sequenceables_'s address
73 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber);
74 // interfaces_'s address
75 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaSequenceable*) * sequenceableNumber);
76 // types_'s address
77 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface*) * interfaceNumber);
78 // stringPool_'s address
79 baseAddr_ = baseAddr_ + sizeof(MetaType*) * typeNumber;
80
81 for (size_t i = 0; i < namespaceNumber; i++) {
82 CalculateMetaNamespace(module->GetNamespace(i));
83 }
84
85 for (size_t i = 0; i < sequenceableNumber; i++) {
86 CalculateMetaSequenceable(module->GetSequenceableDef(i));
87 }
88
89 for (size_t i = 0; i < interfaceNumber; i++) {
90 CalculateMetaInterface(module->GetInterfaceDef(i));
91 }
92
93 const AST::TypeStringMap& types = module_->GetTypes();
94 for (const auto& pair : types) {
95 CalculateMetaType(pair.second);
96 }
97
98 // end address
99 CalculateStringPool();
100 }
101
CalculateMetaNamespace(ASTNamespace * nspace)102 void MetadataBuilder::CalculateMetaNamespace(ASTNamespace* nspace)
103 {
104 size_t sequenceableNumber = nspace->GetSequenceableNumber();
105 size_t interfaceNumber = nspace->GetInterfaceNumber();
106 size_t namespaceNumber = nspace->GetNamespaceNumber();
107
108 // begin address
109 baseAddr_ = ALIGN8(baseAddr_);
110 stringPool_.Add(nspace->GetName());
111 // sequenceables_'s address
112 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace));
113 // interfaces_'s address
114 baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * sequenceableNumber);
115 // namespaces_'s address
116 baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * interfaceNumber);
117 // end address
118 baseAddr_ = baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber;
119
120 for (size_t i = 0; i < namespaceNumber; i++) {
121 CalculateMetaNamespace(nspace->GetNamespace(i));
122 }
123 }
124
CalculateMetaSequenceable(ASTSequenceableType * sequenceable)125 void MetadataBuilder::CalculateMetaSequenceable(ASTSequenceableType* sequenceable)
126 {
127 // begin address
128 baseAddr_ = ALIGN8(baseAddr_);
129 stringPool_.Add(sequenceable->GetName());
130 stringPool_.Add(sequenceable->GetNamespace()->ToString());
131 // end address
132 baseAddr_ = baseAddr_ + sizeof(MetaSequenceable);
133 }
134
CalculateMetaInterface(ASTInterfaceType * interface)135 void MetadataBuilder::CalculateMetaInterface(ASTInterfaceType* interface)
136 {
137 size_t methodNumber = interface->GetMethodNumber();
138
139 // begin address
140 baseAddr_ = ALIGN8(baseAddr_);
141 stringPool_.Add(interface->GetLicense());
142 stringPool_.Add(interface->GetName());
143 stringPool_.Add(interface->GetNamespace()->ToString());
144 // methods_'s address
145 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface));
146 // end address
147 baseAddr_ = baseAddr_ + sizeof(MetaMethod*) * methodNumber;
148
149 for (size_t i = 0; i < methodNumber; i++) {
150 CalculateMetaMethod(interface->GetMethod(i));
151 }
152 }
153
CalculateMetaMethod(ASTMethod * method)154 void MetadataBuilder::CalculateMetaMethod(ASTMethod* method)
155 {
156 size_t parameterNumber = method->GetParameterNumber();
157
158 // begin address
159 baseAddr_ = ALIGN8(baseAddr_);
160 stringPool_.Add(method->GetName());
161 stringPool_.Add(method->GetSignature());
162 // parameters_'s address
163 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaMethod));
164 // end address
165 baseAddr_ = baseAddr_ + sizeof(MetaParameter*) * parameterNumber;
166
167 for (size_t i = 0; i < parameterNumber; i++) {
168 CalculateMetaParameter(method->GetParameter(i));
169 }
170 }
171
CalculateMetaParameter(ASTParameter * parameter)172 void MetadataBuilder::CalculateMetaParameter(ASTParameter* parameter)
173 {
174 // begin address
175 baseAddr_ = ALIGN8(baseAddr_);
176 stringPool_.Add(parameter->GetName());
177 // end address
178 baseAddr_ = baseAddr_ + sizeof(MetaParameter);
179 }
180
CalculateMetaType(ASTType * type)181 void MetadataBuilder::CalculateMetaType(ASTType* type)
182 {
183 // begin address
184 baseAddr_ = ALIGN8(baseAddr_);
185 // nestedTypeIndexes_'s address
186 baseAddr_ = baseAddr_ + sizeof(MetaType);
187 if (type->IsListType()) {
188 baseAddr_ = ALIGN8(baseAddr_);
189 // end address
190 baseAddr_ = baseAddr_ + sizeof(int*);
191 } else if (type->IsMapType()) {
192 // end address
193 size_t typeNumber = 2;
194 baseAddr_ = baseAddr_ + sizeof(int*) * typeNumber;
195 } else if (type->IsArrayType()) {
196 baseAddr_ = baseAddr_ + sizeof(int*);
197 }
198 }
199
CalculateStringPool()200 void MetadataBuilder::CalculateStringPool()
201 {
202 // begin address
203 baseAddr_ = ALIGN8(baseAddr_);
204 // end address
205 baseAddr_ = baseAddr_ + stringPool_.GetSize();
206 }
207
WriteMetadata(uintptr_t base)208 void MetadataBuilder::WriteMetadata(uintptr_t base)
209 {
210 baseAddr_ = base;
211 WriteMetaComponent(module_);
212 }
213
WriteMetaComponent(AST * module)214 void MetadataBuilder::WriteMetaComponent(AST* module)
215 {
216 size_t namespaceNumber = module->GetNamespaceNumber();
217 size_t sequenceableNumber = module->GetSequenceableDefNumber();
218 size_t interfaceNumber = module->GetInterfaceDefNumber();
219 size_t typeNumber = module->GetTypeNumber();
220
221 // begin address
222 baseAddr_ = ALIGN8(baseAddr_);
223 MetaComponent* mc = reinterpret_cast<MetaComponent*>(baseAddr_);
224 mc->magic_ = METADATA_MAGIC_NUMBER;
225 mc->size_ = static_cast<int>(size_);
226 mc->namespaceNumber_ = static_cast<int>(namespaceNumber);
227 mc->sequenceableNumber_ = static_cast<int>(sequenceableNumber);
228 mc->interfaceNumber_ = static_cast<int>(interfaceNumber);
229 mc->typeNumber_ = static_cast<int>(typeNumber);
230 mc->stringPoolSize_ = static_cast<int>(stringPool_.GetSize());
231 // namespaces_'s address
232 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaComponent));
233 mc->namespaces_ = reinterpret_cast<MetaNamespace**>(baseAddr_);
234 // sequenceables_'s address
235 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber);
236 mc->sequenceables_ = reinterpret_cast<MetaSequenceable**>(baseAddr_);
237 // interfaces_'s address
238 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaSequenceable*) * sequenceableNumber);
239 mc->interfaces_ = reinterpret_cast<MetaInterface**>(baseAddr_);
240 // types_'s address
241 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface*) * interfaceNumber);
242 mc->types_ = reinterpret_cast<MetaType**>(baseAddr_);
243 // stringPool_'s address
244 baseAddr_ = baseAddr_ + sizeof(MetaType*) * typeNumber;
245 mc->stringPool_ = reinterpret_cast<char*>(baseAddr_);
246 // end address
247 baseAddr_ = baseAddr_ + stringPool_.GetSize();
248 (void)memcpy_s(mc->stringPool_, stringPool_.GetSize(), stringPool_.GetData(), stringPool_.GetSize());
249
250 mc->name_ = WriteString(module->GetName());
251
252 for (size_t i = 0; i < namespaceNumber; i++) {
253 mc->namespaces_[i] = WriteMetaNamespace(module->GetNamespace(i));
254 }
255
256 for (size_t i = 0; i < sequenceableNumber; i++) {
257 mc->sequenceables_[i] = WriteMetaSequenceable(module->GetSequenceableDef(i));
258 }
259
260 for (size_t i = 0; i < interfaceNumber; i++) {
261 mc->interfaces_[i] = WriteMetaInterface(module->GetInterfaceDef(i));
262 }
263
264 const AST::TypeStringMap& types = module->GetTypes();
265 int i = 0;
266 for (const auto& pair : types) {
267 mc->types_[i++] = WriteMetaType(pair.second);
268 }
269 }
270
WriteMetaNamespace(ASTNamespace * nspace)271 MetaNamespace* MetadataBuilder::WriteMetaNamespace(ASTNamespace* nspace)
272 {
273 size_t sequenceableNumber = nspace->GetSequenceableNumber();
274 size_t interfaceNumber = nspace->GetInterfaceNumber();
275 size_t namespaceNumber = nspace->GetNamespaceNumber();
276
277 // begin address
278 baseAddr_ = ALIGN8(baseAddr_);
279 MetaNamespace* mn = reinterpret_cast<MetaNamespace*>(baseAddr_);
280 mn->name_ = WriteString(nspace->GetName());
281 mn->sequenceableNumber_ = static_cast<int>(sequenceableNumber);
282 mn->interfaceNumber_ = static_cast<int>(interfaceNumber);
283 mn->namespaceNumber_ = static_cast<int>(namespaceNumber);
284 // sequenceables_'s address
285 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace));
286 mn->sequenceableIndexes_ = reinterpret_cast<int*>(baseAddr_);
287 // interfaces_'s address
288 baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * sequenceableNumber);
289 mn->interfaceIndexes_ = reinterpret_cast<int*>(baseAddr_);
290 // namespaces_'s address
291 baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * interfaceNumber);
292 mn->namespaces_ = reinterpret_cast<MetaNamespace**>(baseAddr_);
293 // end address
294 baseAddr_ = baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber;
295
296 for (size_t i = 0; i < sequenceableNumber; i++) {
297 AutoPtr<ASTSequenceableType> sequenceable = nspace->GetSequenceable(i);
298 mn->sequenceableIndexes_[i] = module_->IndexOf(sequenceable.Get());
299 }
300
301 for (size_t i = 0; i < interfaceNumber; i++) {
302 AutoPtr<ASTInterfaceType> interface = nspace->GetInterface(i);
303 mn->interfaceIndexes_[i] = module_->IndexOf(interface.Get());
304 }
305
306 for (size_t i = 0; i < namespaceNumber; i++) {
307 AutoPtr<ASTNamespace> inner = nspace->GetNamespace(i);
308 mn->namespaces_[i] = WriteMetaNamespace(inner);
309 }
310
311 return mn;
312 }
313
WriteMetaSequenceable(ASTSequenceableType * parcelabe)314 MetaSequenceable* MetadataBuilder::WriteMetaSequenceable(ASTSequenceableType* parcelabe)
315 {
316 // begin address
317 baseAddr_ = ALIGN8(baseAddr_);
318 MetaSequenceable* mp = reinterpret_cast<MetaSequenceable*>(baseAddr_);
319 mp->name_ = WriteString(parcelabe->GetName());
320 mp->namespace_ = WriteString(parcelabe->GetNamespace()->ToString());
321 // end address
322 baseAddr_ = baseAddr_ + sizeof(MetaSequenceable);
323
324 return mp;
325 }
326
WriteMetaInterface(ASTInterfaceType * interface)327 MetaInterface* MetadataBuilder::WriteMetaInterface(ASTInterfaceType* interface)
328 {
329 size_t methodNumber = interface->GetMethodNumber();
330
331 // begin address
332 baseAddr_ = ALIGN8(baseAddr_);
333 MetaInterface* mi = reinterpret_cast<MetaInterface*>(baseAddr_);
334 mi->license_ = WriteString(interface->GetLicense());
335 mi->name_ = WriteString(interface->GetName());
336 mi->namespace_ = WriteString(interface->GetNamespace()->ToString());
337 mi->properties_ = interface->GetAttribute()->GetValue() == ASTAttr::ONEWAY ? INTERFACE_PROPERTY_ONEWAY : 0;
338 mi->methodNumber_ = static_cast<int>(methodNumber);
339 mi->external_ = interface->IsExternal();
340 // methods_'s address
341 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface));
342 mi->methods_ = reinterpret_cast<MetaMethod**>(baseAddr_);
343 // end address
344 baseAddr_ = baseAddr_ + sizeof(MetaMethod*) * methodNumber;
345
346 for (size_t i = 0; i < methodNumber; i++) {
347 mi->methods_[i] = WriteMetaMethod(interface->GetMethod(i));
348 }
349
350 return mi;
351 }
352
WriteMetaMethod(ASTMethod * method)353 MetaMethod* MetadataBuilder::WriteMetaMethod(ASTMethod* method)
354 {
355 size_t parameterNumber = method->GetParameterNumber();
356
357 // begin address
358 baseAddr_ = ALIGN8(baseAddr_);
359 MetaMethod* mm = reinterpret_cast<MetaMethod*>(baseAddr_);
360 mm->name_ = WriteString(method->GetName());
361 mm->signature_ = WriteString(method->GetSignature());
362 mm->properties_ = method->GetAttribute()->GetValue() == ASTAttr::ONEWAY ? METHOD_PROPERTY_ONEWAY : 0;
363 mm->returnTypeIndex_ = module_->IndexOf(method->GetReturnType());
364 mm->parameterNumber_ = static_cast<int>(parameterNumber);
365 // parameters_'s address
366 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaMethod));
367 mm->parameters_ = reinterpret_cast<MetaParameter**>(baseAddr_);
368 // end address
369 baseAddr_ = baseAddr_ + sizeof(MetaParameter*) * parameterNumber;
370
371 for (size_t i = 0; i < parameterNumber; i++) {
372 mm->parameters_[i] = WriteMetaParameter(method->GetParameter(i));
373 }
374
375 return mm;
376 }
377
WriteMetaParameter(ASTParameter * parameter)378 MetaParameter* MetadataBuilder::WriteMetaParameter(ASTParameter* parameter)
379 {
380 // begin address
381 baseAddr_ = ALIGN8(baseAddr_);
382 MetaParameter* mp = reinterpret_cast<MetaParameter*>(baseAddr_);
383 mp->name_ = WriteString(parameter->GetName());
384 if (parameter->GetAttribute() & ASTParamAttr::PARAM_IN) {
385 mp->attributes_ |= ATTR_IN;
386 }
387 if (parameter->GetAttribute() & ASTParamAttr::PARAM_OUT) {
388 mp->attributes_ |= ATTR_OUT;
389 }
390 mp->typeIndex_ = module_->IndexOf(parameter->GetType());
391 // end address
392 baseAddr_ = baseAddr_ + sizeof(MetaParameter);
393
394 return mp;
395 }
396
WriteMetaType(ASTType * type)397 MetaType* MetadataBuilder::WriteMetaType(ASTType* type)
398 {
399 // begin address
400 baseAddr_ = ALIGN8(baseAddr_);
401 MetaType* mt = reinterpret_cast<MetaType*>(baseAddr_);
402 mt->kind_ = Type2Kind(type);
403 if (type->IsSequenceableType()) {
404 mt->index_ = module_->IndexOf(static_cast<ASTSequenceableType*>(type));
405 } else if (type->IsInterfaceType()) {
406 mt->index_ = module_->IndexOf(static_cast<ASTInterfaceType*>(type));
407 } else {
408 mt->index_ = module_->IndexOf(type);
409 }
410 baseAddr_ = baseAddr_ + sizeof(MetaType);
411 if (type->IsListType()) {
412 mt->nestedTypeNumber_ = 1;
413 // nestedTypeIndexes_'s address
414 baseAddr_ = ALIGN8(baseAddr_);
415 mt->nestedTypeIndexes_ = reinterpret_cast<int*>(baseAddr_);
416 AutoPtr<ASTType> elementType = (static_cast<ASTListType*>(type))->GetElementType();
417 mt->nestedTypeIndexes_[0] = module_->IndexOf(elementType);
418 // end address
419 baseAddr_ = baseAddr_ + sizeof(int*);
420 } else if (type->IsMapType()) {
421 size_t typeNumber = 2;
422 mt->nestedTypeNumber_ = static_cast<int>(typeNumber);
423 // nestedTypeIndexes_'s address
424 baseAddr_ = ALIGN8(baseAddr_);
425 mt->nestedTypeIndexes_ = reinterpret_cast<int*>(baseAddr_);
426 AutoPtr<ASTType> keyType = (static_cast<ASTMapType*>(type))->GetKeyType();
427 AutoPtr<ASTType> valueType = (static_cast<ASTMapType*>(type))->GetValueType();
428 mt->nestedTypeIndexes_[0] = module_->IndexOf(keyType);
429 mt->nestedTypeIndexes_[1] = module_->IndexOf(valueType);
430 // end address
431 baseAddr_ = baseAddr_ + sizeof(int*) * typeNumber;
432 } else if (type->IsArrayType()) {
433 mt->nestedTypeNumber_ = 1;
434 // nestedTypeIndexes_'s address
435 baseAddr_ = ALIGN8(baseAddr_);
436 mt->nestedTypeIndexes_ = reinterpret_cast<int*>(baseAddr_);
437 AutoPtr<ASTType> elementType = (static_cast<ASTArrayType*>(type))->GetElementType();
438 mt->nestedTypeIndexes_[0] = module_->IndexOf(elementType);
439 // end address
440 baseAddr_ = baseAddr_ + sizeof(int*);
441 }
442
443 return mt;
444 }
445
WriteString(const std::string & string)446 char* MetadataBuilder::WriteString(const std::string& string)
447 {
448 return string.empty() ? nullptr : metaComponent_->stringPool_ + stringPool_.GetOffset(string);
449 }
450
Type2Kind(ASTType * type)451 MetaTypeKind MetadataBuilder::Type2Kind(ASTType* type)
452 {
453 if (type->IsCharType()) {
454 return MetaTypeKind::Char;
455 } else if (type->IsBooleanType()) {
456 return MetaTypeKind::Boolean;
457 } else if (type->IsByteType()) {
458 return MetaTypeKind::Byte;
459 } else if (type->IsShortType()) {
460 return MetaTypeKind::Short;
461 } else if (type->IsIntegerType()) {
462 return MetaTypeKind::Integer;
463 } else if (type->IsLongType()) {
464 return MetaTypeKind::Long;
465 } else if (type->IsFloatType()) {
466 return MetaTypeKind::Float;
467 } else if (type->IsDoubleType()) {
468 return MetaTypeKind::Double;
469 } else if (type->IsStringType()) {
470 return MetaTypeKind::String;
471 } else if (type->IsVoidType()) {
472 return MetaTypeKind::Void;
473 } else if (type->IsSequenceableType()) {
474 return MetaTypeKind::Sequenceable;
475 } else if (type->IsInterfaceType()) {
476 return MetaTypeKind::Interface;
477 } else if (type->IsListType()) {
478 return MetaTypeKind::List;
479 } else if (type->IsMapType()) {
480 return MetaTypeKind::Map;
481 } else if (type->IsArrayType()) {
482 return MetaTypeKind::Array;
483 }
484 return MetaTypeKind::Unknown;
485 }
486 } // namespace Idl
487 } // namespace OHOS
488