提交 7a8b94c5 编写于 作者: Y yaofeng wang

Merge branch 'buffer' of https://gitee.com/robottoy/third_party_musl into buffer

...@@ -1968,7 +1968,7 @@ LIBC { ...@@ -1968,7 +1968,7 @@ LIBC {
__mq_timedsend_time64; __mq_timedsend_time64;
shm_open; shm_open;
shm_unlink; shm_unlink;
# pthread_cancel; pthread_cancel;
# pthread_setcancelstate; # pthread_setcancelstate;
pthread_setcanceltype; pthread_setcanceltype;
pthread_testcancel; pthread_testcancel;
......
...@@ -2010,6 +2010,7 @@ musl_inc_root_files = [ ...@@ -2010,6 +2010,7 @@ musl_inc_root_files = [
] ]
musl_src_porting_file = [ musl_src_porting_file = [
"arch/aarch64/syscall_arch.h",
"arch/arm/bits/fenv.h", "arch/arm/bits/fenv.h",
"arch/generic/bits/shm.h", "arch/generic/bits/shm.h",
"arch/generic/crtbrand.s", "arch/generic/crtbrand.s",
...@@ -2125,6 +2126,11 @@ musl_src_porting_file = [ ...@@ -2125,6 +2126,11 @@ musl_src_porting_file = [
"src/ldso/riscv64/dlvsym.s", "src/ldso/riscv64/dlvsym.s",
"src/ldso/x86_64/dlvsym.s", "src/ldso/x86_64/dlvsym.s",
"src/stdio/__fdopen.c", "src/stdio/__fdopen.c",
"src/internal/vdso.c",
"src/time/clock_gettime.c",
"src/time/clock_getres.c",
"src/time/gettimeofday.c",
"src/time/time.c",
] ]
musl_inc_hook_files = [ musl_inc_hook_files = [
......
...@@ -279,6 +279,7 @@ template("musl_libs") { ...@@ -279,6 +279,7 @@ template("musl_libs") {
sources_orig -= [ sources_orig -= [
"src/thread/${musl_arch}/__set_thread_area.s", "src/thread/${musl_arch}/__set_thread_area.s",
"src/string/memcpy.c", "src/string/memcpy.c",
"src/string/memmove.c",
"src/string/memchr.c", "src/string/memchr.c",
"src/string/memcmp.c", "src/string/memcmp.c",
"src/string/strcpy.c", "src/string/strcpy.c",
...@@ -428,6 +429,7 @@ template("musl_libs") { ...@@ -428,6 +429,7 @@ template("musl_libs") {
"$OPTRTDIR/string/aarch64/strrchr.S", "$OPTRTDIR/string/aarch64/strrchr.S",
] ]
asmflags = [ asmflags = [
"-D__memmove_aarch64 = memmove",
"-D__memcpy_aarch64 = memcpy", "-D__memcpy_aarch64 = memcpy",
"-D__memchr_aarch64 = memchr", "-D__memchr_aarch64 = memchr",
"-D__memset_aarch64 = memset", "-D__memset_aarch64 = memset",
......
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define __SYSCALL_LL_E(x) (x)
#define __SYSCALL_LL_O(x) (x)
#define __asm_syscall(...) do { \
__asm__ __volatile__ ( "svc 0" \
: "=r"(x0) : __VA_ARGS__ : "memory", "cc"); \
return x0; \
} while (0)
static inline long __syscall0(long n)
{
register long x8 __asm__("x8") = n;
register long x0 __asm__("x0");
__asm_syscall("r"(x8));
}
static inline long __syscall1(long n, long a)
{
register long x8 __asm__("x8") = n;
register long x0 __asm__("x0") = a;
__asm_syscall("r"(x8), "0"(x0));
}
static inline long __syscall2(long n, long a, long b)
{
register long x8 __asm__("x8") = n;
register long x0 __asm__("x0") = a;
register long x1 __asm__("x1") = b;
__asm_syscall("r"(x8), "0"(x0), "r"(x1));
}
static inline long __syscall3(long n, long a, long b, long c)
{
register long x8 __asm__("x8") = n;
register long x0 __asm__("x0") = a;
register long x1 __asm__("x1") = b;
register long x2 __asm__("x2") = c;
__asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2));
}
static inline long __syscall4(long n, long a, long b, long c, long d)
{
register long x8 __asm__("x8") = n;
register long x0 __asm__("x0") = a;
register long x1 __asm__("x1") = b;
register long x2 __asm__("x2") = c;
register long x3 __asm__("x3") = d;
__asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3));
}
static inline long __syscall5(long n, long a, long b, long c, long d, long e)
{
register long x8 __asm__("x8") = n;
register long x0 __asm__("x0") = a;
register long x1 __asm__("x1") = b;
register long x2 __asm__("x2") = c;
register long x3 __asm__("x3") = d;
register long x4 __asm__("x4") = e;
__asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4));
}
static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
{
register long x8 __asm__("x8") = n;
register long x0 __asm__("x0") = a;
register long x1 __asm__("x1") = b;
register long x2 __asm__("x2") = c;
register long x3 __asm__("x3") = d;
register long x4 __asm__("x4") = e;
register long x5 __asm__("x5") = f;
__asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5));
}
#define VDSO_USEFUL
#define VDSO_CGT_SYM "__kernel_clock_gettime"
#define VDSO_CGT_VER "LINUX_2.6.39"
#define VDSO_CGR_SYM "__kernel_clock_getres"
#define VDSO_CGR_VER "LINUX_2.6.39"
#define VDSO_GTD_SYM "__kernel_gettimeofday"
#define VDSO_GTD_VER "LINUX_2.6.39"
#define IPC_64 0
...@@ -1757,8 +1757,6 @@ struct dso *load_library( ...@@ -1757,8 +1757,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, '/')) {
...@@ -1777,8 +1775,6 @@ struct dso *load_library( ...@@ -1777,8 +1775,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) {
...@@ -1839,8 +1835,6 @@ struct dso *load_library( ...@@ -1839,8 +1835,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;
} }
...@@ -1886,7 +1880,6 @@ struct dso *load_library( ...@@ -1886,7 +1880,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. */
...@@ -2487,7 +2480,6 @@ void __dls3(size_t *sp, size_t *auxv) ...@@ -2487,7 +2480,6 @@ void __dls3(size_t *sp, size_t *auxv)
#ifdef OHOS_ENABLE_PARAMETER #ifdef OHOS_ENABLE_PARAMETER
InitParameterClient(); InitParameterClient();
#endif #endif
musl_log_reset();
ld_log_reset(); ld_log_reset();
/* If the main program was already loaded by the kernel, /* If the main program was already loaded by the kernel,
* AT_PHDR will point to some location other than the dynamic * AT_PHDR will point to some location other than the dynamic
...@@ -2787,7 +2779,7 @@ static void prepare_lazy(struct dso *p) ...@@ -2787,7 +2779,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;
...@@ -2802,9 +2794,6 @@ static void *dlopen_impl( ...@@ -2802,9 +2794,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;
...@@ -2812,12 +2801,8 @@ static void *dlopen_impl( ...@@ -2812,12 +2801,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) {
...@@ -2908,16 +2893,16 @@ static void *dlopen_impl( ...@@ -2908,16 +2893,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) {
...@@ -2925,7 +2910,7 @@ static void *dlopen_impl( ...@@ -2925,7 +2910,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",
...@@ -3005,15 +2990,6 @@ static void *dlopen_impl( ...@@ -3005,15 +2990,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();
...@@ -3031,11 +3007,39 @@ end: ...@@ -3031,11 +3007,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)
...@@ -3252,8 +3256,10 @@ static void *do_dlsym(struct dso *p, const char *s, const char *v, void *ra) ...@@ -3252,8 +3256,10 @@ static void *do_dlsym(struct dso *p, const char *s, const char *v, void *ra)
if (!p) p=head; if (!p) p=head;
p = p->next; p = p->next;
ra2dso = true; ra2dso = true;
#ifndef HANDLE_RANDOMIZATION
} else if (__dl_invalid_handle(p)) { } else if (__dl_invalid_handle(p)) {
return 0; return 0;
#endif
} else { } else {
use_deps = 1; use_deps = 1;
ns = p->namespace; ns = p->namespace;
...@@ -3278,9 +3284,8 @@ static void *do_dlsym(struct dso *p, const char *s, const char *v, void *ra) ...@@ -3278,9 +3284,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;
...@@ -3297,8 +3302,7 @@ static int do_dlclose(struct dso *p) ...@@ -3297,8 +3302,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 */
...@@ -3384,6 +3388,46 @@ static int do_dlclose(struct dso *p) ...@@ -3384,6 +3388,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;
...@@ -3487,7 +3531,6 @@ int dladdr(const void *addr_arg, Dl_info *info) ...@@ -3487,7 +3531,6 @@ int dladdr(const void *addr_arg, Dl_info *info)
hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra) hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
{ {
void *res; void *res;
musl_log_reset();
ld_log_reset(); ld_log_reset();
pthread_rwlock_rdlock(&lock); pthread_rwlock_rdlock(&lock);
#ifdef HANDLE_RANDOMIZATION #ifdef HANDLE_RANDOMIZATION
...@@ -3511,7 +3554,6 @@ hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra ...@@ -3511,7 +3554,6 @@ hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra
hidden void *__dlvsym(void *restrict p, const char *restrict s, const char *restrict v, void *restrict ra) hidden void *__dlvsym(void *restrict p, const char *restrict s, const char *restrict v, void *restrict ra)
{ {
void *res; void *res;
musl_log_reset();
ld_log_reset(); ld_log_reset();
pthread_rwlock_rdlock(&lock); pthread_rwlock_rdlock(&lock);
#ifdef HANDLE_RANDOMIZATION #ifdef HANDLE_RANDOMIZATION
...@@ -4104,8 +4146,6 @@ static bool load_library_header(struct loadtask *task) ...@@ -4104,8 +4146,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;
} }
...@@ -4121,9 +4161,7 @@ static bool load_library_header(struct loadtask *task) ...@@ -4121,9 +4161,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) {
...@@ -4189,9 +4227,7 @@ static bool load_library_header(struct loadtask *task) ...@@ -4189,9 +4227,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;
} }
...@@ -4297,7 +4333,6 @@ static void task_load_library(struct loadtask *task, struct reserved_address_par ...@@ -4297,7 +4333,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;
......
...@@ -377,4 +377,7 @@ hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned); ...@@ -377,4 +377,7 @@ hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned);
hidden void *__vdsosym(const char *, const char *); hidden void *__vdsosym(const char *, const char *);
hidden void __get_vdso_info();
hidden void *__get_vdso_addr(const char *, const char *);
#endif #endif
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <elf.h>
#include <link.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
#include "libc.h"
#include "syscall.h"
#ifdef VDSO_USEFUL
#if ULONG_MAX == 0xffffffff
typedef Elf32_Ehdr Ehdr;
typedef Elf32_Phdr Phdr;
typedef Elf32_Sym Sym;
typedef Elf32_Verdef Verdef;
typedef Elf32_Verdaux Verdaux;
#else
typedef Elf64_Ehdr Ehdr;
typedef Elf64_Phdr Phdr;
typedef Elf64_Sym Sym;
typedef Elf64_Verdef Verdef;
typedef Elf64_Verdaux Verdaux;
#endif
static int checkver(Verdef *def, int vsym, const char *vername, char *strings)
{
vsym &= 0x7fff;
for (;;) {
if (!(def->vd_flags & VER_FLG_BASE)
&& (def->vd_ndx & 0x7fff) == vsym)
break;
if (def->vd_next == 0)
return 0;
def = (Verdef *)((char *)def + def->vd_next);
}
Verdaux *aux = (Verdaux *)((char *)def + def->vd_aux);
return !strcmp(vername, strings + aux->vda_name);
}
#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON)
#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
struct __vdso_info {
size_t base;
char *strings;
Sym *syms;
Elf_Symndx *hashtab;
uint16_t *versym;
Verdef *verdef;
} vdso_info = {-1, 0, 0, 0, 0, 0};
void __get_vdso_info()
{
if (vdso_info.base != -1) {
return ;
}
size_t i;
for (i=0; libc.auxv[i] != AT_SYSINFO_EHDR; i+=2)
if (!libc.auxv[i]) return ;
if (!libc.auxv[i+1]) return ;
Ehdr *eh = (void *)libc.auxv[i+1];
Phdr *ph = (void *)((char *)eh + eh->e_phoff);
size_t *dynv=0, base=-1;
for (i=0; i<eh->e_phnum; i++, ph=(void *)((char *)ph+eh->e_phentsize)) {
if (ph->p_type == PT_LOAD)
base = (size_t)eh + ph->p_offset - ph->p_vaddr;
else if (ph->p_type == PT_DYNAMIC)
dynv = (void *)((char *)eh + ph->p_offset);
}
if (!dynv || base==(size_t)-1) return ;
for (i=0; dynv[i]; i+=2) {
void *p = (void *)(base + dynv[i+1]);
switch(dynv[i]) {
case DT_STRTAB: vdso_info.strings = p; break;
case DT_SYMTAB: vdso_info.syms = p; break;
case DT_HASH: vdso_info.hashtab = p; break;
case DT_VERSYM: vdso_info.versym = p; break;
case DT_VERDEF: vdso_info.verdef = p; break;
}
}
vdso_info.base = base;
return ;
}
void *__get_vdso_addr(const char *vername, const char *name)
{
if (!vdso_info.strings || !vdso_info.syms || !vdso_info.hashtab) return 0;
if (!vdso_info.verdef) vdso_info.versym = 0;
size_t i;
for (i=0; i<vdso_info.hashtab[1]; i++) {
if (!(1<<(vdso_info.syms[i].st_info&0xf) & OK_TYPES)) continue;
if (!(1<<(vdso_info.syms[i].st_info>>4) & OK_BINDS)) continue;
if (!vdso_info.syms[i].st_shndx) continue;
if (strcmp(name, vdso_info.strings+vdso_info.syms[i].st_name)) continue;
if (vdso_info.versym && !checkver(vdso_info.verdef, vdso_info.versym[i], vername, vdso_info.strings))
continue;
return (void *)(vdso_info.base + vdso_info.syms[i].st_value);
}
return 0;
}
#endif
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <time.h>
#include <errno.h>
#include <stdint.h>
#include "syscall.h"
#include "atomic.h"
#ifdef VDSO_CGR_SYM
static void *volatile vdso_cgr;
static int cgr_init(clockid_t clk, struct timespec *ts)
{
__get_vdso_info();
void *p = __get_vdso_addr(VDSO_CGR_VER, VDSO_CGR_SYM);
int (*f)(clockid_t, struct timespec *) =
(int (*)(clockid_t, struct timespec *))p;
a_cas_p(&vdso_cgr, (void *)cgr_init, p);
return f ? f(clk, ts) : -ENOSYS;
}
static void *volatile vdso_cgr = (void *)cgr_init;
#endif
int clock_getres(clockid_t clk, struct timespec *ts)
{
int r;
#ifdef VDSO_CGR_SYM
int (*f)(clockid_t, struct timespec *) =
(int (*)(clockid_t, struct timespec *))vdso_cgr;
if (f) {
r = f(clk, ts);
if (!r) return r;
if (r == -EINVAL) return __syscall_ret(r);
}
#endif
#ifdef SYS_clock_getres_time64
/* On a 32-bit arch, use the old syscall if it exists. */
if (SYS_clock_getres != SYS_clock_getres_time64) {
long ts32[2];
r = __syscall(SYS_clock_getres, clk, ts32);
if (!r && ts) {
ts->tv_sec = ts32[0];
ts->tv_nsec = ts32[1];
}
return __syscall_ret(r);
}
#endif
/* If reaching this point, it's a 64-bit arch or time64-only
* 32-bit arch and we can get result directly into timespec. */
return syscall(SYS_clock_getres, clk, ts);
}
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <time.h>
#include <errno.h>
#include <stdint.h>
#include "syscall.h"
#include "atomic.h"
#ifdef VDSO_CGT_SYM
static void *volatile vdso_func;
#ifdef VDSO_CGT32_SYM
static void *volatile vdso_func_32;
static int cgt_time32_wrap(clockid_t clk, struct timespec *ts)
{
long ts32[2];
int (*f)(clockid_t, long[2]) =
(int (*)(clockid_t, long[2]))vdso_func_32;
int r = f(clk, ts32);
if (!r) {
/* Fallback to syscalls if time32 overflowed. Maybe
* we lucked out and somehow migrated to a kernel with
* time64 syscalls available. */
if (ts32[0] < 0) {
a_cas_p(&vdso_func, (void *)cgt_time32_wrap, 0);
return -ENOSYS;
}
ts->tv_sec = ts32[0];
ts->tv_nsec = ts32[1];
}
return r;
}
#endif
static int cgt_init(clockid_t clk, struct timespec *ts)
{
__get_vdso_info();
void *p = __get_vdso_addr(VDSO_CGT_VER, VDSO_CGT_SYM);
#ifdef VDSO_CGT32_SYM
if (!p) {
void *q = __get_vdso_addr(VDSO_CGT32_VER, VDSO_CGT32_SYM);
if (q) {
a_cas_p(&vdso_func_32, 0, q);
p = cgt_time32_wrap;
}
}
#endif
int (*f)(clockid_t, struct timespec *) =
(int (*)(clockid_t, struct timespec *))p;
a_cas_p(&vdso_func, (void *)cgt_init, p);
return f ? f(clk, ts) : -ENOSYS;
}
static void *volatile vdso_func = (void *)cgt_init;
#endif
int __clock_gettime(clockid_t clk, struct timespec *ts)
{
int r;
#ifdef VDSO_CGT_SYM
int (*f)(clockid_t, struct timespec *) =
(int (*)(clockid_t, struct timespec *))vdso_func;
if (f) {
r = f(clk, ts);
if (!r) return r;
if (r == -EINVAL) return __syscall_ret(r);
/* Fall through on errors other than EINVAL. Some buggy
* vdso implementations return ENOSYS for clocks they
* can't handle, rather than making the syscall. This
* also handles the case where cgt_init fails to find
* a vdso function to use. */
}
#endif
#ifdef SYS_clock_gettime64
r = -ENOSYS;
if (sizeof(time_t) > 4)
r = __syscall(SYS_clock_gettime64, clk, ts);
if (SYS_clock_gettime == SYS_clock_gettime64 || r!=-ENOSYS)
return __syscall_ret(r);
long ts32[2];
r = __syscall(SYS_clock_gettime, clk, ts32);
if (r==-ENOSYS && clk==CLOCK_REALTIME) {
r = __syscall(SYS_gettimeofday, ts32, 0);
ts32[1] *= 1000;
}
if (!r) {
ts->tv_sec = ts32[0];
ts->tv_nsec = ts32[1];
return r;
}
return __syscall_ret(r);
#else
r = __syscall(SYS_clock_gettime, clk, ts);
if (r == -ENOSYS) {
if (clk == CLOCK_REALTIME) {
__syscall(SYS_gettimeofday, ts, 0);
ts->tv_nsec = (int)ts->tv_nsec * 1000;
return 0;
}
r = -EINVAL;
}
return __syscall_ret(r);
#endif
}
weak_alias(__clock_gettime, clock_gettime);
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <time.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <stdint.h>
#include "syscall.h"
#include "atomic.h"
#ifdef VDSO_GTD_SYM
static void *volatile vdso_gtd;
static int gtd_init(struct timeval *tv, void *tz)
{
__get_vdso_info();
void *p = __get_vdso_addr(VDSO_GTD_VER, VDSO_GTD_SYM);
int (*f)(struct timeval *, void *) =
(int (*)(struct timval *, void *))p;
a_cas_p(&vdso_gtd, (void *)gtd_init, p);
return f ? f(tv, tz) : -ENOSYS;
}
static void *volatile vdso_gtd = (void *)gtd_init;
#endif
int gettimeofday(struct timeval *restrict tv, void *restrict tz)
{
#ifdef VDSO_GTD_SYM
int r;
int (*f)(struct timeval *, void *) =
(int (*)(struct timeval *, void *))vdso_gtd;
if (f) {
r = f(tv, tz);
if (!r) return r;
if (r == -EINVAL) return __syscall_ret(r);
}
#endif
struct timespec ts;
if (!tv) return 0;
clock_gettime(CLOCK_REALTIME, &ts);
tv->tv_sec = ts.tv_sec;
tv->tv_usec = (int)ts.tv_nsec / 1000;
return 0;
}
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <time.h>
#include <errno.h>
#include <stdint.h>
#include "syscall.h"
#include "atomic.h"
#ifdef VDSO_TIME_SYM
static void *volatile vdso_time;
static time_t time_init(time_t *t)
{
__get_vdso_info();
void *p = __get_vdso_addr(VDSO_TIME_VER, VDSO_TIME_SYM);
time_t (*f)(time_t *) =
(time_t (*)(time_t *))p;
a_cas_p(&vdso_time, (void *)time_init, p);
return f ? f(t) : -ENOSYS;
}
static void *volatile vdso_time = (void *)time_init;
#endif
time_t time(time_t *t)
{
#ifdef VDSO_TIME_SYM
time_t (*f)(time_t *) =
(time_t (*)(time_t *))vdso_time;
if (f) {
return f(t);
}
#endif
struct timespec ts;
__clock_gettime(CLOCK_REALTIME, &ts);
if (t) *t = ts.tv_sec;
return ts.tv_sec;
}
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "los_config.h" #include "los_config.h"
#include "los_memory.h" #include "los_memory.h"
#ifdef LOSCFG_LIBC_ICCARM_MALLOC
void *calloc(size_t nitems, size_t size) void *calloc(size_t nitems, size_t size)
{ {
size_t real_size; size_t real_size;
...@@ -105,3 +106,4 @@ void *realloc(void *ptr, size_t size) ...@@ -105,3 +106,4 @@ void *realloc(void *ptr, size_t size)
return LOS_MemRealloc(OS_SYS_MEM_ADDR, ptr, size); return LOS_MemRealloc(OS_SYS_MEM_ADDR, ptr, size);
} }
#endif
...@@ -163,10 +163,12 @@ int sem_close(sem_t *sem) ...@@ -163,10 +163,12 @@ int sem_close(sem_t *sem)
int i; int i;
LOCK(lock); LOCK(lock);
for (i=0; i<SEM_NSEMS_MAX && semtab[i].sem != sem; i++); for (i=0; i<SEM_NSEMS_MAX && semtab[i].sem != sem; i++);
if (!--semtab[i].refcnt) { if (--semtab[i].refcnt) {
semtab[i].sem = 0; UNLOCK(lock);
semtab[i].ino = 0; return 0;
} }
semtab[i].sem = 0;
semtab[i].ino = 0;
UNLOCK(lock); UNLOCK(lock);
munmap(sem, sizeof *sem); munmap(sem, sizeof *sem);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册