Add IFUNC support for arm64 and IRELATIVE reloc

There are number of changes in the way IFUNC related relocations are done:
 1. IRELATIVE relocations are now supported for x86/x86_64 and arm64.
 2. IFUNC relocations are now relying on static linker to generate
    them in correct order - this removes necessety of additional
    relocation pass for ifuncs.
 3. Related to 2: rela?.dyn relocations are preformed before .plt ones.
 4. Ifunc are resolved on symbol lookup this approach allowed to avoid
    mprotect(PROT_WRITE) call on r-x program segments.

Bug: 17399706
Bug: 17177284

(cherry picked from commit 9aea164457)

Change-Id: Ie19d900fc203beb93faf8943b0d06d534a6de4ad
This commit is contained in:
Dmitriy Ivanov
2014-09-11 15:16:03 -07:00
parent ef1306d777
commit f4cb631364
10 changed files with 95 additions and 134 deletions

View File

@@ -197,6 +197,8 @@ struct soinfo {
#if !defined(__LP64__)
bool has_text_relocations;
#endif
// TODO: remove this flag, dynamic linker
// should not use it in any way.
bool has_DT_SYMBOLIC;
soinfo(const char* name, const struct stat* file_stat);
@@ -212,21 +214,20 @@ struct soinfo {
void set_st_dev(dev_t st_dev);
void set_st_ino(ino_t st_ino);
void set_has_ifuncs(bool ifunc);
ino_t get_st_ino();
dev_t get_st_dev();
bool get_has_ifuncs();
soinfo_list_t& get_children();
soinfo_list_t& get_parents();
ElfW(Addr) resolve_symbol_address(ElfW(Sym)* s);
bool inline has_min_version(uint32_t min_version) {
return (flags & FLAG_NEW_SOINFO) != 0 && version >= min_version;
}
private:
void CallArray(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
void CallFunction(const char* function_name, linker_function_t function);
void resolve_ifunc_symbols();
#if defined(USE_RELA)
int Relocate(ElfW(Rela)* rela, unsigned count);
#else
@@ -247,7 +248,6 @@ struct soinfo {
soinfo_list_t parents;
// version >= 1
bool has_ifuncs;
};
extern soinfo* get_libdl_info();