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 25namespace OHOS { 26namespace Idl { 27std::string MetadataBuilder::tag_ = "MetadataBuilder"; 28std::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 53size_t MetadataBuilder::CalculateMetadataSize() 54{ 55 baseAddr_ = 0; 56 CalculateMetaComponent(module_); 57 return baseAddr_; 58} 59 60void 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 102void 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 125void 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 135void 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 154void 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 172void 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 181void 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 200void MetadataBuilder::CalculateStringPool() 201{ 202 // begin address 203 baseAddr_ = ALIGN8(baseAddr_); 204 // end address 205 baseAddr_ = baseAddr_ + stringPool_.GetSize(); 206} 207 208void MetadataBuilder::WriteMetadata(uintptr_t base) 209{ 210 baseAddr_ = base; 211 WriteMetaComponent(module_); 212} 213 214void 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 271MetaNamespace* 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 314MetaSequenceable* 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 327MetaInterface* 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 353MetaMethod* 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 378MetaParameter* 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 397MetaType* 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 446char* MetadataBuilder::WriteString(const std::string& string) 447{ 448 return string.empty() ? nullptr : metaComponent_->stringPool_ + stringPool_.GetOffset(string); 449} 450 451MetaTypeKind 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