Support symbol versioning
Bug: http://b/20139821 Change-Id: I64122a0fb0960c20b2ce614161b7ab048456b681
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
#include "linked_list.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define DL_ERR(fmt, x...) \
|
||||
do { \
|
||||
@@ -142,6 +143,32 @@ class SymbolName {
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName);
|
||||
};
|
||||
|
||||
struct version_info {
|
||||
version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {}
|
||||
|
||||
uint32_t elf_hash;
|
||||
const char* name;
|
||||
const soinfo* target_si;
|
||||
};
|
||||
|
||||
// Class used construct version dependency graph.
|
||||
class VersionTracker {
|
||||
public:
|
||||
VersionTracker() = default;
|
||||
bool init(const soinfo* si_from);
|
||||
|
||||
const version_info* get_version_info(ElfW(Versym) source_symver) const;
|
||||
private:
|
||||
bool init_verneed(const soinfo* si_from);
|
||||
bool init_verdef(const soinfo* si_from);
|
||||
void add_version_info(size_t source_index, ElfW(Word) elf_hash,
|
||||
const char* ver_name, const soinfo* target_si);
|
||||
|
||||
std::vector<version_info> version_infos;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(VersionTracker);
|
||||
};
|
||||
|
||||
struct soinfo {
|
||||
public:
|
||||
typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
|
||||
@@ -260,11 +287,16 @@ struct soinfo {
|
||||
void set_dt_flags_1(uint32_t dt_flags_1);
|
||||
|
||||
soinfo_list_t& get_children();
|
||||
const soinfo_list_t& get_children() const;
|
||||
|
||||
soinfo_list_t& get_parents();
|
||||
|
||||
ElfW(Sym)* find_symbol_by_name(SymbolName& symbol_name);
|
||||
bool find_symbol_by_name(SymbolName& symbol_name,
|
||||
const version_info* vi,
|
||||
const ElfW(Sym)** symbol) const;
|
||||
|
||||
ElfW(Sym)* find_symbol_by_address(const void* addr);
|
||||
ElfW(Addr) resolve_symbol_address(ElfW(Sym)* s);
|
||||
ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const;
|
||||
|
||||
const char* get_string(ElfW(Word) index) const;
|
||||
bool can_unload() const;
|
||||
@@ -292,11 +324,18 @@ struct soinfo {
|
||||
|
||||
const char* get_soname() const;
|
||||
const char* get_realpath() const;
|
||||
const ElfW(Versym)* get_versym(size_t n) const;
|
||||
ElfW(Addr) get_verneed_ptr() const;
|
||||
size_t get_verneed_cnt() const;
|
||||
ElfW(Addr) get_verdef_ptr() const;
|
||||
size_t get_verdef_cnt() const;
|
||||
|
||||
bool find_verdef_version_index(const version_info* vi, ElfW(Versym)* versym) const;
|
||||
|
||||
private:
|
||||
ElfW(Sym)* elf_lookup(SymbolName& symbol_name);
|
||||
bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
|
||||
ElfW(Sym)* elf_addr_lookup(const void* addr);
|
||||
ElfW(Sym)* gnu_lookup(SymbolName& symbol_name);
|
||||
bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
|
||||
ElfW(Sym)* gnu_addr_lookup(const void* addr);
|
||||
|
||||
void call_array(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
|
||||
@@ -341,11 +380,20 @@ struct soinfo {
|
||||
const char* soname_;
|
||||
std::string realpath_;
|
||||
|
||||
const ElfW(Versym)* versym_;
|
||||
|
||||
ElfW(Addr) verdef_ptr_;
|
||||
size_t verdef_cnt_;
|
||||
|
||||
ElfW(Addr) verneed_ptr_;
|
||||
size_t verneed_cnt_;
|
||||
|
||||
friend soinfo* get_libdl_info();
|
||||
};
|
||||
|
||||
ElfW(Sym)* soinfo_do_lookup(soinfo* si_from, const char* name, soinfo** si_found_in,
|
||||
const soinfo::soinfo_list_t& global_group, const soinfo::soinfo_list_t& local_group);
|
||||
bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
|
||||
soinfo** si_found_in, const soinfo::soinfo_list_t& global_group,
|
||||
const soinfo::soinfo_list_t& local_group, const ElfW(Sym)** symbol);
|
||||
|
||||
enum RelocationKind {
|
||||
kRelocAbsolute = 0,
|
||||
@@ -364,10 +412,10 @@ void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
|
||||
soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo);
|
||||
void do_dlclose(soinfo* si);
|
||||
|
||||
ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* caller, void* handle);
|
||||
const ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* caller, void* handle);
|
||||
soinfo* find_containing_library(const void* addr);
|
||||
|
||||
ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name);
|
||||
const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name);
|
||||
|
||||
void debuggerd_init();
|
||||
extern "C" abort_msg_t* g_abort_message;
|
||||
|
||||
Reference in New Issue
Block a user