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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user