linker_mips.cpp revision 18870d350c29c83bdcecbe5cf3715b2c800275f7
1114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov/* 2114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * Copyright (C) 2015 The Android Open Source Project 3114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * All rights reserved. 4114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * 5114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * Redistribution and use in source and binary forms, with or without 6114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * modification, are permitted provided that the following conditions 7114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * are met: 8114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * * Redistributions of source code must retain the above copyright 9114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * notice, this list of conditions and the following disclaimer. 10114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * * Redistributions in binary form must reproduce the above copyright 11114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * notice, this list of conditions and the following disclaimer in 12114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * the documentation and/or other materials provided with the 13114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * distribution. 14114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * 15114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov * SUCH DAMAGE. 27114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov */ 28114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 29114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov#include "linker.h" 30114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov#include "linker_debug.h" 31114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov#include "linker_relocs.h" 32fa26eee77685e8dee7986e62a7d263003f5bd25aDmitriy Ivanov#include "linker_reloc_iterators.h" 3318870d350c29c83bdcecbe5cf3715b2c800275f7Dmitriy Ivanov#include "linker_sleb128.h" 34fa26eee77685e8dee7986e62a7d263003f5bd25aDmitriy Ivanov 3518a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanovtemplate bool soinfo::relocate<plain_reloc_iterator>(plain_reloc_iterator&& rel_iterator, 3618a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov const soinfo_list_t& global_group, 3718a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov const soinfo_list_t& local_group); 3818a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov 3918a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanovtemplate bool soinfo::relocate<packed_reloc_iterator<sleb128_decoder>>( 4018a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov packed_reloc_iterator<sleb128_decoder>&& rel_iterator, 4118a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov const soinfo_list_t& global_group, 4218a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov const soinfo_list_t& local_group); 4318a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov 44fa26eee77685e8dee7986e62a7d263003f5bd25aDmitriy Ivanovtemplate <typename ElfRelIteratorT> 4520d89cb5b0d5eb7546a8fe8da44bbd91564dbddaDmitriy Ivanovbool soinfo::relocate(ElfRelIteratorT&& rel_iterator, 4620d89cb5b0d5eb7546a8fe8da44bbd91564dbddaDmitriy Ivanov const soinfo_list_t& global_group, 4720d89cb5b0d5eb7546a8fe8da44bbd91564dbddaDmitriy Ivanov const soinfo_list_t& local_group) { 482a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov VersionTracker version_tracker; 492a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov 502a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov if (!version_tracker.init(this)) { 512a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov return false; 522a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov } 532a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov 54fa26eee77685e8dee7986e62a7d263003f5bd25aDmitriy Ivanov for (size_t idx = 0; rel_iterator.has_next(); ++idx) { 55fa26eee77685e8dee7986e62a7d263003f5bd25aDmitriy Ivanov const auto rel = rel_iterator.next(); 56114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 5718a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov if (rel == nullptr) { 5818a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov return false; 5918a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov } 6018a6956b76a071097fc658c5fe13ef010e31864aDmitriy Ivanov 61114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov ElfW(Word) type = ELFW(R_TYPE)(rel->r_info); 62114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov ElfW(Word) sym = ELFW(R_SYM)(rel->r_info); 63114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 64114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov ElfW(Addr) reloc = static_cast<ElfW(Addr)>(rel->r_offset + load_bias); 65114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov ElfW(Addr) sym_addr = 0; 66114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov const char* sym_name = nullptr; 67114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 68aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov DEBUG("Processing '%s' relocation at index %zd", get_soname(), idx); 69114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if (type == R_GENERIC_NONE) { 70114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov continue; 71114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 72114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 732a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov const ElfW(Sym)* s = nullptr; 74114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov soinfo* lsi = nullptr; 75114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 76114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if (sym != 0) { 77114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov sym_name = get_string(symtab_[sym].st_name); 782a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov const ElfW(Versym)* sym_ver_ptr = get_versym(sym); 792a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr; 802a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov 812a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov if (sym_ver == VER_NDX_LOCAL || sym_ver == VER_NDX_GLOBAL) { 822a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov // there is no version info for this one 832a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov if (!soinfo_do_lookup(this, sym_name, nullptr, &lsi, global_group, local_group, &s)) { 842a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov return false; 852a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov } 862a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov } else { 872a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov const version_info* vi = version_tracker.get_version_info(sym_ver); 882a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov 892a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov if (vi == nullptr) { 902a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov DL_ERR("cannot find verneed/verdef for version index=%d " 912a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov "referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_soname()); 922a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov return false; 932a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov } 942a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov 952a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) { 962a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov return false; 972a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov } 982a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov } 992a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov 100114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if (s == nullptr) { 101114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // mips does not support relocation with weak-undefined symbols 102aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_soname()); 103114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov return false; 104114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } else { 105114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // We got a definition. 106114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov sym_addr = lsi->resolve_symbol_address(s); 107114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 108114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov count_relocation(kRelocSymbol); 109114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 110114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 111114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov switch (type) { 112114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov case R_MIPS_REL32: 113114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov#if defined(__LP64__) 114114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // MIPS Elf64_Rel entries contain compound relocations 115114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // We only handle the R_MIPS_NONE|R_MIPS_64|R_MIPS_REL32 case 116114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if (ELF64_R_TYPE2(rel->r_info) != R_MIPS_64 || 117114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov ELF64_R_TYPE3(rel->r_info) != R_MIPS_NONE) { 118114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov DL_ERR("Unexpected compound relocation type:%d type2:%d type3:%d @ %p (%zu)", 119db3078d97b57224c2c845cefbd46adc77fadfb37Nikola Veljkovic type, static_cast<unsigned>(ELF64_R_TYPE2(rel->r_info)), 120db3078d97b57224c2c845cefbd46adc77fadfb37Nikola Veljkovic static_cast<unsigned>(ELF64_R_TYPE3(rel->r_info)), rel, idx); 121114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov return false; 122114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 123114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov#endif 124114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov count_relocation(s == nullptr ? kRelocAbsolute : kRelocRelative); 125114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov MARK(rel->r_offset); 126114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov TRACE_TYPE(RELO, "RELO REL32 %08zx <- %08zx %s", static_cast<size_t>(reloc), 127114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov static_cast<size_t>(sym_addr), sym_name ? sym_name : "*SECTIONHDR*"); 128114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if (s != nullptr) { 129114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr; 130114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } else { 131114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov *reinterpret_cast<ElfW(Addr)*>(reloc) += base; 132114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 133114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov break; 134114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov default: 135114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov DL_ERR("unknown reloc type %d @ %p (%zu)", type, rel, idx); 136114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov return false; 137114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 138114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 139114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov return true; 140114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov} 141114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 14220d89cb5b0d5eb7546a8fe8da44bbd91564dbddaDmitriy Ivanovbool soinfo::mips_relocate_got(const soinfo_list_t& global_group, 14320d89cb5b0d5eb7546a8fe8da44bbd91564dbddaDmitriy Ivanov const soinfo_list_t& local_group) { 144114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov ElfW(Addr)** got = plt_got_; 145114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if (got == nullptr) { 146114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov return true; 147114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 148114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 149114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // got[0] is the address of the lazy resolver function. 150114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // got[1] may be used for a GNU extension. 151114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // Set it to a recognizable address in case someone calls it (should be _rtld_bind_start). 152114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // FIXME: maybe this should be in a separate routine? 153114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if ((flags_ & FLAG_LINKER) == 0) { 154114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov size_t g = 0; 155114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov got[g++] = reinterpret_cast<ElfW(Addr)*>(0xdeadbeef); 156114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if (reinterpret_cast<intptr_t>(got[g]) < 0) { 157114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov got[g++] = reinterpret_cast<ElfW(Addr)*>(0xdeadfeed); 158114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 159114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // Relocate the local GOT entries. 160114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov for (; g < mips_local_gotno_; g++) { 161114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov got[g] = reinterpret_cast<ElfW(Addr)*>(reinterpret_cast<uintptr_t>(got[g]) + load_bias); 162114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 163114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 164114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 165114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // Now for the global GOT entries... 166114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov ElfW(Sym)* sym = symtab_ + mips_gotsym_; 167114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov got = plt_got_ + mips_local_gotno_; 168114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov for (size_t g = mips_gotsym_; g < mips_symtabno_; g++, sym++, got++) { 169114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // This is an undefined reference... try to locate it. 170114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov const char* sym_name = get_string(sym->st_name); 171114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov soinfo* lsi = nullptr; 1722a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov const ElfW(Sym)* s = nullptr; 1732a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov if (!soinfo_do_lookup(this, sym_name, nullptr, &lsi, global_group, local_group, &s)) { 1742a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov return false; 1752a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov } 1762a815361448d01b0f4e575f507ce31913214c536Dmitriy Ivanov 177114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if (s == nullptr) { 178114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // We only allow an undefined symbol if this is a weak reference. 179114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov s = &symtab_[g]; 180114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov if (ELF_ST_BIND(s->st_info) != STB_WEAK) { 181114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov DL_ERR("cannot locate \"%s\"...", sym_name); 182114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov return false; 183114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 184114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov *got = 0; 185114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } else { 186114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // FIXME: is this sufficient? 187114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // For reference see NetBSD link loader 188114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov // http://cvsweb.netbsd.org/bsdweb.cgi/src/libexec/ld.elf_so/arch/mips/mips_reloc.c?rev=1.53&content-type=text/x-cvsweb-markup 189114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov *got = reinterpret_cast<ElfW(Addr)*>(lsi->resolve_symbol_address(s)); 190114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 191114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov } 192114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov return true; 193114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov} 194114ff69f1753c7fe4d749f8fb0c082b80e0d43f4Dmitriy Ivanov 195