11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved.
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *  * Redistributions of source code must retain the above copyright
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *  * Redistributions in binary form must reproduce the above copyright
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    the documentation and/or other materials provided with the
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    distribution.
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE.
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef _LINKER_H_
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define _LINKER_H_
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
324a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov#include <dlfcn.h>
33afab3ffcce1054ec887fb347700819d69a9c8151Elliott Hughes#include <android/dlext.h>
349ec0f03a0d0b17bbb94ac0b9fef6add28a133c3aNick Kralevich#include <elf.h>
350d15094287fe0f288d9c258953143fc1998b6b5aDmitriy Ivanov#include <inttypes.h>
36b7beb6907599b36809effe1b4db76039ac649518Pavel Chupin#include <link.h>
37d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov#include <sys/stat.h>
38afab3ffcce1054ec887fb347700819d69a9c8151Elliott Hughes#include <unistd.h>
394688279db5dcc4004941e7f133c4a1c3617d842cElliott Hughes
40afab3ffcce1054ec887fb347700819d69a9c8151Elliott Hughes#include "private/bionic_page.h"
418f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes#include "private/libc_logging.h"
42d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov#include "linked_list.h"
43650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes
44aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov#include <string>
452a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov#include <vector>
46aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov
47650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes#define DL_ERR(fmt, x...) \
48650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes    do { \
49650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes      __libc_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \
50650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes      /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \
51650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes      DEBUG("%s\n", linker_get_error_buffer()); \
527e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes    } while (false)
537e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes
547e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes#define DL_WARN(fmt, x...) \
557e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes    do { \
567e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes      __libc_format_log(ANDROID_LOG_WARN, "linker", fmt, ##x); \
577e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes      __libc_format_fd(2, "WARNING: linker: "); \
587e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes      __libc_format_fd(2, fmt, ##x); \
597e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes      __libc_format_fd(2, "\n"); \
607e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes    } while (false)
617e5a8cc5230dcc027686813e51a1b001cee4c602Elliott Hughes
620266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes#if defined(__LP64__)
630266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes#define ELFW(what) ELF64_ ## what
640266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes#else
650266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes#define ELFW(what) ELF32_ ## what
660266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes#endif
67650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes
689918665a45095ad135576f005c0e5307feb366a1Chris Dearman// mips64 interprets Elf64_Rel structures' r_info field differently.
699918665a45095ad135576f005c0e5307feb366a1Chris Dearman// bionic (like other C libraries) has macros that assume regular ELF files,
709918665a45095ad135576f005c0e5307feb366a1Chris Dearman// but the dynamic linker needs to be able to load mips64 ELF files.
719918665a45095ad135576f005c0e5307feb366a1Chris Dearman#if defined(__mips__) && defined(__LP64__)
729918665a45095ad135576f005c0e5307feb366a1Chris Dearman#undef ELF64_R_SYM
739918665a45095ad135576f005c0e5307feb366a1Chris Dearman#undef ELF64_R_TYPE
749918665a45095ad135576f005c0e5307feb366a1Chris Dearman#undef ELF64_R_INFO
759918665a45095ad135576f005c0e5307feb366a1Chris Dearman#define ELF64_R_SYM(info)   (((info) >> 0) & 0xffffffff)
769918665a45095ad135576f005c0e5307feb366a1Chris Dearman#define ELF64_R_SSYM(info)  (((info) >> 32) & 0xff)
779918665a45095ad135576f005c0e5307feb366a1Chris Dearman#define ELF64_R_TYPE3(info) (((info) >> 40) & 0xff)
789918665a45095ad135576f005c0e5307feb366a1Chris Dearman#define ELF64_R_TYPE2(info) (((info) >> 48) & 0xff)
799918665a45095ad135576f005c0e5307feb366a1Chris Dearman#define ELF64_R_TYPE(info)  (((info) >> 56) & 0xff)
809918665a45095ad135576f005c0e5307feb366a1Chris Dearman#endif
819918665a45095ad135576f005c0e5307feb366a1Chris Dearman
82f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov#define FLAG_LINKED           0x00000001
83f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov#define FLAG_EXE              0x00000004 // The main executable
84f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov#define FLAG_LINKER           0x00000010 // The linker itself
85f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov#define FLAG_GNU_HASH         0x00000040 // uses gnu hash
86f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov#define FLAG_MAPPED_BY_CALLER 0x00000080 // the map is reserved by the caller
87f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov                                         // and should not be unmapped
88f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov#define FLAG_NEW_SOINFO       0x40000000 // new soinfo format
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
90d225a5e65223b375a63548c4b780f04d8f3d7b60Dmitriy Ivanov#define SUPPORTED_DT_FLAGS_1 (DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE)
91d225a5e65223b375a63548c4b780f04d8f3d7b60Dmitriy Ivanov
9242d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov#define SOINFO_VERSION 3
930d15094287fe0f288d9c258953143fc1998b6b5aDmitriy Ivanov
94280d54680d8842df5b0e37ec50acde48957d8e7aDmitriy Ivanov#if defined(__work_around_b_24465209__)
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SOINFO_NAME_LEN 128
96aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov#endif
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
98ca0c11bd823f37f03cc8067cb182876827d5275aElliott Hughestypedef void (*linker_function_t)();
99ca0c11bd823f37f03cc8067cb182876827d5275aElliott Hughes
1009918665a45095ad135576f005c0e5307feb366a1Chris Dearman// Android uses RELA for aarch64 and x86_64. mips64 still uses REL.
1019918665a45095ad135576f005c0e5307feb366a1Chris Dearman#if defined(__aarch64__) || defined(__x86_64__)
1024eeb1f12a8b63afc0d0ad4d466b16fbffb21cd5aElliott Hughes#define USE_RELA 1
1034eeb1f12a8b63afc0d0ad4d466b16fbffb21cd5aElliott Hughes#endif
1044eeb1f12a8b63afc0d0ad4d466b16fbffb21cd5aElliott Hughes
105d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanovstruct soinfo;
106d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov
107d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanovclass SoinfoListAllocator {
108ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov public:
109d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  static LinkedListEntry<soinfo>* alloc();
110d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  static void free(LinkedListEntry<soinfo>* entry);
111ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov
112ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov private:
113d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  // unconstructable
114d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator);
115d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov};
116d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov
1170551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanovclass NamespaceListAllocator {
1180551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov public:
1190551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov  static LinkedListEntry<android_namespace_t>* alloc();
1200551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov  static void free(LinkedListEntry<android_namespace_t>* entry);
1210551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov
1220551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov private:
1230551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov  // unconstructable
1240551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov  DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceListAllocator);
1250551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov};
1260551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov
127ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanovclass SymbolName {
128ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov public:
129ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  explicit SymbolName(const char* name)
130ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov      : name_(name), has_elf_hash_(false), has_gnu_hash_(false),
131ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov        elf_hash_(0), gnu_hash_(0) { }
132ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov
133ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  const char* get_name() {
134ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov    return name_;
135ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  }
136ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov
137ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  uint32_t elf_hash();
138ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  uint32_t gnu_hash();
139ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov
140ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov private:
141ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  const char* name_;
142ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  bool has_elf_hash_;
143ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  bool has_gnu_hash_;
144ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  uint32_t elf_hash_;
145ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  uint32_t gnu_hash_;
146ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov
147ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName);
148ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov};
149ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov
1502a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanovstruct version_info {
1514a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov  constexpr version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {}
1522a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
1532a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  uint32_t elf_hash;
1542a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  const char* name;
1552a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  const soinfo* target_si;
1562a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov};
1572a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
1582a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov// Class used construct version dependency graph.
1592a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanovclass VersionTracker {
1602a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov public:
1612a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  VersionTracker() = default;
1622a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  bool init(const soinfo* si_from);
1632a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
1642a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  const version_info* get_version_info(ElfW(Versym) source_symver) const;
1652a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov private:
1662a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  bool init_verneed(const soinfo* si_from);
1672a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  bool init_verdef(const soinfo* si_from);
1682a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  void add_version_info(size_t source_index, ElfW(Word) elf_hash,
1692a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov      const char* ver_name, const soinfo* target_si);
1702a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
1712a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  std::vector<version_info> version_infos;
1722a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
1732a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  DISALLOW_COPY_AND_ASSIGN(VersionTracker);
1742a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov};
1752a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
17618a206c81d9743481e364384affd43306911283dElliott Hughesstruct soinfo {
177ca0c11bd823f37f03cc8067cb182876827d5275aElliott Hughes public:
178d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
1790551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov  typedef LinkedList<android_namespace_t, NamespaceListAllocator> android_namespace_list_t;
180280d54680d8842df5b0e37ec50acde48957d8e7aDmitriy Ivanov#if defined(__work_around_b_24465209__)
181aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov private:
182aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov  char old_name_[SOINFO_NAME_LEN];
183aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov#endif
184d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov public:
1850266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes  const ElfW(Phdr)* phdr;
186ca0c11bd823f37f03cc8067cb182876827d5275aElliott Hughes  size_t phnum;
1870266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes  ElfW(Addr) entry;
1880266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes  ElfW(Addr) base;
1895ceb889ac9a36e74e4e00c34c57cbb58d73e228cWeiwu Chen  size_t size;
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
191280d54680d8842df5b0e37ec50acde48957d8e7aDmitriy Ivanov#if defined(__work_around_b_24465209__)
192ca0c11bd823f37f03cc8067cb182876827d5275aElliott Hughes  uint32_t unused1;  // DO NOT USE, maintained for compatibility.
193c620059479c47a78d57086d73726c9adc2f337adElliott Hughes#endif
19438bccb271f121fc06eaa0d8fbd3c982bc44c36b7Nick Kralevich
1950266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes  ElfW(Dyn)* dynamic;
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
197280d54680d8842df5b0e37ec50acde48957d8e7aDmitriy Ivanov#if defined(__work_around_b_24465209__)
198ca0c11bd823f37f03cc8067cb182876827d5275aElliott Hughes  uint32_t unused2; // DO NOT USE, maintained for compatibility
199ca0c11bd823f37f03cc8067cb182876827d5275aElliott Hughes  uint32_t unused3; // DO NOT USE, maintained for compatibility
200c620059479c47a78d57086d73726c9adc2f337adElliott Hughes#endif
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
202d23736e4f228e46304b7cbc674a1d0094d73e0f5Elliott Hughes  soinfo* next;
2036cdeb5234d7f4523fe9d83974f265d80f10512a6Dmitriy Ivanov private:
204ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  uint32_t flags_;
205ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov
206047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  const char* strtab_;
207047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  ElfW(Sym)* symtab_;
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
209047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t nbucket_;
210047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t nchain_;
211047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t* bucket_;
212047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t* chain_;
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2149918665a45095ad135576f005c0e5307feb366a1Chris Dearman#if defined(__mips__) || !defined(__LP64__)
2159918665a45095ad135576f005c0e5307feb366a1Chris Dearman  // This is only used by mips and mips64, but needs to be here for
2164eeb1f12a8b63afc0d0ad4d466b16fbffb21cd5aElliott Hughes  // all 32-bit architectures to preserve binary compatibility.
217047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  ElfW(Addr)** plt_got_;
2184eeb1f12a8b63afc0d0ad4d466b16fbffb21cd5aElliott Hughes#endif
2194eeb1f12a8b63afc0d0ad4d466b16fbffb21cd5aElliott Hughes
2204eeb1f12a8b63afc0d0ad4d466b16fbffb21cd5aElliott Hughes#if defined(USE_RELA)
221047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  ElfW(Rela)* plt_rela_;
222047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t plt_rela_count_;
223c00f2cb587630d5e954c7f548749f1e3170b3cb1Elliott Hughes
224047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  ElfW(Rela)* rela_;
225047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t rela_count_;
226c00f2cb587630d5e954c7f548749f1e3170b3cb1Elliott Hughes#else
227047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  ElfW(Rel)* plt_rel_;
228047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t plt_rel_count_;
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
230047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  ElfW(Rel)* rel_;
231047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t rel_count_;
232c00f2cb587630d5e954c7f548749f1e3170b3cb1Elliott Hughes#endif
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
234047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  linker_function_t* preinit_array_;
235047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t preinit_array_count_;
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
237047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  linker_function_t* init_array_;
238047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t init_array_count_;
239047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  linker_function_t* fini_array_;
240047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t fini_array_count_;
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
242047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  linker_function_t init_func_;
243047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  linker_function_t fini_func_;
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2454eeb1f12a8b63afc0d0ad4d466b16fbffb21cd5aElliott Hughes#if defined(__arm__)
246ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov public:
247d23736e4f228e46304b7cbc674a1d0094d73e0f5Elliott Hughes  // ARM EABI section used for stack unwinding.
2481b20dafdbe65e43b9f4c95057e8482380833ea91Dmitriy Ivanov  uint32_t* ARM_exidx;
249ca0c11bd823f37f03cc8067cb182876827d5275aElliott Hughes  size_t ARM_exidx_count;
250889409168322920ab6cddeb93f506c983d8b5878Dmitriy Ivanov private:
251ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov#elif defined(__mips__)
252047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t mips_symtabno_;
253047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t mips_local_gotno_;
254047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t mips_gotsym_;
255f39cb63603da949325b4d186e870d0c3de01eb30Dmitriy Ivanov  bool mips_relocate_got(const VersionTracker& version_tracker,
256f39cb63603da949325b4d186e870d0c3de01eb30Dmitriy Ivanov                         const soinfo_list_t& global_group,
257f39cb63603da949325b4d186e870d0c3de01eb30Dmitriy Ivanov                         const soinfo_list_t& local_group);
258bc425c73e07dc150d1dcb64889ca7d379dace410Duane Sand#if !defined(__LP64__)
259bc425c73e07dc150d1dcb64889ca7d379dace410Duane Sand  bool mips_check_and_adjust_fp_modes();
260bc425c73e07dc150d1dcb64889ca7d379dace410Duane Sand#endif
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
262ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  size_t ref_count_;
263047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov public:
2643a9c5d66dc8d41272f51482b713717af7049697eElliott Hughes  link_map link_map_head;
265e83c56dfbb6a9a61f0f18031620322af97e80162Evgeniy Stepanov
266d23736e4f228e46304b7cbc674a1d0094d73e0f5Elliott Hughes  bool constructors_called;
2679ec0f03a0d0b17bbb94ac0b9fef6add28a133c3aNick Kralevich
268d23736e4f228e46304b7cbc674a1d0094d73e0f5Elliott Hughes  // When you read a virtual address from the ELF file, add this
269d23736e4f228e46304b7cbc674a1d0094d73e0f5Elliott Hughes  // value to get the corresponding address in the process' address space.
2700266ae5f884d72da58f33a072e865ba131234a5eElliott Hughes  ElfW(Addr) load_bias;
2715ae44f302b7d1d19f25c4c6f125e32dc369961d9Ard Biesheuvel
27256be6ed9e4ac99fdd920090ee89c57e3cf55e885Dimitry Ivanov#if !defined(__LP64__)
27356be6ed9e4ac99fdd920090ee89c57e3cf55e885Dimitry Ivanov  bool has_text_relocations;
274e4d792adb8d6f9228b9ac9dc1ad7f43b271f085fElliott Hughes#endif
27596bc37f2e1093416a432135265fd7a4db6c3df17Dmitriy Ivanov  bool has_DT_SYMBOLIC;
2760d15094287fe0f288d9c258953143fc1998b6b5aDmitriy Ivanov
277047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov public:
27842d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat,
27942d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov         off64_t file_offset, int rtld_flags);
280ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9Dimitry Ivanov  ~soinfo();
2810d15094287fe0f288d9c258953143fc1998b6b5aDmitriy Ivanov
282047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  void call_constructors();
283047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  void call_destructors();
284047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  void call_pre_init_constructors();
285047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  bool prelink_image();
28620d89cb5b0d5eb7546a8fe8da44bbd91564dbddaDmitriy Ivanov  bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
28720d89cb5b0d5eb7546a8fe8da44bbd91564dbddaDmitriy Ivanov                  const android_dlextinfo* extinfo);
2889ce09e423f24823d52f19ab8247e078977100132Mingwei Shi  bool protect_relro();
289d23736e4f228e46304b7cbc674a1d0094d73e0f5Elliott Hughes
290d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  void add_child(soinfo* child);
291d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  void remove_all_links();
292d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov
293d225a5e65223b375a63548c4b780f04d8f3d7b60Dmitriy Ivanov  ino_t get_st_ino() const;
294d225a5e65223b375a63548c4b780f04d8f3d7b60Dmitriy Ivanov  dev_t get_st_dev() const;
295d225a5e65223b375a63548c4b780f04d8f3d7b60Dmitriy Ivanov  off64_t get_file_offset() const;
296c5a13efa9bc4264be0a9a9e37c00633af01584edBrigid Smith
297d225a5e65223b375a63548c4b780f04d8f3d7b60Dmitriy Ivanov  uint32_t get_rtld_flags() const;
298d225a5e65223b375a63548c4b780f04d8f3d7b60Dmitriy Ivanov  uint32_t get_dt_flags_1() const;
299d225a5e65223b375a63548c4b780f04d8f3d7b60Dmitriy Ivanov  void set_dt_flags_1(uint32_t dt_flags_1);
300e8ba50fe0d51fbefee1a8f5bb62bf51d841512c8Dmitriy Ivanov
301d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  soinfo_list_t& get_children();
3022a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  const soinfo_list_t& get_children() const;
3032a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
30414669a939d113214a4a20b9318fca0992d5453f0Dmitriy Ivanov  soinfo_list_t& get_parents();
305d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov
3062a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  bool find_symbol_by_name(SymbolName& symbol_name,
3072a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov                           const version_info* vi,
3082a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov                           const ElfW(Sym)** symbol) const;
3092a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
310ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  ElfW(Sym)* find_symbol_by_address(const void* addr);
3112a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const;
3129aea164457c269c475592da36b4655d45f55c7bcDmitriy Ivanov
3136cdeb5234d7f4523fe9d83974f265d80f10512a6Dmitriy Ivanov  const char* get_string(ElfW(Word) index) const;
3141b20dafdbe65e43b9f4c95057e8482380833ea91Dmitriy Ivanov  bool can_unload() const;
315ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  bool is_gnu_hash() const;
3166cdeb5234d7f4523fe9d83974f265d80f10512a6Dmitriy Ivanov
317aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov  bool inline has_min_version(uint32_t min_version __unused) const {
318280d54680d8842df5b0e37ec50acde48957d8e7aDmitriy Ivanov#if defined(__work_around_b_24465209__)
319ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov    return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
320aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov#else
321aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov    return true;
322aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov#endif
3230d15094287fe0f288d9c258953143fc1998b6b5aDmitriy Ivanov  }
3241b20dafdbe65e43b9f4c95057e8482380833ea91Dmitriy Ivanov
325ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  bool is_linked() const;
3269acb3b747ce2e9a526cc6510029a6b432f551856Dimitry Ivanov  bool is_linker() const;
327ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  bool is_main_executable() const;
328ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov
329ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  void set_linked();
330ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  void set_linker_flag();
331ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  void set_main_executable();
33242d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  void set_nodelete();
333ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov
334ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  void increment_ref_count();
335ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  size_t decrement_ref_count();
336ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov
337ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  soinfo* get_local_group_root() const;
338ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov
3394f7a7ad3fed2ea90d454ec9f3cabfffb0deda8c4Dmitriy Ivanov  void set_soname(const char* soname);
340aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov  const char* get_soname() const;
341aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov  const char* get_realpath() const;
3422a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  const ElfW(Versym)* get_versym(size_t n) const;
3432a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  ElfW(Addr) get_verneed_ptr() const;
3442a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  size_t get_verneed_cnt() const;
3452a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  ElfW(Addr) get_verdef_ptr() const;
3462a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  size_t get_verdef_cnt() const;
3472a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
3482a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  bool find_verdef_version_index(const version_info* vi, ElfW(Versym)* versym) const;
349618f1a36f8635fa0f2d60c621fbf79ead2c3f3deDmitriy Ivanov
3501913352c6b3501893dfb45189754970f9dc6e7bbDmitriy Ivanov  uint32_t get_target_sdk_version() const;
3511913352c6b3501893dfb45189754970f9dc6e7bbDmitriy Ivanov
3524f7a7ad3fed2ea90d454ec9f3cabfffb0deda8c4Dmitriy Ivanov  void set_dt_runpath(const char *);
3536865082ca6d887766c6651ed2d079dca56a99d32Evgenii Stepanov  const std::vector<std::string>& get_dt_runpath() const;
3540551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov  android_namespace_t* get_primary_namespace();
3550551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov  void add_secondary_namespace(android_namespace_t* secondary_ns);
3566865082ca6d887766c6651ed2d079dca56a99d32Evgenii Stepanov
357f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov  void set_mapped_by_caller(bool reserved_map);
358f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov  bool is_mapped_by_caller() const;
359f45b0e9edee72e97106c4b3d393b9bf1582303b3Dimitry Ivanov
360ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9Dimitry Ivanov  uintptr_t get_handle() const;
361ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9Dimitry Ivanov  void generate_handle();
362ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9Dimitry Ivanov  void* to_handle();
363ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9Dimitry Ivanov
364d23736e4f228e46304b7cbc674a1d0094d73e0f5Elliott Hughes private:
3652a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
366ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  ElfW(Sym)* elf_addr_lookup(const void* addr);
3672a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
368ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  ElfW(Sym)* gnu_addr_lookup(const void* addr);
369ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov
37031b408d2c2e070c35838e7859ca4a4e5eb0c45fcDmitriy Ivanov  bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
37131b408d2c2e070c35838e7859ca4a4e5eb0c45fcDmitriy Ivanov                           const char* sym_name, const version_info** vi);
37231b408d2c2e070c35838e7859ca4a4e5eb0c45fcDmitriy Ivanov
373047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  void call_array(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
374047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  void call_function(const char* function_name, linker_function_t function);
375fa26eee77685e8dee7986e62a7d263003f5bd25aDmitriy Ivanov  template<typename ElfRelIteratorT>
3767e4bbbae4a1e2034e6fa47ac2b0e1e7ca970acf0Dmitriy Ivanov  bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
3777e4bbbae4a1e2034e6fa47ac2b0e1e7ca970acf0Dmitriy Ivanov                const soinfo_list_t& global_group, const soinfo_list_t& local_group);
378d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov
379d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov private:
380d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  // This part of the structure is only available
381d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  // when FLAG_NEW_SOINFO is set in this->flags.
382047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t version_;
383c5a13efa9bc4264be0a9a9e37c00633af01584edBrigid Smith
3840d15094287fe0f288d9c258953143fc1998b6b5aDmitriy Ivanov  // version >= 0
385047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  dev_t st_dev_;
386047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  ino_t st_ino_;
387d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov
388d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  // dependency graph
389047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  soinfo_list_t children_;
390047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  soinfo_list_t parents_;
391d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov
3920d15094287fe0f288d9c258953143fc1998b6b5aDmitriy Ivanov  // version >= 1
393047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  off64_t file_offset_;
394047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t rtld_flags_;
395047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t dt_flags_1_;
396047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  size_t strtab_size_;
3976cdeb5234d7f4523fe9d83974f265d80f10512a6Dmitriy Ivanov
398ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov  // version >= 2
3993597b8055da090ef3f1ee662e96dcb952bba2c30Dmitriy Ivanov
4003597b8055da090ef3f1ee662e96dcb952bba2c30Dmitriy Ivanov  size_t gnu_nbucket_;
4013597b8055da090ef3f1ee662e96dcb952bba2c30Dmitriy Ivanov  uint32_t* gnu_bucket_;
4023597b8055da090ef3f1ee662e96dcb952bba2c30Dmitriy Ivanov  uint32_t* gnu_chain_;
403047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t gnu_maskwords_;
404047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  uint32_t gnu_shift2_;
405047b5934b5f1c62502fc9262ce634529c6cc1420Dmitriy Ivanov  ElfW(Addr)* gnu_bloom_filter_;
406ec18ce06f2d007be40ad6f043058f5a4c7236573Dmitriy Ivanov
407ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov  soinfo* local_group_root_;
408ab972b9adf8789a9e1b03129cd7f0c22e6bba117Dmitriy Ivanov
40918a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov  uint8_t* android_relocs_;
41018a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov  size_t android_relocs_size_;
41118a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov
412618f1a36f8635fa0f2d60c621fbf79ead2c3f3deDmitriy Ivanov  const char* soname_;
413aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov  std::string realpath_;
414618f1a36f8635fa0f2d60c621fbf79ead2c3f3deDmitriy Ivanov
4152a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  const ElfW(Versym)* versym_;
4162a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
4172a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  ElfW(Addr) verdef_ptr_;
4182a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  size_t verdef_cnt_;
4192a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
4202a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  ElfW(Addr) verneed_ptr_;
4212a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov  size_t verneed_cnt_;
4222a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov
4231913352c6b3501893dfb45189754970f9dc6e7bbDmitriy Ivanov  uint32_t target_sdk_version_;
4241913352c6b3501893dfb45189754970f9dc6e7bbDmitriy Ivanov
42542d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  // version >= 3
4266865082ca6d887766c6651ed2d079dca56a99d32Evgenii Stepanov  std::vector<std::string> dt_runpath_;
4270551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov  android_namespace_t* primary_namespace_;
4280551c1d47bad202ce6dd90757067bc0fd217497aDimitry Ivanov  android_namespace_list_t secondary_namespaces_;
429ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9Dimitry Ivanov  uintptr_t handle_;
4306865082ca6d887766c6651ed2d079dca56a99d32Evgenii Stepanov
4316cdeb5234d7f4523fe9d83974f265d80f10512a6Dmitriy Ivanov  friend soinfo* get_libdl_info();
4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project};
4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4342a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanovbool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
4352a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov                      soinfo** si_found_in, const soinfo::soinfo_list_t& global_group,
4362a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov                      const soinfo::soinfo_list_t& local_group, const ElfW(Sym)** symbol);
437114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov
438114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanovenum RelocationKind {
439114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov  kRelocAbsolute = 0,
440114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov  kRelocRelative,
441114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov  kRelocCopy,
442114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov  kRelocSymbol,
443114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov  kRelocMax
444114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov};
445114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov
446114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanovvoid count_relocation(RelocationKind kind);
447114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov
4481b20dafdbe65e43b9f4c95057e8482380833ea91Dmitriy Ivanovsoinfo* get_libdl_info();
4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
450a4aafd156068ee174012f28cd894dbecf0e4ab90Elliott Hughesvoid do_android_get_LD_LIBRARY_PATH(char*, size_t);
451cade4c36e7c9c62db3f476a0f9cfc329bac9acb7Elliott Hughesvoid do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
452ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9Dimitry Ivanovvoid* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo, void* caller_addr);
453ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9Dimitry Ivanovint do_dlclose(void* handle);
45416084168111cd7d2ac8a6b92e6fa6df5696928a5David 'Digit' Turner
4557271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanovint do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data);
4567271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanov
4574a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanovbool do_dlsym(void* handle, const char* sym_name, const char* sym_ver,
4584a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov              void* caller_addr, void** symbol);
45942d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
4604a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanovint do_dladdr(const void* addr, Dl_info* info);
461d23736e4f228e46304b7cbc674a1d0094d73e0f5Elliott Hughes
462d4ee82dfa3ba01baa10e3ca48fcb31a27b8a4e81Brian Carlstromvoid debuggerd_init();
4631728b2396591853345507a063ed6075dfd251706Elliott Hughesextern "C" abort_msg_t* g_abort_message;
4644688279db5dcc4004941e7f133c4a1c3617d842cElliott Hughes
465650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hugheschar* linker_get_error_buffer();
466650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughessize_t linker_get_error_buffer_size();
467650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes
46879fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanovvoid set_application_target_sdk_version(uint32_t target);
46979fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanovuint32_t get_application_target_sdk_version();
47079fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov
47119b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanovenum {
47219b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov  /* A regular namespace is the namespace with a custom search path that does
47319b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   * not impose any restrictions on the location of native libraries.
47419b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   */
47519b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov  ANDROID_NAMESPACE_TYPE_REGULAR = 0,
47619b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov
47719b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov  /* An isolated namespace requires all the libraries to be on the search path
47819b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   * or under permitted_when_isolated_path. The search path is the union of
47919b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   * ld_library_path and default_library_path.
48019b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   */
48119b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov  ANDROID_NAMESPACE_TYPE_ISOLATED = 1,
48219b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov
48319b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov  /* The shared namespace clones the list of libraries of the caller namespace upon creation
48419b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   * which means that they are shared between namespaces - the caller namespace and the new one
48519b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   * will use the same copy of a library if it was loaded prior to android_create_namespace call.
48619b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   *
48719b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   * Note that libraries loaded after the namespace is created will not be shared.
48819b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   *
48919b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   * Shared namespaces can be isolated or regular. Note that they do not inherit the search path nor
49019b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   * permitted_path from the caller's namespace.
49119b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov   */
49219b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov  ANDROID_NAMESPACE_TYPE_SHARED = 2,
49319b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov  ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
49419b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov                                           ANDROID_NAMESPACE_TYPE_ISOLATED,
49519b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov};
49619b669b00325bcbab4679c4e57c5d8d95f54decbDimitry Ivanov
4971ffec1cc4d0e283bb1ff6f49843769a3493b8d73Dmitriy Ivanovbool init_namespaces(const char* public_ns_sonames, const char* anon_ns_library_path);
49849cfc899a3708fae9175e44c0c02cd479fda8b36Dimitry Ivanovandroid_namespace_t* create_namespace(const void* caller_addr,
49949cfc899a3708fae9175e44c0c02cd479fda8b36Dimitry Ivanov                                      const char* name,
50049cfc899a3708fae9175e44c0c02cd479fda8b36Dimitry Ivanov                                      const char* ld_library_path,
50149cfc899a3708fae9175e44c0c02cd479fda8b36Dimitry Ivanov                                      const char* default_library_path,
50249cfc899a3708fae9175e44c0c02cd479fda8b36Dimitry Ivanov                                      uint64_t type,
50349cfc899a3708fae9175e44c0c02cd479fda8b36Dimitry Ivanov                                      const char* permitted_when_isolated_path,
50449cfc899a3708fae9175e44c0c02cd479fda8b36Dimitry Ivanov                                      android_namespace_t* parent_namespace);
50542d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
507