提交 1ad26732 编写于 作者: D dhy308

fixed cac9d8d3 from https://gitee.com/dhy308/third_party_musl/pulls/612

在dlclose中实现卸载依赖库功能
Signed-off-by: Ndhy308 <tony.gan@huawei.com>
上级 ffdb7b7c
...@@ -1742,8 +1742,6 @@ struct dso *load_library( ...@@ -1742,8 +1742,6 @@ struct dso *load_library(
ldso.namespace = namespace; ldso.namespace = namespace;
ns_add_dso(namespace, &ldso); ns_add_dso(namespace, &ldso);
} }
/* increase libc dlopen refcnt */
a_inc(&ldso.nr_dlopen);
return &ldso; return &ldso;
} }
if (strchr(name, '/')) { if (strchr(name, '/')) {
...@@ -1762,8 +1760,6 @@ struct dso *load_library( ...@@ -1762,8 +1760,6 @@ struct dso *load_library(
p = find_library_by_name(name, namespace, check_inherited); p = find_library_by_name(name, namespace, check_inherited);
if (p) { if (p) {
LD_LOGD("load_library find_library_by_name found p, return it!"); LD_LOGD("load_library find_library_by_name found p, return it!");
/* increase dlopen refcnt */
a_inc(&p->nr_dlopen);
return p; return p;
} }
if (strlen(name) > NAME_MAX) { if (strlen(name) > NAME_MAX) {
...@@ -1824,8 +1820,6 @@ struct dso *load_library( ...@@ -1824,8 +1820,6 @@ struct dso *load_library(
if (!p->shortname && pathname != name) if (!p->shortname && pathname != name)
p->shortname = strrchr(p->name, '/')+1; p->shortname = strrchr(p->name, '/')+1;
close(fd); close(fd);
/* increase dlopen refcnt */
a_inc(&p->nr_dlopen);
LD_LOGD("load_library find_library_by_fstat, found p and return it!"); LD_LOGD("load_library find_library_by_fstat, found p and return it!");
return p; return p;
} }
...@@ -1871,7 +1865,6 @@ struct dso *load_library( ...@@ -1871,7 +1865,6 @@ struct dso *load_library(
p->ino = st.st_ino; p->ino = st.st_ino;
p->needed_by = needed_by; p->needed_by = needed_by;
p->name = p->buf; p->name = p->buf;
p->nr_dlopen = 1;
p->runtime_loaded = runtime; p->runtime_loaded = runtime;
strcpy(p->name, pathname); strcpy(p->name, pathname);
/* Add a shortname only if name arg was not an explicit pathname. */ /* Add a shortname only if name arg was not an explicit pathname. */
...@@ -2772,7 +2765,7 @@ static void prepare_lazy(struct dso *p) ...@@ -2772,7 +2765,7 @@ static void prepare_lazy(struct dso *p)
} }
/* add namespace function */ /* add namespace function */
static void *dlopen_impl( static void *dlopen_impl_orig(
const char *file, int mode, const char *namespace, const void *caller_addr, const dl_extinfo *extinfo) const char *file, int mode, const char *namespace, const void *caller_addr, const dl_extinfo *extinfo)
{ {
struct dso *volatile p, *orig_tail, *orig_syms_tail, *orig_lazy_head, *next; struct dso *volatile p, *orig_tail, *orig_syms_tail, *orig_lazy_head, *next;
...@@ -2787,9 +2780,6 @@ static void *dlopen_impl( ...@@ -2787,9 +2780,6 @@ static void *dlopen_impl(
bool reserved_address = false; bool reserved_address = false;
bool reserved_address_recursive = false; bool reserved_address_recursive = false;
struct reserved_address_params reserved_params = {0}; struct reserved_address_params reserved_params = {0};
#ifdef HANDLE_RANDOMIZATION
void *handle = 0;
#endif
#ifdef LOAD_ORDER_RANDOMIZATION #ifdef LOAD_ORDER_RANDOMIZATION
struct loadtasks *tasks = NULL; struct loadtasks *tasks = NULL;
struct loadtask *task = NULL; struct loadtask *task = NULL;
...@@ -2797,12 +2787,8 @@ static void *dlopen_impl( ...@@ -2797,12 +2787,8 @@ static void *dlopen_impl(
#endif #endif
if (!file) { if (!file) {
LD_LOGD("dlopen_impl file is null, return head."); LD_LOGD("dlopen_impl_orig file is null, return head.");
#ifdef HANDLE_RANDOMIZATION
return assign_valid_handle(head);
#else
return head; return head;
#endif
} }
if (extinfo) { if (extinfo) {
...@@ -2893,16 +2879,16 @@ static void *dlopen_impl( ...@@ -2893,16 +2879,16 @@ static void *dlopen_impl(
#ifdef LOAD_ORDER_RANDOMIZATION #ifdef LOAD_ORDER_RANDOMIZATION
tasks = create_loadtasks(); tasks = create_loadtasks();
if (!tasks) { if (!tasks) {
LD_LOGE("dlopen_impl create loadtasks failed"); LD_LOGE("dlopen_impl_orig create loadtasks failed");
goto end; goto end;
} }
task = create_loadtask(file, head, ns, true); task = create_loadtask(file, head, ns, true);
if (!task) { if (!task) {
LD_LOGE("dlopen_impl create loadtask failed"); LD_LOGE("dlopen_impl_orig create loadtask failed");
goto end; goto end;
} }
if (!load_library_header(task)) { if (!load_library_header(task)) {
LD_LOGE("dlopen_impl load library header failed for %{public}s", task->name); LD_LOGE("dlopen_impl_orig load library header failed for %{public}s", task->name);
goto end; goto end;
} }
if (reserved_address) { if (reserved_address) {
...@@ -2910,7 +2896,7 @@ static void *dlopen_impl( ...@@ -2910,7 +2896,7 @@ static void *dlopen_impl(
} }
} }
if (!task->p) { if (!task->p) {
LD_LOGE("dlopen_impl load library failed for %{public}s", task->name); LD_LOGE("dlopen_impl_orig load library failed for %{public}s", task->name);
error(noload ? error(noload ?
"Library %s is not already loaded" : "Library %s is not already loaded" :
"Error loading shared library %s: %m", "Error loading shared library %s: %m",
...@@ -2990,15 +2976,6 @@ static void *dlopen_impl( ...@@ -2990,15 +2976,6 @@ static void *dlopen_impl(
if (tls_cnt != orig_tls_cnt) if (tls_cnt != orig_tls_cnt)
install_new_tls(); install_new_tls();
orig_tail = tail; orig_tail = tail;
#ifdef HANDLE_RANDOMIZATION
handle = assign_valid_handle(p);
if (handle == 0) {
LD_LOGE("generate random handle failed");
do_dlclose(p);
p = 0;
}
#endif
end: end:
debug.state = RT_CONSISTENT; debug.state = RT_CONSISTENT;
_dl_debug_state(); _dl_debug_state();
...@@ -3016,11 +2993,39 @@ end: ...@@ -3016,11 +2993,39 @@ end:
internal_free(ctor_queue); internal_free(ctor_queue);
} }
pthread_setcancelstate(cs, 0); pthread_setcancelstate(cs, 0);
return p;
}
static void *dlopen_impl(
const char *file, int mode, const char *namespace, const void *caller_addr, const dl_extinfo *extinfo){
struct dso* p = (struct dso*)dlopen_impl_orig(file, mode, namespace, caller_addr, extinfo);
if (p == NULL) {
return p;
}
p->nr_dlopen++;
if (p->bfs_built) {
for (int i = 0; p->deps[i]; i++) {
p->deps[i]->nr_dlopen++;
if (mode & RTLD_NODELETE) {
p->deps[i]->flags |= DSO_FLAGS_NODELETE;
}
}
}
#ifdef HANDLE_RANDOMIZATION #ifdef HANDLE_RANDOMIZATION
void *handle = assign_valid_handle(p);
if (handle == NULL) {
LD_LOGE("dlopen_impl: generate random handle failed");
do_dlclose(p);
}
return handle; return handle;
#else
return p;
#endif #endif
return p;
} }
void *dlopen(const char *file, int mode) void *dlopen(const char *file, int mode)
...@@ -3263,9 +3268,8 @@ static void *do_dlsym(struct dso *p, const char *s, const char *v, void *ra) ...@@ -3263,9 +3268,8 @@ static void *do_dlsym(struct dso *p, const char *s, const char *v, void *ra)
return laddr(def.dso, def.sym->st_value); return laddr(def.dso, def.sym->st_value);
} }
static int do_dlclose(struct dso *p) static int dlclose_impl(struct dso *p)
{ {
int old;
size_t n; size_t n;
struct dso *d; struct dso *d;
...@@ -3282,8 +3286,7 @@ static int do_dlclose(struct dso *p) ...@@ -3282,8 +3286,7 @@ static int do_dlclose(struct dso *p)
return 0; return 0;
} }
old = a_fetch_add(&p->nr_dlopen, -1); if (--(p->nr_dlopen) > 0)
if (old > 1)
return 0; return 0;
/* call destructors if needed */ /* call destructors if needed */
...@@ -3369,6 +3372,46 @@ static int do_dlclose(struct dso *p) ...@@ -3369,6 +3372,46 @@ static int do_dlclose(struct dso *p)
return 0; return 0;
} }
static char* dlclose_deps_black_list[] =
{
"/system/lib64/libhidebug.so",
"/system/lib64/libmsdp_neardetect_algorithm.z.so",
"/vendor/lib64/libhril_hdf.z.so"
};
static int do_dlclose(struct dso *p)
{
bool ldclose_deps = true;
for (int i = 0; i < sizeof(dlclose_deps_black_list)/sizeof(char*); i++) {
if (!strcmp(dlclose_deps_black_list[i], p->name)) {
ldclose_deps = false;
break;
}
}
size_t deps_num;
for (deps_num = 0; p->deps[deps_num]; deps_num++);
struct dso **deps_bak = malloc(deps_num*sizeof(struct dso*));
if (deps_bak != NULL) {
memcpy(deps_bak, p->deps, deps_num*sizeof(struct dso*));
}
LD_LOGI("do_dlclose name=%{public}s count=%{public}d by_dlopen=%{public}d", p->name, p->nr_dlopen, p->by_dlopen);
dlclose_impl(p);
if (ldclose_deps) {
for (size_t i = 0; i < deps_num; i++) {
LD_LOGI("do_dlclose name=%{public}s count=%{public}d by_dlopen=%{public}d", deps_bak[i]->name, deps_bak[i]->nr_dlopen, deps_bak[i]->by_dlopen);
dlclose_impl(deps_bak[i]);
}
}
free(deps_bak);
}
hidden int __dlclose(void *p) hidden int __dlclose(void *p)
{ {
int rc; int rc;
...@@ -4089,8 +4132,6 @@ static bool load_library_header(struct loadtask *task) ...@@ -4089,8 +4132,6 @@ static bool load_library_header(struct loadtask *task)
ns_add_dso(namespace, &ldso); ns_add_dso(namespace, &ldso);
} }
task->isloaded = true; task->isloaded = true;
/* increase libc dlopen refcnt */
a_inc(&ldso.nr_dlopen);
task->p = &ldso; task->p = &ldso;
return true; return true;
} }
...@@ -4106,9 +4147,7 @@ static bool load_library_header(struct loadtask *task) ...@@ -4106,9 +4147,7 @@ static bool load_library_header(struct loadtask *task)
/* Search in namespace */ /* Search in namespace */
task->p = find_library_by_name(name, namespace, check_inherited); task->p = find_library_by_name(name, namespace, check_inherited);
if (task->p) { if (task->p) {
/* increase dlopen refcnt */
task->isloaded = true; task->isloaded = true;
a_inc(&task->p->nr_dlopen);
return true; return true;
} }
if (strlen(name) > NAME_MAX) { if (strlen(name) > NAME_MAX) {
...@@ -4174,9 +4213,7 @@ static bool load_library_header(struct loadtask *task) ...@@ -4174,9 +4213,7 @@ static bool load_library_header(struct loadtask *task)
} }
close(task->fd); close(task->fd);
task->fd = -1; task->fd = -1;
/* increase dlopen refcnt */
task->isloaded = true; task->isloaded = true;
a_inc(&task->p->nr_dlopen);
return true; return true;
} }
...@@ -4282,7 +4319,6 @@ static void task_load_library(struct loadtask *task, struct reserved_address_par ...@@ -4282,7 +4319,6 @@ static void task_load_library(struct loadtask *task, struct reserved_address_par
if (!runtime) { if (!runtime) {
reclaim_gaps(task->p); reclaim_gaps(task->p);
} }
task->p->nr_dlopen = 1;
task->p->runtime_loaded = runtime; task->p->runtime_loaded = runtime;
if (runtime) if (runtime)
task->p->by_dlopen = 1; task->p->by_dlopen = 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册