blob: 5c9c8c030fd38bace1c02a0cb7a0d9b1973306fb [file] [log] [blame]
/*
* 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 <functional>
#include <vector>
#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<std::string> 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<Namespace> 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