提交 12cb2bae 编写于 作者: Y yinchuang

Optimize dlopen performance by reducing search so range

Use global and deps to reloc so

Issue: I6687G

Test: Build & Boot devices
Signed-off-by: Nyinchuang <yinchuang@huawei.com>
上级 d9bf73f3
......@@ -172,6 +172,8 @@ struct dso {
struct dso **parents;
size_t parents_count;
size_t parents_capacity;
bool is_global;
bool is_reloc_head_so_dep;
struct dso **reloc_can_search_dso_list;
size_t reloc_can_search_dso_count;
size_t reloc_can_search_dso_capacity;
......@@ -759,14 +761,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) {
struct dso *check_dso = start_check_dso;
while (check_dso) {
if (dso->namespace && check_sym_accessible(check_dso, dso->namespace)) {
add_reloc_can_search_dso(dso, check_dso);
static char* reloc_white_list[] = {
"/usr/lib/libace_lite.so",
"/usr/lib/libsec_shared.so",
"/usr/lib/libisp.so",
"/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;
}
......@@ -2220,7 +2256,9 @@ static void reloc_all(struct dso *p, const dl_extinfo *extinfo)
size_t dyn[DYN_CNT];
for (; p; p=p->next) {
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);
if (NEED_MIPS_GOT_RELOCS)
do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));
......@@ -2527,6 +2565,7 @@ hidden void __dls2(unsigned char *base, size_t *sp)
ldso.phnum = ehdr->e_phnum;
ldso.phdr = laddr(&ldso, ehdr->e_phoff);
ldso.phentsize = ehdr->e_phentsize;
ldso.is_global = true;
kernel_mapped_dso(&ldso);
decode_dyn(&ldso);
......@@ -2743,6 +2782,7 @@ void __dls3(size_t *sp, size_t *auxv)
}
argv[-3] = (void *)app.loadmap;
}
app.is_global = true;
/* Initial dso chain consists only of the app. */
head = tail = syms_tail = &app;
......@@ -2772,6 +2812,9 @@ void __dls3(size_t *sp, size_t *auxv)
if (env_preload) {
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);
unmap_preloaded_sections(tasks);
shuffle_loadtasks(tasks);
......@@ -2780,11 +2823,17 @@ void __dls3(size_t *sp, size_t *auxv)
assign_tls(app.next);
#else
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);
#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);
}
/* Attach to vdso, if provided by the kernel, last so that it does
* not become part of the global namespace. */
......@@ -2846,6 +2895,9 @@ void __dls3(size_t *sp, size_t *auxv)
* copy relocations which depend on libraries' relocations. */
reloc_all(app.next, 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,
* since the TLS images might have contained relocated addresses. */
......@@ -3140,12 +3192,21 @@ static void *dlopen_impl(
/* Make new symbols global, at least temporarily, so we can do
* relocations. If not RTLD_GLOBAL, this is reverted below. */
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]);
}
}
struct dso *reloc_head_so = p;
if (!p->relocated) {
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
* 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.
先完成此消息的编辑!
想要评论请 注册