未验证 提交 da950515 编写于 作者: O openharmony_ci 提交者: Gitee

!748 Optimize dlopen performance by reducing search so range(pick 747)

Merge pull request !748 from yinchuang/cherry-pick-1671154249
...@@ -172,6 +172,8 @@ struct dso { ...@@ -172,6 +172,8 @@ struct dso {
struct dso **parents; struct dso **parents;
size_t parents_count; size_t parents_count;
size_t parents_capacity; size_t parents_capacity;
bool is_global;
bool is_reloc_head_so_dep;
struct dso **reloc_can_search_dso_list; struct dso **reloc_can_search_dso_list;
size_t reloc_can_search_dso_count; size_t reloc_can_search_dso_count;
size_t reloc_can_search_dso_capacity; size_t reloc_can_search_dso_capacity;
...@@ -766,14 +768,48 @@ static void free_reloc_can_search_dso(struct dso *p) ...@@ -766,14 +768,48 @@ static void free_reloc_can_search_dso(struct dso *p)
} }
} }
static void add_can_search_so_list_in_dso(struct dso *dso, struct dso *start_check_dso) { static char* reloc_white_list[] = {
struct dso *check_dso = start_check_dso; "/usr/lib/libace_lite.so",
while (check_dso) { "/usr/lib/libsec_shared.so",
if (dso->namespace && check_sym_accessible(check_dso, dso->namespace)) { "/usr/lib/libisp.so",
add_reloc_can_search_dso(dso, check_dso); "/usr/lib/lib_hiae.so",
"/usr/lib/lib_hiawb.so",
"/usr/lib/libmedia_hal_common.so",
"/usr/lib/libhi_osal.so",
"/usr/lib/libmpi.so"
};
/* The list of so that can be accessed during relocation include:
* - The is_global flag of the so is true which means accessible by default.
* Global so includes exe, ld preload so and ldso.
* - We only check whether ns is accessible for the so if is_reloc_head_so_dep is true.
*
* How to set is_reloc_head_so_dep:
* When dlopen A, we set is_reloc_head_so_dep to true for
* all direct and indirect dependent sos of A, including A itself. */
static void add_can_search_so_list_in_dso(struct dso *dso_relocating, struct dso *start_check_dso) {
struct dso *p = start_check_dso;
for (; p; p = p->syms_next) {
if (p->is_global) {
add_reloc_can_search_dso(dso_relocating, p);
continue;
}
if (p->is_reloc_head_so_dep) {
if (dso_relocating->namespace && check_sym_accessible(p, dso_relocating->namespace)) {
add_reloc_can_search_dso(dso_relocating, p);
continue;
}
}
for (size_t i = 0; i < sizeof(reloc_white_list) / sizeof(char*); i++) {
if (strcmp(reloc_white_list[i], p->name) == 0) {
add_reloc_can_search_dso(dso_relocating, p);
break;
}
} }
check_dso = check_dso->syms_next;
} }
return; return;
} }
...@@ -2227,7 +2263,9 @@ static void reloc_all(struct dso *p, const dl_extinfo *extinfo) ...@@ -2227,7 +2263,9 @@ static void reloc_all(struct dso *p, const dl_extinfo *extinfo)
size_t dyn[DYN_CNT]; size_t dyn[DYN_CNT];
for (; p; p=p->next) { for (; p; p=p->next) {
if (p->relocated) continue; if (p->relocated) continue;
add_can_search_so_list_in_dso(p, head); if (p != &ldso) {
add_can_search_so_list_in_dso(p, head);
}
decode_vec(p->dynv, dyn, DYN_CNT); decode_vec(p->dynv, dyn, DYN_CNT);
if (NEED_MIPS_GOT_RELOCS) if (NEED_MIPS_GOT_RELOCS)
do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT])); do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));
...@@ -2534,6 +2572,7 @@ hidden void __dls2(unsigned char *base, size_t *sp) ...@@ -2534,6 +2572,7 @@ hidden void __dls2(unsigned char *base, size_t *sp)
ldso.phnum = ehdr->e_phnum; ldso.phnum = ehdr->e_phnum;
ldso.phdr = laddr(&ldso, ehdr->e_phoff); ldso.phdr = laddr(&ldso, ehdr->e_phoff);
ldso.phentsize = ehdr->e_phentsize; ldso.phentsize = ehdr->e_phentsize;
ldso.is_global = true;
kernel_mapped_dso(&ldso); kernel_mapped_dso(&ldso);
decode_dyn(&ldso); decode_dyn(&ldso);
...@@ -2751,6 +2790,7 @@ void __dls3(size_t *sp, size_t *auxv) ...@@ -2751,6 +2790,7 @@ void __dls3(size_t *sp, size_t *auxv)
} }
argv[-3] = (void *)app.loadmap; argv[-3] = (void *)app.loadmap;
} }
app.is_global = true;
/* Initial dso chain consists only of the app. */ /* Initial dso chain consists only of the app. */
head = tail = syms_tail = &app; head = tail = syms_tail = &app;
...@@ -2780,6 +2820,9 @@ void __dls3(size_t *sp, size_t *auxv) ...@@ -2780,6 +2820,9 @@ void __dls3(size_t *sp, size_t *auxv)
if (env_preload) { if (env_preload) {
load_preload(env_preload, get_default_ns(), tasks); load_preload(env_preload, get_default_ns(), tasks);
} }
for (struct dso *q=head; q; q=q->next) {
q->is_global = true;
}
preload_deps(&app, tasks); preload_deps(&app, tasks);
unmap_preloaded_sections(tasks); unmap_preloaded_sections(tasks);
shuffle_loadtasks(tasks); shuffle_loadtasks(tasks);
...@@ -2788,11 +2831,17 @@ void __dls3(size_t *sp, size_t *auxv) ...@@ -2788,11 +2831,17 @@ void __dls3(size_t *sp, size_t *auxv)
assign_tls(app.next); assign_tls(app.next);
#else #else
if (env_preload) load_preload(env_preload, get_default_ns()); if (env_preload) load_preload(env_preload, get_default_ns());
for (struct dso *q=head; q; q=q->next) {
q->is_global = true;
}
load_deps(&app, NULL); load_deps(&app, NULL);
#endif #endif
for (struct dso *p=head; p; p=p->next) /* Set is_reloc_head_so_dep to true for all direct and indirect dependent sos of app, including app self. */
for (struct dso *p=head; p; p=p->next) {
p->is_reloc_head_so_dep = true;
add_syms(p); add_syms(p);
}
/* Attach to vdso, if provided by the kernel, last so that it does /* Attach to vdso, if provided by the kernel, last so that it does
* not become part of the global namespace. */ * not become part of the global namespace. */
...@@ -2854,6 +2903,9 @@ void __dls3(size_t *sp, size_t *auxv) ...@@ -2854,6 +2903,9 @@ void __dls3(size_t *sp, size_t *auxv)
* copy relocations which depend on libraries' relocations. */ * copy relocations which depend on libraries' relocations. */
reloc_all(app.next, NULL); reloc_all(app.next, NULL);
reloc_all(&app, NULL); reloc_all(&app, NULL);
for (struct dso *q=head; q; q=q->next) {
q->is_reloc_head_so_dep = false;
}
/* Actual copying to new TLS needs to happen after relocations, /* Actual copying to new TLS needs to happen after relocations,
* since the TLS images might have contained relocated addresses. */ * since the TLS images might have contained relocated addresses. */
...@@ -3144,12 +3196,21 @@ static void *dlopen_impl( ...@@ -3144,12 +3196,21 @@ static void *dlopen_impl(
/* Make new symbols global, at least temporarily, so we can do /* Make new symbols global, at least temporarily, so we can do
* relocations. If not RTLD_GLOBAL, this is reverted below. */ * relocations. If not RTLD_GLOBAL, this is reverted below. */
add_syms(p); add_syms(p);
for (i=0; p->deps[i]; i++) /* Set is_reloc_head_so_dep to true for all direct and indirect dependent sos of p, including p self. */
p->is_reloc_head_so_dep = true;
for (i=0; p->deps[i]; i++) {
p->deps[i]->is_reloc_head_so_dep = true;
add_syms(p->deps[i]); add_syms(p->deps[i]);
}
} }
struct dso *reloc_head_so = p;
if (!p->relocated) { if (!p->relocated) {
reloc_all(p, extinfo); reloc_all(p, extinfo);
} }
reloc_head_so->is_reloc_head_so_dep = false;
for (size_t i=0; reloc_head_so->deps[i]; i++) {
reloc_head_so->deps[i]->is_reloc_head_so_dep = false;
}
/* If RTLD_GLOBAL was not specified, undo any new additions /* If RTLD_GLOBAL was not specified, undo any new additions
* to the global symbol table. This is a nop if the library was * to the global symbol table. This is a nop if the library was
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册