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