diff --git a/src/elf_link_common.c b/src/elf_link_common.c index 51c0cf0791cb1b473d5068b0dfd2a13fca30b6ff..9bbed3538a2ac4bddc0773b7644f195ce7afeddc 100644 --- a/src/elf_link_common.c +++ b/src/elf_link_common.c @@ -530,13 +530,6 @@ char *elf_get_tmp_section_name(elf_link_t *elf_link, Elf64_Shdr *shdr) Elf64_Shdr *src_sec = (Elf64_Shdr *)obj_mapping->src_obj; char *sec_name = elf_get_section_name(src_ef, src_sec); - if (is_need_preinit(elf_link) && is_init_name(sec_name)) { - elf_file_t *main_ef = get_main_ef(elf_link); - if (src_ef != main_ef) { - return ".preinit_array"; - } - } - return sec_name; } diff --git a/src/elf_link_common.h b/src/elf_link_common.h index 342a0c89b57003c3ffc5e7c38cf9338107a927c6..054748263fe4e0f22a8f314e7a7182360c04da65 100644 --- a/src/elf_link_common.h +++ b/src/elf_link_common.h @@ -159,6 +159,12 @@ static inline bool is_static_nolibc_mode(elf_link_t *elf_link) return elf_link->link_mode == ELF_LINK_STATIC_NOLIBC; } +// libc _init_first is in .init_array, must run before _start +// libc __libc_early_init need init before .init_array +// dl_main(phdr, phnum, user_entry, auxv) +// _dl_call_libc_early_init (GL(dl_ns)[LM_ID_BASE].libc_map, true); +// __libc_early_init(true) + // this mode merge all ELFs exclude ld.so // ld.so parse env and parameter, rtld_global_ro share to libc.so // ld.so have some init process for libc, soname need call libc.so @@ -221,40 +227,6 @@ static inline elf_file_t *get_libc_ef(elf_link_t *elf_link) return elf_link->libc_ef; } -static inline bool is_init_name(const char *name) -{ - if (strcmp(name, ".init_array") == 0) { - return true; - } - - return false; -} - -static inline bool is_preinit_name(const char *name) -{ - if (strcmp(name, ".preinit_array") == 0) { - return true; - } - - return false; -} - -// libc _init_first is in .init_array, must run before _start, move _init_first to .preinit_array -// libc __libc_early_init need init before .init_array, so put first of .preinit_array -// dl_main(phdr, phnum, user_entry, auxv) -// _dl_call_libc_early_init (GL(dl_ns)[LM_ID_BASE].libc_map, true); -// __libc_early_init(true) -static inline bool is_need_preinit(elf_link_t *elf_link) -{ - // TODO: clean this - (void)elf_link; - //if (is_static_nold_mode(elf_link)) { - // return true; - //} - - return false; -} - static inline void elf_write_u32(elf_file_t *ef, unsigned long addr_, unsigned value) { unsigned *addr = ((void *)ef->hdr + (unsigned long)addr_); diff --git a/src/elf_link_elf.c b/src/elf_link_elf.c index 6a8dc304a2ae998a59430af2b58c4094df394313..826da7a285ab3a98951446dae2344d865f8e9c38 100644 --- a/src/elf_link_elf.c +++ b/src/elf_link_elf.c @@ -782,31 +782,6 @@ static int dynamic_add_obj_from_libc(elf_link_t *elf_link, Elf64_Dyn *begin_dyn, return len; } -// .dynamic is merge all elf, so mem space is enough -static int dynamic_add_preinit(elf_link_t *elf_link, Elf64_Dyn *begin_dyn, int len) -{ - if (is_need_preinit(elf_link) == false) { - return len; - } - - Elf64_Shdr *sec = find_tmp_section_by_name(elf_link, ".preinit_array"); - if (sec == NULL) { - si_panic("not found .preinit_array\n"); - } - - Elf64_Dyn *dst_dyn = &begin_dyn[len]; - dst_dyn->d_tag = DT_PREINIT_ARRAY; - dst_dyn->d_un.d_val = sec->sh_addr; - len++; - - dst_dyn++; - dst_dyn->d_tag = DT_PREINIT_ARRAYSZ; - dst_dyn->d_un.d_val = sec->sh_size; - len++; - - return len; -} - static int dynamic_copy_obj(elf_link_t *elf_link, Elf64_Dyn *begin_dyn, int len) { Elf64_Dyn *dst_dyn = &begin_dyn[len]; @@ -923,9 +898,6 @@ static void scan_dynamic(elf_link_t *elf_link) // DT_SONAME len = dynamic_add_obj_from_libc(elf_link, begin_dyn, len); - // DT_PREINIT_ARRAY - len = dynamic_add_preinit(elf_link, begin_dyn, len); - // new addr of INIT FINI STRTAB SYMTAB len = dynamic_copy_obj(elf_link, begin_dyn, len); diff --git a/src/elf_read_elf.h b/src/elf_read_elf.h index 28f0e9a1aabc2bb54a43c779cac46e37ab1ad072..29a3426f51042008137b1bb096de4a38779a337d 100644 --- a/src/elf_read_elf.h +++ b/src/elf_read_elf.h @@ -231,6 +231,23 @@ static inline bool elf_rela_is_relative(Elf64_Rela *rela) return false; } +static inline Elf64_Rela *elf_find_none_rela(elf_file_t *ef, Elf64_Shdr *sec) +{ + int count = sec->sh_size / sizeof(Elf64_Rela); + Elf64_Rela *relas = elf_get_section_data(ef, sec); + Elf64_Rela *rela = NULL; + + for (int i = 0; i < count; i++) { + rela = &relas[i]; + // TODO: for ARM + if (ELF64_R_TYPE(rela->r_info) == R_X86_64_NONE) { + return rela; + } + } + + return NULL; +} + Elf64_Rela *elf_get_rela_by_addr(elf_file_t *ef, unsigned long addr); diff --git a/src/elf_relocation.c b/src/elf_relocation.c index cd86035b70c8c11c65f5a46e9bc28467c696befc..b40004f3aefdbd42c11d2b60e9ed731e8e2c356c 100644 --- a/src/elf_relocation.c +++ b/src/elf_relocation.c @@ -341,22 +341,6 @@ void modify_rela_dyn_item(elf_link_t *elf_link, elf_file_t *src_ef, Elf64_Rela * dst_rela->r_offset, dst_rela->r_info, dst_rela->r_addend); } -static Elf64_Rela *find_none_rela(elf_file_t *ef, Elf64_Shdr *sec) -{ - int count = sec->sh_size / sizeof(Elf64_Rela); - Elf64_Rela *relas = elf_get_section_data(ef, sec); - Elf64_Rela *rela = NULL; - - for (int i = 0; i < count; i++) { - rela = &relas[i]; - // TODO: for ARM - if (ELF64_R_TYPE(rela->r_info) == R_X86_64_NONE) { - return rela; - } - } - - return NULL; -} // .rela.dyn void modify_rela_dyn(elf_link_t *elf_link) @@ -372,28 +356,6 @@ void modify_rela_dyn(elf_link_t *elf_link) elf_file_t *src_ef = obj_rel->src_ef; modify_rela_dyn_item(elf_link, src_ef, src_rela, dst_rela); } - - // add rela for __libc_early_init - if (is_need_preinit(elf_link) == false) { - return; - } - Elf64_Shdr *find_sec = find_tmp_section_by_name(elf_link, ".preinit_array"); - if (find_sec == NULL) { - si_panic("find section fail\n"); - } - Elf64_Shdr *sec = find_tmp_section_by_name(elf_link, ".rela.dyn"); - if (sec == NULL) { - si_panic("find section fail\n"); - } - elf_file_t *out_ef = &elf_link->out_ef; - Elf64_Rela *rela = find_none_rela(out_ef, sec); - if (rela == NULL) { - si_panic("find none rela fail\n"); - } - - rela->r_offset = find_sec->sh_addr; - unsigned long func = elf_read_u64(out_ef, find_sec->sh_offset); - rela_change_to_relative(rela, func); } void modify_got(elf_link_t *elf_link) diff --git a/src/elf_write_elf.c b/src/elf_write_elf.c index 5d6fbb70a36662c6a8a9c1792ed229dcc27f103c..5dbe31c019394381d55397f7c0a8e71b85b194e4 100644 --- a/src/elf_write_elf.c +++ b/src/elf_write_elf.c @@ -157,29 +157,6 @@ static Elf64_Shdr *add_tmp_section(elf_link_t *elf_link, elf_file_t *ef, Elf64_S return dst_sec; } -static Elf64_Shdr *find_sec_exclude_main_ef(elf_link_t *elf_link, const char *name, elf_file_t **lef) -{ - int in_ef_nr = elf_link->in_ef_nr; - elf_file_t *ef = NULL; - Elf64_Shdr *sec = NULL; - elf_file_t *main_ef = get_main_ef(elf_link); - - for (int i = 0; i < in_ef_nr; i++) { - ef = &elf_link->in_efs[i]; - if (ef == main_ef) { - continue; - } - sec = elf_find_section_by_name(ef, name); - if (sec == NULL) { - continue; - } - *lef = ef; - return sec; - } - - return NULL; -} - static Elf64_Shdr *add_tmp_section_by_name(elf_link_t *elf_link, const char *name) { int in_ef_nr = elf_link->in_ef_nr; @@ -201,15 +178,6 @@ static Elf64_Shdr *add_tmp_section_by_name(elf_link_t *elf_link, const char *nam break; } - // libc _init_first is in .init_array, this func must run before _start - // move _init_first to .preinit_array - if (is_need_preinit(elf_link) && is_preinit_name(name)) { - if (sec) { - si_panic(".preinit_array not supported\n"); - } - sec = find_sec_exclude_main_ef(elf_link, ".init_array", &ef); - } - if (sec == NULL) { return NULL; } @@ -255,22 +223,6 @@ void copy_from_old_elf(elf_link_t *elf_link) } } -// add __libc_early_init to first of .preinit_array, add rela for it -// __libc_early_init first arg is bool, is one Byte -// init_func(argc, argv, env) first arg need < 256, other args no used -static void preinit_add_libc_early_init(elf_link_t *elf_link) -{ - elf_file_t *libc_ef = get_libc_ef(elf_link); - if (libc_ef == NULL) { - return; - } - - unsigned long old_sym_addr = elf_find_symbol_addr_by_name(libc_ef, "__libc_early_init"); - unsigned long new_sym_addr = get_new_addr_by_old_addr(elf_link, libc_ef, old_sym_addr); - - write_elf_file(elf_link, &new_sym_addr, sizeof(unsigned long)); -} - static void record_rela_arr(elf_link_t *elf_link, elf_file_t *ef, Elf64_Shdr *sec, void *dst) { si_array_t *arr = NULL; @@ -335,17 +287,11 @@ static Elf64_Shdr *elf_merge_section(elf_link_t *elf_link, Elf64_Shdr *tmp_sec, Elf64_Shdr *sec = NULL; void *dst = NULL; elf_file_t *main_ef = get_main_ef(elf_link); - bool is_preinit = is_need_preinit(elf_link) && is_preinit_name(name); - char *l_name = (char*)name; tmp_sec->sh_offset = elf_align_file(elf_link, tmp_sec->sh_addralign); tmp_sec->sh_addr = elf_link->next_mem_addr; SI_LOG_DEBUG("section %s at 0x%lx\n", name, tmp_sec->sh_offset); - if (is_preinit) { - preinit_add_libc_early_init(elf_link); - } - // libc .dynsym .dynstr need put first, so version section no change bool is_first_libc = is_merge_libc_first(elf_link, tmp_sec, name); elf_file_t *libc_ef = get_libc_ef(elf_link); @@ -357,21 +303,16 @@ static Elf64_Shdr *elf_merge_section(elf_link_t *elf_link, Elf64_Shdr *tmp_sec, } for (int i = 0; i < in_ef_nr; i++) { - if (is_preinit) { - // TODO: order by deps lib - ef = &elf_link->in_efs[in_ef_nr - 1 - i]; - // libs .init_array to .preinit_array - l_name = ".init_array"; - } else { - ef = &elf_link->in_efs[i]; - } + // TODO: order by deps lib + // ef = &elf_link->in_efs[in_ef_nr - 1 - i]; + ef = &elf_link->in_efs[i]; if (skip_main_ef && (ef == main_ef)) { continue; } if (is_first_libc && (ef == libc_ef)) { continue; } - sec = elf_find_section_by_name(ef, l_name); + sec = elf_find_section_by_name(ef, name); if (sec == NULL) { continue; } @@ -538,15 +479,6 @@ static int foreach_merge_section_by_name(const void *item, void *pridata) const char *name = item; elf_link_t *elf_link = pridata; - // add .preinit_array section for libc init func - if (is_need_preinit(elf_link) && is_init_name(name)) { - merge_libs_ef_section(elf_link, ".preinit_array"); - - // .init_array - merge_template_ef_section(elf_link, name); - return 0; - } - merge_all_ef_section(elf_link, name); return 0; }