/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "linkerconfig/namespace.h" #include "linkerconfig/sectionbuilder.h" #include #include #include "linkerconfig/common.h" #include "linkerconfig/environment.h" #include "linkerconfig/log.h" #include "linkerconfig/namespacebuilder.h" #include "linkerconfig/section.h" using android::linkerconfig::contents::SectionType; using android::linkerconfig::modules::ApexInfo; using android::linkerconfig::modules::LibProvider; using android::linkerconfig::modules::LibProviders; using android::linkerconfig::modules::Namespace; using android::linkerconfig::modules::Section; using android::linkerconfig::modules::SharedLibs; namespace android { namespace linkerconfig { namespace contents { // Builds default section for the apex // For com.android.foo, // dir.com.android.foo = /apex/com.android.foo/bin // [com.android.foo] // additional.namespaces = system // namespace.default.... // namespace.system... Section BuildApexDefaultSection(Context& ctx, const ApexInfo& apex_info) { ctx.SetCurrentSection(SectionType::Other); bool target_apex_visible = apex_info.visible; std::set visible_apexes; if (apex_info.name == "com.android.art") { // ld.config.txt for the ART module needs to have the namespaces with public // and JNI libs visible since it runs dalvikvm and hence libnativeloader, // which builds classloader namespaces that may link to those libs. for (const auto& apex : ctx.GetApexModules()) { if (apex.jni_libs.size() > 0 || apex.public_libs.size() > 0) { visible_apexes.insert(apex.name); if (apex.name == apex_info.name) { target_apex_visible = true; } } } } std::vector namespaces; // If target APEX should be visible, then there will be two namespaces - // default and APEX namespace - with same set of libraries. To avoid any // confusion based on two same namespaces, and also to avoid loading same // library twice based on the namespace, use empty default namespace which // does not contain any search path and fully links to visible APEX namespace. if (target_apex_visible) { namespaces.emplace_back(BuildApexEmptyDefaultNamespace(ctx, apex_info)); } else { namespaces.emplace_back(BuildApexDefaultNamespace(ctx, apex_info)); } namespaces.emplace_back(BuildApexPlatformNamespace(ctx)); // Vendor APEXes can use libs provided by "vendor" // and Product APEXes can use libs provided by "product" if (android::linkerconfig::modules::IsTreblelizedDevice()) { if (apex_info.InVendor()) { namespaces.emplace_back(BuildRsNamespace(ctx)); auto vendor = BuildVendorNamespace(ctx, "vendor"); if (!vendor.GetProvides().empty()) { namespaces.emplace_back(std::move(vendor)); } if (android::linkerconfig::modules::IsVendorVndkVersionDefined()) { namespaces.emplace_back( BuildVndkNamespace(ctx, VndkUserPartition::Vendor)); if (android::linkerconfig::modules::IsVndkInSystemNamespace()) { namespaces.emplace_back(BuildVndkInSystemNamespace(ctx)); } } } else if (apex_info.InProduct()) { auto product = BuildProductNamespace(ctx, "product"); if (!product.GetProvides().empty()) { namespaces.emplace_back(std::move(product)); } if (android::linkerconfig::modules::IsProductVndkVersionDefined()) { namespaces.emplace_back( BuildVndkNamespace(ctx, VndkUserPartition::Product)); if (android::linkerconfig::modules::IsVndkInSystemNamespace()) { namespaces.emplace_back(BuildVndkInSystemNamespace(ctx)); } } } } LibProviders libs_providers; if (apex_info.InVendor()) { // In Vendor APEX, sphal namespace is not required and possible to cause // same library being loaded from two namespaces (sphal and vendor). As // SPHAL itself is not required from vendor (APEX) section, add vendor // namespace instead. libs_providers[":sphal"] = {LibProvider{ "vendor", std::bind(BuildVendorNamespace, ctx, "vendor"), SharedLibs{{}}, }}; } else { libs_providers[":sphal"] = {LibProvider{ "sphal", std::bind(BuildSphalNamespace, ctx), SharedLibs{{}}, }}; } bool in_vendor_with_vndk_enabled = !apex_info.InProduct() && android::linkerconfig::modules::IsVendorVndkVersionDefined(); bool in_product_with_vndk_enabled = apex_info.InProduct() && android::linkerconfig::modules::IsProductVndkVersionDefined(); if (in_vendor_with_vndk_enabled || in_product_with_vndk_enabled) { VndkUserPartition user_partition = VndkUserPartition::Vendor; std::string user_partition_suffix = "VENDOR"; if (apex_info.InProduct()) { user_partition = VndkUserPartition::Product; user_partition_suffix = "PRODUCT"; } libs_providers[":sanitizer"] = {LibProvider{ ctx.GetSystemNamespaceName(), std::bind(BuildApexPlatformNamespace, ctx), // "system" should be available SharedLibs{{Var("SANITIZER_DEFAULT_" + user_partition_suffix)}}, }}; libs_providers[":vndk"] = GetVndkProvider(ctx, user_partition); libs_providers[":vndksp"] = {LibProvider{ "vndk", std::bind(BuildVndkNamespace, ctx, user_partition), SharedLibs{{Var("VNDK_SAMEPROCESS_LIBRARIES_" + user_partition_suffix)}}, }}; } else if (apex_info.InProduct() || apex_info.InVendor()) { // vendor or product partitions don't need this because they link LLNDK // libs. however, vendor/product apexes still need to link LLNDK sanitizer // libs even though these are not listed in "required". libs_providers[":sanitizer"] = {LibProvider{ ctx.GetSystemNamespaceName(), std::bind(BuildApexPlatformNamespace, ctx), // "system" should be available SharedLibs{{Var("SANITIZER_LIBRARIES_LLNDK")}}, }}; } if (apex_info.InVendor()) { AddVendorSubdirNamespaceProviders(ctx, libs_providers); } return BuildSection( ctx, apex_info.name, std::move(namespaces), visible_apexes, libs_providers); } } // namespace contents } // namespace linkerconfig } // namespace android