13f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov/*
23f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * Copyright (C) 2016 The Android Open Source Project
33f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * All rights reserved.
43f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *
53f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * Redistribution and use in source and binary forms, with or without
63f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * modification, are permitted provided that the following conditions
73f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * are met:
83f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *  * Redistributions of source code must retain the above copyright
93f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *    notice, this list of conditions and the following disclaimer.
103f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *  * Redistributions in binary form must reproduce the above copyright
113f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *    notice, this list of conditions and the following disclaimer in
123f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *    the documentation and/or other materials provided with the
133f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *    distribution.
143f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *
153f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
163f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
173f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
183f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
193f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
203f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
213f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
223f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
233f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
243f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
253f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
263f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * SUCH DAMAGE.
273f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov */
283f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
293f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "linker_main.h"
303f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
313f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "linker_debug.h"
320a3637d3eb2424d8e825ad1825f843450a888406Evgenii Stepanov#include "linker_cfi.h"
333f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "linker_gdb_support.h"
343f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "linker_globals.h"
353f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "linker_phdr.h"
363f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "linker_utils.h"
373f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
383f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "private/bionic_globals.h"
393f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "private/bionic_tls.h"
403f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "private/KernelArgumentBlock.h"
413f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
423f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "android-base/strings.h"
433f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include "android-base/stringprintf.h"
447ec52b12efc1c4ed9cd83ba8c95fab5bbf39aaf4Dan Willemsen#ifdef __ANDROID__
452a3b4fa6ec9ab3d4604860b0bdd3766c9f5c44f4Josh Gao#include "debuggerd/handler.h"
467ec52b12efc1c4ed9cd83ba8c95fab5bbf39aaf4Dan Willemsen#endif
473f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
487a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris#include <async_safe/log.h>
497a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris
503f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#include <vector>
513f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
523f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovextern void __libc_init_globals(KernelArgumentBlock&);
533f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovextern void __libc_init_AT_SECURE(KernelArgumentBlock&);
543f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
553f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovextern "C" void _start();
563f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
573f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf);
583f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
593f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov// These should be preserved static to avoid emitting
603f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov// RELATIVE relocations for the part of the code running
613f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov// before linker links itself.
623f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
633f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov// TODO (dimtiry): remove somain, rename solist to solist_head
643f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic soinfo* solist;
653f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic soinfo* sonext;
663f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic soinfo* somain; // main process, always the one after libdl_info
6769c68c46ac18a440bf1c0447d8343a6dbad595f1dimitrystatic soinfo* vdso; // vdso if present
683f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
693f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovvoid solist_add_soinfo(soinfo* si) {
703f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  sonext->next = si;
713f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  sonext = si;
723f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
733f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
743f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovbool solist_remove_soinfo(soinfo* si) {
753f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  soinfo *prev = nullptr, *trav;
763f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  for (trav = solist; trav != nullptr; trav = trav->next) {
773f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    if (trav == si) {
783f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      break;
793f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    }
803f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    prev = trav;
813f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
823f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
833f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (trav == nullptr) {
843f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    // si was not in solist
853f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    PRINT("name \"%s\"@%p is not in solist!", si->get_realpath(), si);
863f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    return false;
873f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
883f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
893f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // prev will never be null, because the first entry in solist is
903f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // always the static libdl_info.
91705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV  CHECK(prev != nullptr);
923f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  prev->next = si->next;
933f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (si == sonext) {
943f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    sonext = prev;
953f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
963f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
973f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  return true;
983f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
993f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1003f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovsoinfo* solist_get_head() {
1013f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  return solist;
1023f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
1033f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1043f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovsoinfo* solist_get_somain() {
1053f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  return somain;
1063f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
1073f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
10869c68c46ac18a440bf1c0447d8343a6dbad595f1dimitrysoinfo* solist_get_vdso() {
10969c68c46ac18a440bf1c0447d8343a6dbad595f1dimitry  return vdso;
11069c68c46ac18a440bf1c0447d8343a6dbad595f1dimitry}
11169c68c46ac18a440bf1c0447d8343a6dbad595f1dimitry
1123f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovint g_ld_debug_verbosity;
1133f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovabort_msg_t* g_abort_message = nullptr; // For debuggerd.
1143f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1153f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic std::vector<std::string> g_ld_preload_names;
1163f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1173f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic std::vector<soinfo*> g_ld_preloads;
1183f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1193f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic void parse_path(const char* path, const char* delimiters,
1203f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov                       std::vector<std::string>* resolved_paths) {
1213f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  std::vector<std::string> paths;
1223f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  split_path(path, delimiters, &paths);
1233f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  resolve_paths(paths, resolved_paths);
1243f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
1253f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1263f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic void parse_LD_LIBRARY_PATH(const char* path) {
1273f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  std::vector<std::string> ld_libary_paths;
1283f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  parse_path(path, ":", &ld_libary_paths);
1293f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  g_default_namespace.set_ld_library_paths(std::move(ld_libary_paths));
1303f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
1313f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1323f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic void parse_LD_PRELOAD(const char* path) {
1333f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  g_ld_preload_names.clear();
1343f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (path != nullptr) {
1353f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    // We have historically supported ':' as well as ' ' in LD_PRELOAD.
1363f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    g_ld_preload_names = android::base::Split(path, " :");
13744f6e189d97fa3e07e2a95605d4ecd76bc73b103Josh Gao    g_ld_preload_names.erase(std::remove_if(g_ld_preload_names.begin(), g_ld_preload_names.end(),
13827242c642eac64d4d47a1899af341170c9456d79Josh Gao                                            [](const std::string& s) { return s.empty(); }),
13927242c642eac64d4d47a1899af341170c9456d79Josh Gao                             g_ld_preload_names.end());
1403f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
1413f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
1423f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1433f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov// An empty list of soinfos
1443f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic soinfo_list_t g_empty_list;
1453f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
146f9abbf69838bd8649d51fe3b8b6550fc14462757dimitrystatic void add_vdso(KernelArgumentBlock& args) {
1473f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  ElfW(Ehdr)* ehdr_vdso = reinterpret_cast<ElfW(Ehdr)*>(args.getauxval(AT_SYSINFO_EHDR));
1483f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (ehdr_vdso == nullptr) {
1493f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    return;
1503f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
1513f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1523f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  soinfo* si = soinfo_alloc(&g_default_namespace, "[vdso]", nullptr, 0, 0);
1533f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1543f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->phdr = reinterpret_cast<ElfW(Phdr)*>(reinterpret_cast<char*>(ehdr_vdso) + ehdr_vdso->e_phoff);
1553f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->phnum = ehdr_vdso->e_phnum;
1563f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->base = reinterpret_cast<ElfW(Addr)>(ehdr_vdso);
1573f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->size = phdr_table_get_load_size(si->phdr, si->phnum);
1583f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->load_bias = get_elf_exec_load_bias(ehdr_vdso);
1593f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1603f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->prelink_image();
1613f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr);
162c18de1bd47a558c9a24c6a4645df27df2c4738b4dimitry  // prevents accidental unloads...
163c18de1bd47a558c9a24c6a4645df27df2c4738b4dimitry  si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_NODELETE);
164c18de1bd47a558c9a24c6a4645df27df2c4738b4dimitry  si->set_linked();
165c18de1bd47a558c9a24c6a4645df27df2c4738b4dimitry  si->call_constructors();
16669c68c46ac18a440bf1c0447d8343a6dbad595f1dimitry
16769c68c46ac18a440bf1c0447d8343a6dbad595f1dimitry  vdso = si;
1683f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
1693f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1703f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov/* gdb expects the linker to be in the debug shared object list.
1713f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * Without this, gdb has trouble locating the linker's ".text"
1723f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * and ".plt" sections. Gdb could also potentially use this to
1733f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * relocate the offset of our exported 'rtld_db_dlactivity' symbol.
1743f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * Note that the linker shouldn't be on the soinfo list.
1753f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov */
176cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanovstatic link_map linker_link_map;
1773f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
178cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanovstatic void init_linker_info_for_gdb(ElfW(Addr) linker_base, char* linker_path) {
179cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov  linker_link_map.l_addr = linker_base;
180cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov  linker_link_map.l_name = linker_path;
1813f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1823f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  /*
1833f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov   * Set the dynamic field in the link map otherwise gdb will complain with
1843f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov   * the following:
1853f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov   *   warning: .dynamic section for "/system/bin/linker" is not at the
1863f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov   *   expected address (wrong library or version mismatch?)
1873f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov   */
1883f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_base);
1893f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_base + elf_hdr->e_phoff);
1903f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  phdr_table_get_dynamic_section(phdr, elf_hdr->e_phnum, linker_base,
191cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov                                 &linker_link_map.l_ld, nullptr);
1923f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1933f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
1943f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1953f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovextern "C" int __system_properties_init(void);
1963f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
1973f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic const char* get_executable_path() {
1983f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  static std::string executable_path;
1993f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (executable_path.empty()) {
2003f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    char path[PATH_MAX];
2013f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
2023f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
2037a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris      async_safe_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno));
2043f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    }
2053f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    executable_path = std::string(path, path_len);
2063f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
2073f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
2083f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  return executable_path.c_str();
2093f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
2103f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
211d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov#if defined(__LP64__)
212d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanovstatic char kLinkerPath[] = "/system/bin/linker64";
213d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov#else
214d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanovstatic char kLinkerPath[] = "/system/bin/linker";
215d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov#endif
216d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov
217ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughesstatic void __linker_cannot_link(const char* argv0) {
21804f7a798cff26c1809138d329e0a5717efc2b3c5dimitry  async_safe_format_fd(STDERR_FILENO,
21904f7a798cff26c1809138d329e0a5717efc2b3c5dimitry                       "CANNOT LINK EXECUTABLE \"%s\": %s\n",
22004f7a798cff26c1809138d329e0a5717efc2b3c5dimitry                       argv0,
22104f7a798cff26c1809138d329e0a5717efc2b3c5dimitry                       linker_get_error_buffer());
22204f7a798cff26c1809138d329e0a5717efc2b3c5dimitry
22304f7a798cff26c1809138d329e0a5717efc2b3c5dimitry  async_safe_format_log(ANDROID_LOG_FATAL,
22404f7a798cff26c1809138d329e0a5717efc2b3c5dimitry                        "linker",
22504f7a798cff26c1809138d329e0a5717efc2b3c5dimitry                        "CANNOT LINK EXECUTABLE \"%s\": %s",
22604f7a798cff26c1809138d329e0a5717efc2b3c5dimitry                        argv0,
22704f7a798cff26c1809138d329e0a5717efc2b3c5dimitry                        linker_get_error_buffer());
22804f7a798cff26c1809138d329e0a5717efc2b3c5dimitry  _exit(EXIT_FAILURE);
229ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes}
230ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes
2313f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov/*
2323f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * This code is called after the linker has linked itself and
2333f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * fixed it's own GOT. It is safe to make references to externs
2343f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * and other non-local data at this point.
2353f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov */
236cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanovstatic ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) {
2374cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov  ProtectedDataGuard guard;
2384cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov
2393f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#if TIMING
2403f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  struct timeval t0, t1;
2413f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  gettimeofday(&t0, 0);
2423f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#endif
2433f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
2443f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Sanitize the environment.
2453f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  __libc_init_AT_SECURE(args);
2463f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
2473f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Initialize system properties
2483f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  __system_properties_init(); // may use 'environ'
2493f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
2503f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Register the debuggerd signal handler.
2517ec52b12efc1c4ed9cd83ba8c95fab5bbf39aaf4Dan Willemsen#ifdef __ANDROID__
2523f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  debuggerd_callbacks_t callbacks = {
2533f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    .get_abort_message = []() {
2543f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      return g_abort_message;
2553f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    },
2563f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    .post_dump = &notify_gdb_of_libraries,
2573f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  };
2583f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  debuggerd_init(&callbacks);
2597ec52b12efc1c4ed9cd83ba8c95fab5bbf39aaf4Dan Willemsen#endif
2603f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
2613f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  g_linker_logger.ResetState();
2623f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
2633f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Get a few environment variables.
2643f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  const char* LD_DEBUG = getenv("LD_DEBUG");
2653f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (LD_DEBUG != nullptr) {
2663f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    g_ld_debug_verbosity = atoi(LD_DEBUG);
2673f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
2683f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
2693f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#if defined(__LP64__)
2703f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  INFO("[ Android dynamic linker (64-bit) ]");
2713f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#else
2723f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  INFO("[ Android dynamic linker (32-bit) ]");
2733f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#endif
2743f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
2753f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // These should have been sanitized by __libc_init_AT_SECURE, but the test
2763f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // doesn't cost us anything.
2773f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  const char* ldpath_env = nullptr;
2783f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  const char* ldpreload_env = nullptr;
2793f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (!getauxval(AT_SECURE)) {
2803f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    ldpath_env = getenv("LD_LIBRARY_PATH");
2813f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    if (ldpath_env != nullptr) {
2823f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      INFO("[ LD_LIBRARY_PATH set to \"%s\" ]", ldpath_env);
2833f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    }
2843f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    ldpreload_env = getenv("LD_PRELOAD");
2853f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    if (ldpreload_env != nullptr) {
2863f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      INFO("[ LD_PRELOAD set to \"%s\" ]", ldpreload_env);
2873f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    }
2883f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
2893f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
29069c68c46ac18a440bf1c0447d8343a6dbad595f1dimitry  add_vdso(args);
29169c68c46ac18a440bf1c0447d8343a6dbad595f1dimitry
2923f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  struct stat file_stat;
2933f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Stat "/proc/self/exe" instead of executable_path because
2943f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // the executable could be unlinked by this point and it should
2953f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // not cause a crash (see http://b/31084669)
2963f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (TEMP_FAILURE_RETRY(stat("/proc/self/exe", &file_stat)) != 0) {
2977a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris    async_safe_fatal("unable to stat \"/proc/self/exe\": %s", strerror(errno));
2983f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
2993f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3003f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  const char* executable_path = get_executable_path();
3013f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  soinfo* si = soinfo_alloc(&g_default_namespace, executable_path, &file_stat, 0, RTLD_GLOBAL);
3023f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3037b0af7ad82fcf88e800d1a553d81fda29dc064bdElliott Hughes  // Bootstrap the link map, the main exe always needs to be first.
3043f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->set_main_executable();
3053f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  link_map* map = &(si->link_map_head);
3063f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3073f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Register the main executable and the linker upfront to have
3083f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // gdb aware of them before loading the rest of the dependency
3093f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // tree.
3103f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  map->l_addr = 0;
3113f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  map->l_name = const_cast<char*>(executable_path);
3123f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  insert_link_map_into_debug_map(map);
313cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov  insert_link_map_into_debug_map(&linker_link_map);
3143f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3153f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Extract information passed from the kernel.
3163f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->phdr = reinterpret_cast<ElfW(Phdr)*>(args.getauxval(AT_PHDR));
3173f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->phnum = args.getauxval(AT_PHNUM);
3183f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3193f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  /* Compute the value of si->base. We can't rely on the fact that
3203f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov   * the first entry is the PHDR because this will not be true
3213f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov   * for certain executables (e.g. some in the NDK unit test suite)
3223f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov   */
3233f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->base = 0;
3243f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->size = phdr_table_get_load_size(si->phdr, si->phnum);
3253f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->load_bias = 0;
3263f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  for (size_t i = 0; i < si->phnum; ++i) {
3273f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    if (si->phdr[i].p_type == PT_PHDR) {
3283f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      si->load_bias = reinterpret_cast<ElfW(Addr)>(si->phdr) - si->phdr[i].p_vaddr;
3293f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      si->base = reinterpret_cast<ElfW(Addr)>(si->phdr) - si->phdr[i].p_offset;
3303f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      break;
3313f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    }
3323f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
333705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV
334705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV  if (si->base == 0) {
335705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV    async_safe_fatal("Could not find a PHDR: broken executable?");
336705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV  }
337705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV
3383f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->dynamic = nullptr;
3393f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3403f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base);
3413bdb31b51b353d12e482d28d6ffe115944f8819eElliott Hughes
3423bdb31b51b353d12e482d28d6ffe115944f8819eElliott Hughes  // We haven't supported non-PIE since Lollipop for security reasons.
3433f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (elf_hdr->e_type != ET_DYN) {
344ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes    // We don't use async_safe_fatal here because we don't want a tombstone:
345ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes    // even after several years we still find ourselves on app compatibility
3463bdb31b51b353d12e482d28d6ffe115944f8819eElliott Hughes    // investigations because some app's trying to launch an executable that
3473bdb31b51b353d12e482d28d6ffe115944f8819eElliott Hughes    // hasn't worked in at least three years, and we've "helpfully" dropped a
3483bdb31b51b353d12e482d28d6ffe115944f8819eElliott Hughes    // tombstone for them. The tombstone never provided any detail relevant to
3493bdb31b51b353d12e482d28d6ffe115944f8819eElliott Hughes    // fixing the problem anyway, and the utility of drawing extra attention
3503bdb31b51b353d12e482d28d6ffe115944f8819eElliott Hughes    // to the problem is non-existent at this late date.
3517a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris    async_safe_format_fd(STDERR_FILENO,
352ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes                         "\"%s\": error: Android 5.0 and later only support "
353ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes                         "position-independent executables (-fPIE).\n",
354ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes                         g_argv[0]);
35595e2e6f6204ea02de9e0dad9bd274e3c5d51a88cDan Albert    exit(EXIT_FAILURE);
3563f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
3573f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3583f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
3593f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  parse_LD_LIBRARY_PATH(ldpath_env);
3603f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  parse_LD_PRELOAD(ldpreload_env);
3613f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3623f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  somain = si;
3633f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
36402586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park  std::vector<android_namespace_t*> namespaces = init_default_namespaces(executable_path);
3653f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
366ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes  if (!si->prelink_image()) __linker_cannot_link(g_argv[0]);
3673f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3683f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // add somain to global group
3693f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
37002586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park  // ... and add it to all other linked namespaces
37102586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park  for (auto linked_ns : namespaces) {
37202586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park    if (linked_ns != &g_default_namespace) {
37302586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park      linked_ns->add_soinfo(somain);
37402586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park      somain->add_secondary_namespace(linked_ns);
37502586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park    }
37602586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park  }
3773f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3783f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Load ld_preloads and dependencies.
3793f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  std::vector<const char*> needed_library_name_list;
3803f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  size_t ld_preloads_count = 0;
3813f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3823f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  for (const auto& ld_preload_name : g_ld_preload_names) {
3833f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    needed_library_name_list.push_back(ld_preload_name.c_str());
3843f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    ++ld_preloads_count;
3853f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
3863f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3873f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  for_each_dt_needed(si, [&](const char* name) {
3883f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    needed_library_name_list.push_back(name);
3893f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  });
3903f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3913f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  const char** needed_library_names = &needed_library_name_list[0];
3923f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  size_t needed_libraries_count = needed_library_name_list.size();
3933f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
3943f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (needed_libraries_count > 0 &&
3957d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov      !find_libraries(&g_default_namespace,
3967d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov                      si,
3977d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov                      needed_library_names,
3987d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov                      needed_libraries_count,
3997d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov                      nullptr,
4007d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov                      &g_ld_preloads,
4017d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov                      ld_preloads_count,
4027d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov                      RTLD_GLOBAL,
4037d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov                      nullptr,
4047d429d3c480166e1013bcdf68f4be479209aa509Dimitry Ivanov                      true /* add_as_children */,
40502586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park                      true /* search_linked_namespaces */,
40602586a2a34e6acfccf359b94db840f422b6c0231Jiyong Park                      &namespaces)) {
407ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes    __linker_cannot_link(g_argv[0]);
4083f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  } else if (needed_libraries_count == 0) {
4093f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    if (!si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr)) {
410ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes      __linker_cannot_link(g_argv[0]);
4113f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    }
4123f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    si->increment_ref_count();
4133f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
4143f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
415ad2d0380a69db3066d49c5a67b85d6858236012fElliott Hughes  if (!get_cfi_shadow()->InitialLinkDone(solist)) __linker_cannot_link(g_argv[0]);
4160a3637d3eb2424d8e825ad1825f843450a888406Evgenii Stepanov
4174cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov  si->call_pre_init_constructors();
4183f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
4194cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov  /* After the prelink_image, the si->load_bias is initialized.
4204cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov   * For so lib, the map->l_addr will be updated in notify_gdb_of_load.
4214cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov   * We need to update this value for so exe here. So Unwind_Backtrace
4224cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov   * for some arch like x86 could work correctly within so exe.
4234cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov   */
4244cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov  map->l_addr = si->load_bias;
4254cabfaad340c957ff691cfbc420b29da805c5dd8Dimitry Ivanov  si->call_constructors();
4263f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
4273f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#if TIMING
4283f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  gettimeofday(&t1, nullptr);
4293f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  PRINT("LINKER TIME: %s: %d microseconds", g_argv[0], (int) (
4303f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov           (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) -
4313f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov           (((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec)));
4323f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#endif
4333f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#if STATS
4343f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  PRINT("RELO STATS: %s: %d abs, %d rel, %d copy, %d symbol", g_argv[0],
4353f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov         linker_stats.count[kRelocAbsolute],
4363f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov         linker_stats.count[kRelocRelative],
4373f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov         linker_stats.count[kRelocCopy],
4383f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov         linker_stats.count[kRelocSymbol]);
4393f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#endif
4403f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#if COUNT_PAGES
4413f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  {
4423f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    unsigned n;
4433f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    unsigned i;
4443f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    unsigned count = 0;
4453f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    for (n = 0; n < 4096; n++) {
4463f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      if (bitmask[n]) {
4473f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov        unsigned x = bitmask[n];
4483f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#if defined(__LP64__)
4493f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov        for (i = 0; i < 32; i++) {
4503f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#else
4513f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov        for (i = 0; i < 8; i++) {
4523f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#endif
4533f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov          if (x & 1) {
4543f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov            count++;
4553f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov          }
4563f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov          x >>= 1;
4573f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov        }
4583f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      }
4593f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    }
4603f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    PRINT("PAGES MODIFIED: %s: %d (%dKB)", g_argv[0], count, count * 4);
4613f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
4623f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#endif
4633f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
4643f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#if TIMING || STATS || COUNT_PAGES
4653f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  fflush(stdout);
4663f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#endif
4673f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
4683f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  ElfW(Addr) entry = args.getauxval(AT_ENTRY);
4693f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  TRACE("[ Ready to execute \"%s\" @ %p ]", si->get_realpath(), reinterpret_cast<void*>(entry));
4703f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  return entry;
4713f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
4723f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
4733f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov/* Compute the load-bias of an existing executable. This shall only
4743f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * be used to compute the load bias of an executable or shared library
4753f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * that was loaded by the kernel itself.
4763f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *
4773f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * Input:
4783f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *    elf    -> address of ELF header, assumed to be at the start of the file.
4793f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * Return:
4803f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *    load bias, i.e. add the value of any p_vaddr in the file to get
4813f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *    the corresponding address in memory.
4823f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov */
4833f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovstatic ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf) {
4843f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  ElfW(Addr) offset = elf->e_phoff;
4853f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  const ElfW(Phdr)* phdr_table =
4863f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      reinterpret_cast<const ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(elf) + offset);
4873f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  const ElfW(Phdr)* phdr_end = phdr_table + elf->e_phnum;
4883f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
4893f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_end; phdr++) {
4903f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    if (phdr->p_type == PT_LOAD) {
4913f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov      return reinterpret_cast<ElfW(Addr)>(elf) + phdr->p_offset - phdr->p_vaddr;
4923f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov    }
4933f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  }
4943f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  return 0;
4953f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
4963f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
4973f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov/*
4983f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * This is the entry point for the linker, called from begin.S. This
4993f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * method is responsible for fixing the linker's own relocations, and
5003f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * then calling __linker_init_post_relocation().
5013f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov *
5023f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * Because this method is called before the linker has fixed it's own
5033f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * relocations, any attempt to reference an extern variable, extern
5043f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov * function, or other GOT reference will generate a segfault.
5053f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov */
5063f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovextern "C" ElfW(Addr) __linker_init(void* raw_args) {
5073f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  KernelArgumentBlock args(raw_args);
5083f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5099b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // AT_BASE is set to 0 in the case when linker is run by iself
5109b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // so in order to link the linker it needs to calcuate AT_BASE
5119b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // using information at hand. The trick below takes advantage
5129b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // of the fact that the value of linktime_addr before relocations
5139b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // are run is an offset and this can be used to calculate AT_BASE.
5149b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  static uintptr_t linktime_addr = reinterpret_cast<uintptr_t>(&linktime_addr);
5159b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  ElfW(Addr) linker_addr = reinterpret_cast<uintptr_t>(&linktime_addr) - linktime_addr;
5169b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov
517705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV#if defined(__clang_analyzer__)
518705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV  // The analyzer assumes that linker_addr will always be null. Make it an
519705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV  // unknown value so we don't have to mark N places with NOLINTs.
520705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV  //
521705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV  // (`+=`, rather than `=`, allows us to sidestep a potential "unused store"
522705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV  // complaint)
523705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV  linker_addr += reinterpret_cast<uintptr_t>(raw_args);
524705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV#endif
525705910094d07ddfc5a3b7a4baab58b0a94bcc691George Burgess IV
5263f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  ElfW(Addr) entry_point = args.getauxval(AT_ENTRY);
5273f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
5283f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
5293f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5303f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  soinfo linker_so(nullptr, nullptr, nullptr, 0, 0);
5313f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5323f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  linker_so.base = linker_addr;
5333f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  linker_so.size = phdr_table_get_load_size(phdr, elf_hdr->e_phnum);
5343f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  linker_so.load_bias = get_elf_exec_load_bias(elf_hdr);
5353f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  linker_so.dynamic = nullptr;
5363f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  linker_so.phdr = phdr;
5373f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  linker_so.phnum = elf_hdr->e_phnum;
5383f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  linker_so.set_linker_flag();
5393f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5403f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Prelink the linker so we can access linker globals.
5413f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (!linker_so.prelink_image()) __linker_cannot_link(args.argv[0]);
5423f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5433f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // This might not be obvious... The reasons why we pass g_empty_list
5443f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // in place of local_group here are (1) we do not really need it, because
5453f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // linker is built with DT_SYMBOLIC and therefore relocates its symbols against
5463f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // itself without having to look into local_group and (2) allocators
5473f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // are not yet initialized, and therefore we cannot use linked_list.push_*
5483f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // functions at this point.
5493f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (!linker_so.link_image(g_empty_list, g_empty_list, nullptr)) __linker_cannot_link(args.argv[0]);
5503f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5513f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#if defined(__i386__)
5523f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // On x86, we can't make system calls before this point.
5533f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // We can't move this up because this needs to assign to a global.
5543f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Note that until we call __libc_init_main_thread below we have
5553f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // no TLS, so you shouldn't make a system call that can fail, because
5563f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // it will SEGV when it tries to set errno.
5573f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  __libc_init_sysinfo(args);
5583f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov#endif
5593f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5603f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Initialize the main thread (including TLS, so system calls really work).
5613f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  __libc_init_main_thread(args);
5623f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5633f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // We didn't protect the linker's RELRO pages in link_image because we
5643f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // couldn't make system calls on x86 at that point, but we can now...
5653f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  if (!linker_so.protect_relro()) __linker_cannot_link(args.argv[0]);
5663f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5673f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Initialize the linker's static libc's globals
5683f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  __libc_init_globals(args);
5693f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5703f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // store argc/argv/envp to use them for calling constructors
5713f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  g_argc = args.argc;
5723f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  g_argv = args.argv;
5733f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  g_envp = args.envp;
5743f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5753f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Initialize the linker's own global variables
5763f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  linker_so.call_constructors();
5773f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5789b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // If the linker is not acting as PT_INTERP entry_point is equal to
5799b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // _start. Which means that the linker is running as an executable and
5809b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // already linked by PT_INTERP.
5819b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  //
5829b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // This happens when user tries to run 'adb shell /system/bin/linker'
5839b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  // see also https://code.google.com/p/android/issues/detail?id=63174
5849b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  if (reinterpret_cast<ElfW(Addr)>(&_start) == entry_point) {
5857a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris    async_safe_format_fd(STDOUT_FILENO,
5869b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov                     "This is %s, the helper program for dynamic executables.\n",
5879b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov                     args.argv[0]);
5889b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov    exit(0);
5899b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov  }
5909b1cc4bb9cd84c2a52b8183a418e9dbb41f59959Dimitry Ivanov
591cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov  init_linker_info_for_gdb(linker_addr, kLinkerPath);
592cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov
5933f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Initialize static variables. Note that in order to
5943f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // get correct libdl_info we need to call constructors
5953f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // before get_libdl_info().
5967abea57ba599b9b114031ae33699b5d7fba8cc97dimitry  sonext = solist = get_libdl_info(kLinkerPath, linker_so, linker_link_map);
597d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov  g_default_namespace.add_soinfo(solist);
5983f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
5993f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // We have successfully fixed our own relocations. It's safe to run
6003f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // the main part of the linker now.
6013f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  args.abort_message_ptr = &g_abort_message;
602cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov  ElfW(Addr) start_address = __linker_init_post_relocation(args);
6033f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
6043f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  INFO("[ Jumping to _start (%p)... ]", reinterpret_cast<void*>(start_address));
6053f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov
6063f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  // Return the address that the calling assembly stub should jump to.
6073f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov  return start_address;
6083f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov}
609