1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file. 4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef CRAZY_LINKER_ELF_SYMBOLS_H 6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define CRAZY_LINKER_ELF_SYMBOLS_H 7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <string.h> 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "elf_traits.h" 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace crazy { 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ElfView; 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// An ElfSymbols instance holds information about symbols in a mapped ELF 17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// binary. 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ElfSymbols { 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public: 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ElfSymbols() { ::memset(this, 0, sizeof(*this)); } 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ~ElfSymbols() {} 22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool Init(const ElfView* view); 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ELF::Sym* LookupByName(const char* symbol_name) const; 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ELF::Sym* LookupById(size_t symbol_id) const { 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return &symbol_table_[symbol_id]; 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ELF::Sym* LookupByAddress(void* address, size_t load_bias) const; 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Returns true iff symbol with id |symbol_id| is weak. 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool IsWeakById(size_t symbol_id) const { 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ELF_ST_BIND(symbol_table_[symbol_id].st_info) == STB_WEAK; 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* LookupNameById(size_t symbol_id) const { 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ELF::Sym* sym = LookupById(symbol_id); 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!sym) 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return string_table_ + sym->st_name; 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void* LookupAddressByName(const char* symbol_name, size_t load_bias) const { 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ELF::Sym* sym = LookupByName(symbol_name); 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!sym) 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return reinterpret_cast<void*>(load_bias + sym->st_value); 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool LookupNearestByAddress(void* address, 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t load_bias, 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char** sym_name, 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void** sym_addr, 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t* sym_size) const; 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* GetStringById(size_t str_id) const { 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return string_table_ + str_id; 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // TODO(digit): Remove this once ElfRelocator is gone. 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ELF::Sym* symbol_table() const { return symbol_table_; } 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* string_table() const { return string_table_; } 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private: 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ELF::Sym* symbol_table_; 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* string_table_; 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ELF::Word* hash_bucket_; 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t hash_bucket_size_; 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ELF::Word* hash_chain_; 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t hash_chain_size_; 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace crazy 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif // CRAZY_LINKER_ELF_SYMBOLS_H 78