Home | History | Annotate | Download | only in linker
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #pragma once
     30 
     31 #include <android/api-level.h>
     32 
     33 #include <stdlib.h>
     34 #include <limits.h>
     35 #include "private/bionic_macros.h"
     36 
     37 #include <memory>
     38 #include <string>
     39 #include <vector>
     40 #include <unordered_map>
     41 
     42 class NamespaceLinkConfig {
     43  public:
     44   NamespaceLinkConfig() = default;
     45   NamespaceLinkConfig(const std::string& ns_name, const std::string& shared_libs,
     46                       bool allow_all_shared_libs)
     47       : ns_name_(ns_name), shared_libs_(shared_libs),
     48         allow_all_shared_libs_(allow_all_shared_libs) {}
     49 
     50   const std::string& ns_name() const {
     51     return ns_name_;
     52   }
     53 
     54   const std::string& shared_libs() const {
     55     return shared_libs_;
     56   }
     57 
     58   bool allow_all_shared_libs() const {
     59     return allow_all_shared_libs_;
     60   }
     61 
     62  private:
     63   std::string ns_name_;
     64   std::string shared_libs_;
     65   bool allow_all_shared_libs_;
     66 };
     67 
     68 class NamespaceConfig {
     69  public:
     70   explicit NamespaceConfig(const std::string& name)
     71       : name_(name), isolated_(false), visible_(false)
     72   {}
     73 
     74   const char* name() const {
     75     return name_.c_str();
     76   }
     77 
     78   bool isolated() const {
     79     return isolated_;
     80   }
     81 
     82   bool visible() const {
     83     return visible_;
     84   }
     85 
     86   const std::vector<std::string>& search_paths() const {
     87     return search_paths_;
     88   }
     89 
     90   const std::vector<std::string>& permitted_paths() const {
     91     return permitted_paths_;
     92   }
     93 
     94   const std::vector<NamespaceLinkConfig>& links() const {
     95     return namespace_links_;
     96   }
     97 
     98   void add_namespace_link(const std::string& ns_name, const std::string& shared_libs,
     99                           bool allow_all_shared_libs) {
    100     namespace_links_.push_back(NamespaceLinkConfig(ns_name, shared_libs, allow_all_shared_libs));
    101   }
    102 
    103   void set_isolated(bool isolated) {
    104     isolated_ = isolated;
    105   }
    106 
    107   void set_visible(bool visible) {
    108     visible_ = visible;
    109   }
    110 
    111   void set_search_paths(std::vector<std::string>&& search_paths) {
    112     search_paths_ = search_paths;
    113   }
    114 
    115   void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
    116     permitted_paths_ = permitted_paths;
    117   }
    118  private:
    119   const std::string name_;
    120   bool isolated_;
    121   bool visible_;
    122   std::vector<std::string> search_paths_;
    123   std::vector<std::string> permitted_paths_;
    124   std::vector<NamespaceLinkConfig> namespace_links_;
    125 
    126   DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceConfig);
    127 };
    128 
    129 class Config {
    130  public:
    131   Config() : target_sdk_version_(__ANDROID_API__) {}
    132 
    133   const std::vector<std::unique_ptr<NamespaceConfig>>& namespace_configs() const {
    134     return namespace_configs_;
    135   }
    136 
    137   const NamespaceConfig* default_namespace_config() const {
    138     auto it = namespace_configs_map_.find("default");
    139     return it == namespace_configs_map_.end() ? nullptr : it->second;
    140   }
    141 
    142   uint32_t target_sdk_version() const {
    143     return target_sdk_version_;
    144   }
    145 
    146   // note that this is one time event and therefore there is no need to
    147   // read every section of the config. Every linker instance needs at
    148   // most one configuration.
    149   // Returns false in case of an error. If binary config was not found
    150   // sets *config = nullptr.
    151   static bool read_binary_config(const char* ld_config_file_path,
    152                                  const char* binary_realpath,
    153                                  bool is_asan,
    154                                  const Config** config,
    155                                  std::string* error_msg);
    156 
    157   static std::string get_vndk_version_string(const char delimiter);
    158  private:
    159   void clear();
    160 
    161   void set_target_sdk_version(uint32_t target_sdk_version) {
    162     target_sdk_version_ = target_sdk_version;
    163   }
    164 
    165   NamespaceConfig* create_namespace_config(const std::string& name);
    166 
    167   std::vector<std::unique_ptr<NamespaceConfig>> namespace_configs_;
    168   std::unordered_map<std::string, NamespaceConfig*> namespace_configs_map_;
    169   uint32_t target_sdk_version_;
    170 
    171   DISALLOW_COPY_AND_ASSIGN(Config);
    172 };
    173