Skip to content
Snippets Groups Projects
Commit 29122488 authored by Esben Haabendal's avatar Esben Haabendal Committed by Thierry Escande
Browse files

musl: Add OpenHarmony patch to OpenHarmony-3.1-Release


This adds the musl patches based on the OpenHarmony-v3.1-Release tag in
the OpenHarmony musl repository.

Signed-off-by: default avatarEsben Haabendal <esben.haabendal@huawei.com>
parent b0f13def
No related branches found
No related tags found
1 merge request!10OpenHarmony 3.1
# SPDX-FileCopyrightText: Huawei Inc.
#
# SPDX-License-Identifier: Apache-2.0
Patch generated from OpenHarmony-v3.1-Release version, with the following commands:
git diff --no-renames v1.2.0..OpenHarmony-v3.1-Release | \
filterdiff -x '*/porting/*' -x '?/.gitee/*' -x '*/BUILD.gn' -x '*/*.gni' \
-x '*/OAT.xml' -x '*/README.OpenSource' -x '*/scripts/*' \
-x '*/ndk_script/*' -x '*/bundle.json' -x '*/libc-test/*' \
> openharmony-common.patch
Upstream-status: Pending
Signed-off-by: Esben Haabendal <esben.haabendal@huawei.com>
diff --git a/arch/aarch64/bits/signal.h b/arch/aarch64/bits/signal.h
old mode 100644
new mode 100755
index b71261f56816..760a9f323bcb
--- a/arch/aarch64/bits/signal.h
+++ b/arch/aarch64/bits/signal.h
@@ -149,5 +149,7 @@ typedef struct __ucontext {
#define SIGPWR 30
#define SIGSYS 31
#define SIGUNUSED SIGSYS
+#define SIGHOOK 36
+#define SIGUNHOOK 37
#define _NSIG 65
diff --git a/arch/arm/bits/signal.h b/arch/arm/bits/signal.h
index 3c78985672df..213e5fc23b9d 100644
--- a/arch/arm/bits/signal.h
+++ b/arch/arm/bits/signal.h
@@ -82,5 +82,7 @@ typedef struct __ucontext {
#define SIGPWR 30
#define SIGSYS 31
#define SIGUNUSED SIGSYS
+#define SIGHOOK 36
+#define SIGUNHOOK 37
#define _NSIG 65
diff --git a/arch/arm/syscall_arch.h b/arch/arm/syscall_arch.h
index 4b08762d7b35..a877b2cff196 100644
--- a/arch/arm/syscall_arch.h
+++ b/arch/arm/syscall_arch.h
@@ -98,12 +98,6 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
__asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
}
-#define VDSO_USEFUL
-#define VDSO_CGT32_SYM "__vdso_clock_gettime"
-#define VDSO_CGT32_VER "LINUX_2.6"
-#define VDSO_CGT_SYM "__vdso_clock_gettime64"
-#define VDSO_CGT_VER "LINUX_2.6"
-
#define SYSCALL_FADVISE_6_ARG
#define SYSCALL_IPC_BROKEN_MODE
diff --git a/dynamic.list b/dynamic.list
index ee0d363b648d..d427f5ace030 100644
--- a/dynamic.list
+++ b/dynamic.list
@@ -14,6 +14,8 @@ memalign;
posix_memalign;
aligned_alloc;
malloc_usable_size;
+mallinfo;
+mallinfo2;
timezone;
daylight;
diff --git a/include/malloc.h b/include/malloc.h
index 35f8b19c2c34..98ba01000134 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -18,6 +18,36 @@ void *memalign(size_t, size_t);
size_t malloc_usable_size(void *);
+struct mallinfo {
+ int arena;
+ int ordblks;
+ int smblks;
+ int hblks;
+ int hblkhd;
+ int usmblks;
+ int fsmblks;
+ int uordblks;
+ int fordblks;
+ int keepcost;
+};
+
+struct mallinfo mallinfo(void);
+
+struct mallinfo2 {
+ size_t arena;
+ size_t ordblks;
+ size_t smblks;
+ size_t hblks;
+ size_t hblkhd;
+ size_t usmblks;
+ size_t fsmblks;
+ size_t uordblks;
+ size_t fordblks;
+ size_t keepcost;
+};
+
+struct mallinfo2 mallinfo2(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/sys/prctl.h b/include/sys/prctl.h
index d9c846e9c2ea..769229f56bc7 100644
--- a/include/sys/prctl.h
+++ b/include/sys/prctl.h
@@ -158,6 +158,9 @@ struct prctl_mm_map {
#define PR_GET_TAGGED_ADDR_CTRL 56
#define PR_TAGGED_ADDR_ENABLE (1UL << 0)
+#define PR_SET_VMA 0x53564d41
+#define PR_SET_VMA_ANON_NAME 0
+
int prctl (int, ...);
#ifdef __cplusplus
diff --git a/src/malloc/expand_heap.c b/src/malloc/expand_heap.c
index e6a3d7a000eb..ab4eb5a3593e 100644
--- a/src/malloc/expand_heap.c
+++ b/src/malloc/expand_heap.c
@@ -6,6 +6,8 @@
#include "syscall.h"
#include "malloc_impl.h"
+#include <sys/prctl.h>
+
/* This function returns true if the interval [old,new]
* intersects the 'len'-sized interval below &libc.auxv
* (interpreted as the main-thread stack) or below &b
@@ -65,6 +67,8 @@ void *__expand_heap(size_t *pn)
void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (area == MAP_FAILED) return 0;
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, area, n, "native_heap:musl");
+
*pn = n;
mmap_step++;
return area;
diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c
index 96982596b94d..51fa4a3ac399 100644
--- a/src/malloc/malloc.c
+++ b/src/malloc/malloc.c
@@ -293,6 +293,9 @@ void *malloc(size_t n)
char *base = __mmap(0, len, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (base == (void *)-1) return 0;
+
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, base, len, "native_heap:musl");
+
c = (void *)(base + SIZE_ALIGN - OVERHEAD);
c->csize = len - (SIZE_ALIGN - OVERHEAD);
c->psize = SIZE_ALIGN - OVERHEAD;
diff --git a/src/malloc/mallocng/mallinfo.c b/src/malloc/mallocng/mallinfo.c
new file mode 100644
index 000000000000..6e0856ae3d6f
--- /dev/null
+++ b/src/malloc/mallocng/mallinfo.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2021 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 <limits.h>
+#include <malloc.h>
+#include <stddef.h>
+
+#if 0
+#include "glue.h"
+#include "meta.h"
+
+static void accumulate_meta(struct mallinfo2 *mi, struct meta *g) {
+ int sc = g->sizeclass;
+ if (sc >= 48) {
+ // Large mmap allocation
+ mi->hblks++;
+ mi->uordblks += g->maplen*4096;
+ mi->hblkhd += g->maplen*4096;
+ } else {
+ if (g->freeable && !g->maplen) {
+ // Small size slots are embedded in a larger slot, avoid double counting
+ // by subtracing the size of the larger slot from the total used memory.
+ struct meta* outer_g = get_meta((void*)g->mem);
+ int outer_sc = outer_g->sizeclass;
+ int outer_sz = size_classes[outer_sc]*UNIT;
+ mi->uordblks -= outer_sz;
+ }
+ int sz = size_classes[sc]*UNIT;
+ int mask = g->avail_mask | g->freed_mask;
+ int nr_unused = __builtin_popcount(mask);
+ mi->ordblks += nr_unused;
+ mi->uordblks += sz*(g->last_idx+1-nr_unused);
+ mi->fordblks += sz*nr_unused;
+ }
+}
+
+static void accumulate_meta_area(struct mallinfo2 *mi, struct meta_area *ma) {
+ for (int i=0; i<ma->nslots; i++) {
+ if (ma->slots[i].mem) {
+ accumulate_meta(mi, &ma->slots[i]);
+ }
+ }
+}
+#endif
+
+struct mallinfo2 mallinfo2() {
+
+ struct mallinfo2 mi = {0};
+
+#if 0
+ rdlock();
+ struct meta_area *ma = ctx.meta_area_head;
+ while (ma) {
+ accumulate_meta_area(&mi, ma);
+ ma = ma->next;
+ }
+ unlock();
+#endif
+
+ return mi;
+}
+
+#define cap(x) ((x > INT_MAX) ? INT_MAX : x)
+
+struct mallinfo mallinfo() {
+ struct mallinfo mi = {0};
+ struct mallinfo2 mi2 = mallinfo2();
+
+ mi.arena = cap(mi2.arena);
+ mi.ordblks = cap(mi2.ordblks);
+ mi.smblks = cap(mi2.smblks);
+ mi.hblks = cap(mi2.hblks);
+ mi.hblkhd = cap(mi2.hblkhd);
+ mi.usmblks = cap(mi2.usmblks);
+ mi.fsmblks = cap(mi2.fsmblks);
+ mi.uordblks = cap(mi2.uordblks);
+ mi.fordblks = cap(mi2.fordblks);
+ mi.keepcost = cap(mi2.keepcost);
+
+ return mi;
+}
diff --git a/src/mman/mmap.c b/src/mman/mmap.c
index eff88d82a8fc..763c248cdba9 100644
--- a/src/mman/mmap.c
+++ b/src/mman/mmap.c
@@ -22,6 +22,10 @@ void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
errno = ENOMEM;
return MAP_FAILED;
}
+ if (len == 0) {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
if (flags & MAP_FIXED) {
__vm_wait();
}
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
index 5f491092597e..62407c45dd1f 100644
--- a/src/thread/pthread_create.c
+++ b/src/thread/pthread_create.c
@@ -6,6 +6,15 @@
#include <sys/mman.h>
#include <string.h>
#include <stddef.h>
+#include <stdarg.h>
+
+void log_print(const char* info,...)
+{
+ va_list ap;
+ va_start(ap, info);
+ vfprintf(stdout,info, ap);
+ va_end(ap);
+}
static void dummy_0()
{
@@ -380,3 +389,34 @@ fail:
weak_alias(__pthread_exit, pthread_exit);
weak_alias(__pthread_create, pthread_create);
+
+struct pthread* __pthread_list_find(pthread_t thread_id, const char* info)
+{
+ struct pthread *thread = (struct pthread *)thread_id;
+ if (NULL == thread) {
+ log_print("invalid pthread_t (0) passed to %s\n", info);
+ return NULL;
+ }
+
+ struct pthread *self = __pthread_self();
+ if (thread == self) {
+ return thread;
+ }
+ struct pthread *t = self;
+ t = t->next ;
+ while (t != self) {
+ if (t == thread) return thread;
+ t = t->next ;
+ }
+ log_print("invalid pthread_t %p passed to %s\n", thread, info);
+ return NULL;
+}
+
+pid_t __pthread_gettid_np(pthread_t t)
+{
+ __tl_lock();
+ struct pthread* thread = __pthread_list_find(t, "pthread_gettid_np");
+ __tl_unlock();
+ return thread ? thread->tid : -1;
+}
+weak_alias(__pthread_gettid_np, pthread_gettid_np);
\ No newline at end of file
# SPDX-FileCopyrightText: Huawei Inc.
#
# SPDX-License-Identifier: Apache-2.0
Patch generated from OpenHarmony-v3.1-Release version, with the following commands:
cp -r porting/linux/user/* .
git add -A
git diff --staged > openharmony-linux-user.patch
This file contains only the hunk for sys/capabilty.h so that it can be
excluded for configurations with components that need libcap (which
already provide this header).
Upstream-status: Pending
Signed-off-by: Esben Haabendal <esben.haabendal@huawei.com>
diff --git a/include/sys/capability.h b/include/sys/capability.h
new file mode 100644
index 000000000000..ed2ff97783b1
--- /dev/null
+++ b/include/sys/capability.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
+ * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_CAPABILITY_H
+#define _SYS_CAPABILITY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <linux/capability.h>
+
+int capget(cap_user_header_t hdr_ptr, cap_user_data_t data_ptr);
+int capset(cap_user_header_t hdr_ptr, const cap_user_data_t data_ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_CAPABILITY_H */
# SPDX-FileCopyrightText: Huawei Inc.
#
# SPDX-License-Identifier: Apache-2.0
Patch generated from OpenHarmony-v3.1-Release version, with the following commands:
cp -r porting/linux/user/* .
git add -A
git diff --staged > openharmony-linux-user.patch
The hunks from 0001-Make-dynamic-linker-a-relative-symlink-to-libc.patch in
Yocto was removed manually afterwards.
The hunk for the file sys/capabilty.h has been moved to a seperate patch
file so it can be ignored for some configurations that include components
with a dependency on the libcap package, as this pakage already provide
this header.
Upstream-status: Pending
Signed-off-by: Esben Haabendal <esben.haabendal@huawei.com>
diff --git a/arch/arm/bits/fenv.h b/arch/arm/bits/fenv.h
index d85fc86d7947..b497a9878800 100644
--- a/arch/arm/bits/fenv.h
+++ b/arch/arm/bits/fenv.h
@@ -9,10 +9,10 @@
#define FE_INEXACT 16
#define FE_ALL_EXCEPT 31
#define FE_TONEAREST 0
-#define FE_DOWNWARD 0x800000
-#define FE_UPWARD 0x400000
#define FE_TOWARDZERO 0xc00000
#endif
+#define FE_DOWNWARD 0x800000
+#define FE_UPWARD 0x400000
typedef unsigned long fexcept_t;
diff --git a/arch/generic/bits/shm.h b/arch/generic/bits/shm.h
index 8d19378191ba..da07a2a0cb50 100644
--- a/arch/generic/bits/shm.h
+++ b/arch/generic/bits/shm.h
@@ -1,4 +1,4 @@
-#define SHMLBA 4096
+#define SHMLBA (4*4096)
struct shmid_ds {
struct ipc_perm shm_perm;
diff --git a/include/ctype.h b/include/ctype.h
index 7936536f577c..7b91d3ef6228 100644
--- a/include/ctype.h
+++ b/include/ctype.h
@@ -66,6 +66,11 @@ int toascii(int);
#define _toupper(a) ((a)&0x5f)
#define isascii(a) (0 ? isascii(a) : (unsigned)(a) < 128)
+#include <stdint.h>
+
+const int32_t **__ctype_tolower_loc(void);
+const int32_t **__ctype_toupper_loc(void);
+
#endif
#ifdef __cplusplus
diff --git a/include/dlfcn.h b/include/dlfcn.h
index 13ab71dd071e..e87392e70398 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -24,6 +24,21 @@ char *dlerror(void);
void *dlopen(const char *, int);
void *dlsym(void *__restrict, const char *__restrict);
+/* namespace apis */
+typedef const char* Dl_namespace;
+
+void dlns_init(Dl_namespace *, const char *);
+
+/* open dso in given namespace which has own lib search paths
+ * when namespace is null, it's same to dlopen()
+ * void to use "default" as namespace, which is the default namespace*/
+void *dlopen_ns(Dl_namespace *, const char *, int);
+
+/* create the namespace and set lib search paths of namespace,
+ * the paths should be splited by ':'. When namespace already exist,
+ * return error */
+int dlns_create(Dl_namespace *, const char *);
+
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
typedef struct {
const char *dli_fname;
diff --git a/include/pthread.h b/include/pthread.h
index 984db6806418..b430fbffb656 100644
--- a/include/pthread.h
+++ b/include/pthread.h
@@ -6,6 +6,17 @@ extern "C" {
#include <features.h>
+/* Musl did not provide the "owner" macro directly,
+ * so users can not access the mutex-ower-ID.
+ * Thus we added this macro for getting the owner-ID
+ * of the mutex. */
+
+/* These macros provides macros for accessing inner
+ * attributes of the pthread_mutex_t struct.
+ * It is intended for solving the coompiling failure
+ * of Dopra codes which claims that .__data.* realm
+ * can not be found in pthread_mutex_t. */
+
#define __NEED_time_t
#define __NEED_clockid_t
#define __NEED_struct_timespec
@@ -78,6 +89,7 @@ int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void
int pthread_detach(pthread_t);
_Noreturn void pthread_exit(void *);
int pthread_join(pthread_t, void **);
+pid_t pthread_gettid_np(pthread_t);
#ifdef __GNUC__
__attribute__((const))
diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h
index 6a3931e52010..9b095ffb500b 100644
--- a/include/sys/sysinfo.h
+++ b/include/sys/sysinfo.h
@@ -5,6 +5,7 @@
extern "C" {
#endif
+#ifndef _LINUX_KERNEL_H
#define SI_LOAD_SHIFT 16
struct sysinfo {
@@ -22,6 +23,7 @@ struct sysinfo {
unsigned mem_unit;
char __reserved[256];
};
+#endif
int sysinfo (struct sysinfo *);
int get_nprocs_conf (void);
diff --git a/include/unistd.h b/include/unistd.h
index 7bcbff943d4a..c9a87b1a14b6 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -190,6 +190,7 @@ int syncfs(int);
int euidaccess(const char *, int);
int eaccess(const char *, int);
ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
+pid_t gettid(void);
#endif
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
@@ -462,6 +463,19 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
#define _CS_V6_ENV 1148
#define _CS_V7_ENV 1149
+#ifdef _GNU_SOURCE
+#ifndef TEMP_FAILURE_RETRY
+#define MUSL_TEMP_FAILURE_RETRY(expression) \
+ (__extension__ \
+ ({ long int __result; \
+ do __result = (long int)(expression); \
+ while(__result == -1L&& errno == EINTR); \
+ __result;}))
+
+#define TEMP_FAILURE_RETRY(expression) MUSL_TEMP_FAILURE_RETRY(expression)
+#endif
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index afec985a3dbe..1219ee601a3e 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -32,6 +32,7 @@ static void error(const char *, ...);
#define container_of(p,t,m) ((t*)((char *)(p)-offsetof(t,m)))
#define countof(a) ((sizeof (a))/(sizeof (a)[0]))
+#define DSO_FLAGS_NODELETE 0x1
struct debug {
int ver;
@@ -56,6 +57,9 @@ struct dso {
size_t *dynv;
struct dso *next, *prev;
+ /* mark the dso status */
+ unsigned int flags;
+
Phdr *phdr;
int phnum;
size_t phentsize;
@@ -76,10 +80,12 @@ struct dso {
char mark;
char bfs_built;
char runtime_loaded;
+ char by_dlopen;
struct dso **deps, *needed_by;
size_t ndeps_direct;
size_t next_dep;
int ctor_visitor;
+ int nr_dlopen;
char *rpath_orig, *rpath;
struct tls_module tls;
size_t tls_id;
@@ -1021,6 +1027,8 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
ldso.prev = tail;
tail = &ldso;
}
+ /* increase libc dlopen refcnt */
+ a_inc(&ldso.nr_dlopen);
return &ldso;
}
if (strchr(name, '/')) {
@@ -1030,6 +1038,7 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
/* Search for the name to see if it's already loaded */
for (p=head->next; p; p=p->next) {
if (p->shortname && !strcmp(p->shortname, name)) {
+ a_inc(&p->nr_dlopen);
return p;
}
}
@@ -1046,11 +1055,13 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
if (!sys_path) {
char *prefix = 0;
size_t prefix_len;
+ char *filename = ldso.name;
if (ldso.name[0]=='/') {
char *s, *t, *z;
for (s=t=z=ldso.name; *s; s++)
if (*s=='/') z=t, t=s;
prefix_len = z-ldso.name;
+ filename = t+1;
if (prefix_len < PATH_MAX)
prefix = ldso.name;
}
@@ -1058,11 +1069,12 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
prefix = "";
prefix_len = 0;
}
+ size_t name_len = strchrnul(filename, '.') - filename;
char etc_ldso_path[prefix_len + 1
- + sizeof "/etc/ld-musl-" LDSO_ARCH ".path"];
+ + sizeof "/etc/.path" + name_len];
snprintf(etc_ldso_path, sizeof etc_ldso_path,
- "%.*s/etc/ld-musl-" LDSO_ARCH ".path",
- (int)prefix_len, prefix);
+ "%.*s/etc/%.*s.path",
+ (int)prefix_len, prefix, (int)name_len, filename);
FILE *f = fopen(etc_ldso_path, "rbe");
if (f) {
if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) {
@@ -1074,7 +1086,7 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
sys_path = "";
}
}
- if (!sys_path) sys_path = SYS_PATH_DFLT;
+ if (!sys_path) sys_path = strdup(SYS_PATH_DFLT);
fd = path_open(name, sys_path, buf, sizeof buf);
}
pathname = buf;
@@ -1092,6 +1104,8 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
if (!p->shortname && pathname != name)
p->shortname = strrchr(p->name, '/')+1;
close(fd);
+ /* increase dlopen refcnt */
+ a_inc(&p->nr_dlopen);
return p;
}
}
@@ -1137,6 +1151,7 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
p->ino = st.st_ino;
p->needed_by = needed_by;
p->name = p->buf;
+ p->nr_dlopen = 1;
p->runtime_loaded = runtime;
strcpy(p->name, pathname);
/* Add a shortname only if name arg was not an explicit pathname. */
@@ -1166,6 +1181,9 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
p->prev = tail;
tail = p;
+ if (runtime)
+ p->by_dlopen = 1;
+
if (DL_FDPIC) makefuncdescs(p);
if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);
@@ -2086,6 +2104,10 @@ void *dlopen(const char *file, int mode)
* relocations resolved to symbol definitions that get removed. */
redo_lazy_relocs();
+ if (mode & RTLD_NODELETE) {
+ p->flags |= DSO_FLAGS_NODELETE;
+ }
+
update_tls_size();
if (tls_cnt != orig_tls_cnt)
install_new_tls();
@@ -2169,6 +2191,102 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
return laddr(def.dso, def.sym->st_value);
}
+static int do_dlclose(struct dso *p)
+{
+ int old;
+ size_t n;
+ struct dso *d;
+
+ if (__dl_invalid_handle(p))
+ return -1;
+
+ if (!p->by_dlopen) {
+ error("Library %s is not loaded by dlopen", p->name);
+ return -1;
+ }
+
+ /* dso is marked as RTLD_NODELETE library, do nothing here. */
+ if ((p->flags & DSO_FLAGS_NODELETE) != 0) {
+ return 0;
+ }
+
+ old = a_fetch_add(&p->nr_dlopen, -1);
+ if (old > 1)
+ return 0;
+
+ /* call destructors if needed */
+ if (p->constructed) {
+ size_t dyn[DYN_CNT];
+ decode_vec(p->dynv, dyn, DYN_CNT);
+ if (dyn[0] & (1<<DT_FINI_ARRAY)) {
+ n = dyn[DT_FINI_ARRAYSZ] / sizeof(size_t);
+ size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY]) + n;
+ while (n--)
+ ((void (*)(void))*--fn)();
+ }
+ p->constructed = 0;
+ }
+
+ /* remove dso symbols from global list */
+ if (p->syms_next) {
+ for (d = head; d->syms_next != p; d = d->syms_next)
+ ; /* NOP */
+ d->syms_next = p->syms_next;
+ } else if (p == syms_tail) {
+ for (d = head; d->syms_next != p; d = d->syms_next)
+ ; /* NOP */
+ d->syms_next = NULL;
+ syms_tail = d;
+ }
+
+ /* remove dso from lazy list if needed */
+ if (p == lazy_head) {
+ lazy_head = p->lazy_next;
+ } else if (p->lazy_next) {
+ for (d = lazy_head; d->lazy_next != p; d = d->lazy_next)
+ ; /* NOP */
+ d->lazy_next = p->lazy_next;
+ }
+
+ /* remove dso from fini list */
+ if (p == fini_head) {
+ fini_head = p->fini_next;
+ } else if (p->fini_next) {
+ for (d = fini_head; d->fini_next != p; d = d->fini_next)
+ ; /* NOP */
+ d->fini_next = p->fini_next;
+ }
+
+ /* remove dso from global dso list */
+ if (p == tail) {
+ tail = p->prev;
+ tail->next = NULL;
+ } else {
+ p->next->prev = p->prev;
+ p->prev->next = p->next;
+ }
+
+ if (p->lazy != NULL)
+ free(p->lazy);
+ if (p->deps != no_deps)
+ free(p->deps);
+ unmap_library(p);
+ free(p);
+
+ return 0;
+}
+
+hidden int __dlclose(void *p)
+{
+ int rc;
+ pthread_rwlock_wrlock(&lock);
+ __inhibit_ptc();
+ rc = do_dlclose(p);
+ __release_ptc();
+ pthread_rwlock_unlock(&lock);
+ return rc;
+}
+
int dladdr(const void *addr_arg, Dl_info *info)
{
size_t addr = (size_t)addr_arg;
@@ -2312,3 +2430,46 @@ static void error(const char *fmt, ...)
__dl_vseterr(fmt, ap);
va_end(ap);
}
+void dlns_init(Dl_namespace *ns, const char *name)
+{
+ *ns = name;
+}
+
+void *dlopen_ns(Dl_namespace *ns, const char *file, int mode)
+{
+ if (!ns) return NULL;
+
+ return dlopen(file, mode);
+}
+
+int dlns_create(Dl_namespace *ns,const char *search_path)
+{
+ int sys_length = 0;
+ int search_length = 0;
+ char * new_path = NULL;
+
+ if (!search_path || !ns) return EINVAL;
+
+ sys_length = strlen(sys_path);
+ search_length = strlen(search_path);
+
+ if (search_path[0] != ':'){
+ sys_length += search_length + 1;
+ } else {
+ sys_length += search_length;
+ }
+
+ new_path = (char *)malloc(sys_length + 1);
+ if (!new_path) return ENOMEM;
+
+ strcpy(new_path, sys_path);
+ if (search_path[0] != ':') {
+ strcat(new_path, ":");
+ }
+ strcat(new_path, search_path);
+
+ free(sys_path);
+ sys_path = new_path;
+
+ return 0;
+}
diff --git a/src/hook/common_def.h b/src/hook/common_def.h
new file mode 100755
index 000000000000..7d74b3da0c27
--- /dev/null
+++ b/src/hook/common_def.h
@@ -0,0 +1,10 @@
+#ifndef _COMMON_DEF_H
+#define _COMMON_DEF_H
+
+#include <unistd.h>
+#include <stdlib.h>
+
+#define __predict_true(exp) __builtin_expect((exp) != 0, 1)
+#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
+
+#endif
\ No newline at end of file
diff --git a/src/hook/malloc_common.c b/src/hook/malloc_common.c
new file mode 100755
index 000000000000..50abc4d5e5d5
--- /dev/null
+++ b/src/hook/malloc_common.c
@@ -0,0 +1,33 @@
+#ifdef HOOK_ENABLE
+#include <unistd.h>
+#include <sys/types.h>
+#include "musl_malloc.h"
+#include <malloc.h>
+#include "musl_malloc_dispatch_table.h"
+#include "common_def.h"
+#include "musl_preinit_common.h"
+
+void* malloc(size_t bytes)
+{
+ volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
+ if (__predict_false(dispatch_table != NULL)) {
+ void*ret = dispatch_table->malloc(bytes);
+ return ret;
+ }
+ void* result = MuslMalloc(malloc)(bytes);
+ if (__predict_false(result == NULL)) {
+ //__musl_log(__MUSL_LOG_WARN, "malloc(%zu) failed: returning null pointer\n", bytes);
+ }
+ return result;
+}
+
+void free(void* mem)
+{
+ volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
+ if (__predict_false(dispatch_table != NULL)) {
+ dispatch_table->free(mem);
+ } else {
+ MuslMalloc(free)(mem);
+ }
+}
+#endif
diff --git a/src/hook/musl_malloc.h b/src/hook/musl_malloc.h
new file mode 100755
index 000000000000..27f30869d0d8
--- /dev/null
+++ b/src/hook/musl_malloc.h
@@ -0,0 +1,26 @@
+#ifndef _MUSL_MALLOC_H
+#define _MUSL_MALLOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HOOK_ENABLE
+#define MuslMalloc(func) __libc_ ## func
+#else
+#define MuslMalloc(func) func
+#endif
+
+void *__libc_malloc(size_t);
+void *__libc_calloc(size_t, size_t);
+void *__libc_realloc(void *, size_t);
+void __libc_free(void *);
+void *__libc_valloc(size_t);
+void *__libc_memalign(size_t, size_t);
+size_t __libc_malloc_usable_size(void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/hook/musl_malloc_dispatch.h b/src/hook/musl_malloc_dispatch.h
new file mode 100755
index 000000000000..15b859eea083
--- /dev/null
+++ b/src/hook/musl_malloc_dispatch.h
@@ -0,0 +1,37 @@
+#ifndef _MUSL_MALLOC_DISPATCH_H
+#define _MUSL_MALLOC_DISPATCH_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef void* (*MallocMallocType)(size_t);
+typedef void* (*MallocReallocType)(void*, size_t);
+typedef void* (*MallocCallocType)(size_t, size_t);
+typedef void* (*MallocVallocType)(size_t);
+typedef void (*MallocFreeType)(void*);
+typedef void* (*MallocMemalignType)(size_t, size_t);
+typedef size_t (*MallocMallocUsableSizeType)(void*);
+typedef bool (*GetHookFlagType)();
+typedef bool (*SetHookFlagType)(bool);
+
+struct MallocDispatchType {
+ MallocMallocType malloc;
+ MallocCallocType calloc;
+ MallocReallocType realloc;
+ MallocVallocType valloc;
+ MallocFreeType free;
+ MallocMemalignType memalign;
+ MallocMallocUsableSizeType malloc_usable_size;
+ GetHookFlagType get_hook_flag;
+ SetHookFlagType set_hook_flag;
+};
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/hook/musl_malloc_dispatch_table.h b/src/hook/musl_malloc_dispatch_table.h
new file mode 100755
index 000000000000..430de744bb50
--- /dev/null
+++ b/src/hook/musl_malloc_dispatch_table.h
@@ -0,0 +1,13 @@
+#ifndef _MUSL_MALLOC_DISPATCH_TABLE_H
+#define _MUSL_MALLOC_DISPATCH_TABLE_H
+
+#include "musl_malloc_dispatch.h"
+#include <stdatomic.h>
+
+struct musl_libc_globals {
+ volatile atomic_llong current_dispatch_table;
+ volatile atomic_llong so_dispatch_table;
+ struct MallocDispatchType malloc_dispatch_table;
+};
+
+#endif
diff --git a/src/hook/musl_preinit.c b/src/hook/musl_preinit.c
new file mode 100755
index 000000000000..57a0bf12fb84
--- /dev/null
+++ b/src/hook/musl_preinit.c
@@ -0,0 +1,400 @@
+/*
+The hook mode has 3 kinds which can be set by command "param set":
+(1) param set libc.hook_mode "startup:\"prog1 \""
+(2) param set libc.hook_mode startup:program1
+(3) param set libc.hook_mode step
+(4) param set libc.hook_mode direct
+
+Case 1 represents "startup" mode, and the hooked process is "prog1 ",
+which loads hooking shared library when the program starts up.
+The path is added with two quotation marks because a quotation mark is a special charcter,
+which need be escaped.
+(2) is similar with (1), but no escaped character, so quotation marks doesn't need.
+(3) represents "step" mode, which loads hooking shared library by some steps.
+(4) represetnt "direct" mode, which loads hooking shared library by a step.
+*/
+
+#ifdef HOOK_ENABLE
+#include <unistd.h>
+#include <signal.h>
+#include "musl_malloc_dispatch_table.h"
+#include "musl_malloc.h"
+#include "musl_preinit_common.h"
+#include <pthread.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <dlfcn.h>
+#include <stdatomic.h>
+#include <ctype.h>
+#include <assert.h>
+#include <string.h>
+#include <malloc.h>
+
+void* ohos_malloc_hook_init_function(size_t bytes);
+
+static struct MallocDispatchType __ohos_malloc_hook_init_dispatch = {
+ .malloc = ohos_malloc_hook_init_function,
+ .free = MuslMalloc(free),
+};
+#define MAX_SYM_NAME_SIZE 1000
+static char *__malloc_hook_shared_lib = "libnative_hook.z.so";
+static char *__malloc_hook_function_prefix = "ohos_malloc_hook";
+static char *__get_param_shared_Lib = "libparam_client.z.so";
+volatile atomic_llong ohos_malloc_hook_shared_liibrary;
+void* function_of_shared_lib[LAST_FUNCTION];
+static enum EnumHookMode __hook_mode = STEP_HOOK_MODE;
+static char __hook_process_path[PATH_MAX+ 1] = {0};
+static char __progname[PATH_MAX + 1] = {0};
+
+
+static char* get_native_hook_param()
+{
+ int (*getFunction)(const char *name, char *value, unsigned int *len);
+
+ void* shared_library_handle = dlopen(__get_param_shared_Lib, RTLD_NOW | RTLD_LOCAL);
+ if (!shared_library_handle) {
+ return NULL;
+ }
+
+ getFunction = (int (*)(const char *name, char *value, unsigned int *len))dlsym((void*)shared_library_handle, "SystemGetParameter");
+ if (getFunction == NULL) {
+ dlclose(shared_library_handle);
+ return NULL;
+ }
+ const char *key = MUSL_HOOK_PARAM_NAME;
+ char *value = (char *)malloc(OHOS_PARAM_MAX_SIZE);
+ memset(value, 0, OHOS_PARAM_MAX_SIZE);
+ if (value == NULL) {
+ dlclose(shared_library_handle);
+ return NULL;
+ }
+ unsigned int len = OHOS_PARAM_MAX_SIZE;
+ getFunction(key, value, &len);
+ dlclose(shared_library_handle);
+ return value;
+}
+
+static int parse_hook_variable(enum EnumHookMode* mode, char* path, int size)
+{
+ if (!mode || !path || size <= 0) {
+ return -1;
+ }
+
+ bool flag = __set_hook_flag(false);
+ char* hook_param_value = get_native_hook_param();
+ if (!hook_param_value) {
+ *mode = STEP_HOOK_MODE;
+ path[0] = '\0';
+ } else {
+ char* ptr = hook_param_value;
+ char* mode_str = hook_param_value;
+
+ while (*ptr && *ptr != ':') {
+ ++ptr;
+ }
+
+ if (*ptr == ':') {
+ *ptr = '\0';
+ ++ptr;
+ }
+
+ if (strcmp(mode_str, "startup") == 0) {
+ *mode = STATRUP_HOOK_MODE;
+ } else if (strcmp(mode_str, "direct") == 0) {
+ *mode = DIRECT_HOOK_MODE;
+ } else if (strcmp(mode_str, "step") == 0) {
+ *mode = STEP_HOOK_MODE;
+ } else {
+ *mode = STEP_HOOK_MODE;
+ }
+ if (*mode == STATRUP_HOOK_MODE) {
+ if (*ptr == '\"') {
+ ++ptr;
+ int idx = 0;
+ while (idx < size - 1 && *ptr && *ptr != '\"') {
+ path[idx++] = *ptr++;
+ }
+ path[idx] = '\0';
+ } else {
+ int idx = 0;
+ while (idx < size - 1 && *ptr) {
+ path[idx++] = *ptr++;
+ }
+ path[idx] = '\0';
+ }
+ }
+
+ free(hook_param_value);
+ }
+ __set_hook_flag(flag);
+ return 0;
+}
+
+static bool init_malloc_function(void* malloc_shared_library_handler, MallocMallocType* func, const char* prefix)
+{
+ char symbol[MAX_SYM_NAME_SIZE];
+ snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "malloc");
+ *func = (MallocMallocType)(dlsym(malloc_shared_library_handler, symbol));
+ if (*func == NULL) {
+ return false;
+ }
+ return true;
+}
+
+static bool init_free_function(void* malloc_shared_library_handler, MallocFreeType* func, const char* prefix)
+{
+ char symbol[MAX_SYM_NAME_SIZE];
+ snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "free");
+ *func = (MallocFreeType)(dlsym(malloc_shared_library_handler, symbol));
+ if (*func == NULL) {
+ return false;
+ }
+ return true;
+}
+
+static bool init_hook_functions(void* shared_library_handler, struct MallocDispatchType* table, const char* prefix)
+{
+ if (!init_malloc_function(shared_library_handler, &table->malloc, prefix)) {
+ return false;
+ }
+ if (!init_free_function(shared_library_handler, &table->free, prefix)) {
+ return false;
+ }
+ return true;
+}
+
+static void clear_function_table()
+{
+ for (size_t i = 0; i < LAST_FUNCTION; i++) {
+ function_of_shared_lib[i] = NULL;
+ }
+}
+
+bool init_malloc_hook_shared_library(void* shared_library_handle, const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table)
+{
+ static const char* names[] = {
+ "initialize",
+ "finalize",
+ "get_hook_flag",
+ "set_hook_flag",
+ "on_start",
+ "on_end",
+ };
+
+ for (int i = 0; i < LAST_FUNCTION; i++) {
+ char symbol[MAX_SYM_NAME_SIZE];
+ snprintf(symbol, sizeof(symbol), "%s_%s", prefix, names[i]);
+ function_of_shared_lib[i] = dlsym(shared_library_handle, symbol);
+ if (function_of_shared_lib[i] == NULL) {
+ // __musl_log(__MUSL_LOG_ERROR, "%s: %s routine not found in %s\n", getprogname(), symbol, shared_lib);
+ clear_function_table();
+ return false;
+ }
+ }
+
+ if (!init_hook_functions(shared_library_handle, dispatch_table, prefix)) {
+ clear_function_table();
+ return false;
+ }
+
+ return true;
+}
+
+void* load_malloc_hook_shared_library(const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table)
+{
+ void* shared_library_handle = NULL;
+
+ shared_library_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL);
+
+ if (shared_library_handle == NULL) {
+ printf("Unable to open shared library %s: %s\n", shared_lib, dlerror());
+ return NULL;
+ }
+
+ if (!init_malloc_hook_shared_library(shared_library_handle, shared_lib, prefix, dispatch_table)) {
+ dlclose(shared_library_handle);
+ shared_library_handle = NULL;
+ }
+ // printf("load_malloc_hook_shared_library success new version test\n");
+ return shared_library_handle;
+}
+
+typedef void (*finalize_func_t)();
+typedef bool (*init_func_t)(const struct MallocDispatchType*, bool*, const char*);
+typedef bool (*on_start_func_t)();
+typedef bool (*on_end_func_t)();
+
+static void malloc_finalize()
+{
+ __set_hook_flag(false);
+ ((finalize_func_t)function_of_shared_lib[FINALIZE_FUNCTION])();
+
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+}
+
+bool finish_install_ohos_malloc_hooks(struct musl_libc_globals* globals, const char* options, const char* prefix)
+{
+ init_func_t init_func = (init_func_t)(function_of_shared_lib[INITIALIZE_FUNCTION]);
+ if (!init_func(&__libc_malloc_default_dispatch, NULL, options)) {
+ // __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc %s\n", getprogname(), prefix);
+ clear_function_table();
+ return false;
+ }
+ on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
+ if (!start_func()) {
+ // __musl_log(__MUSL_LOG_ERROR, "%s: failed to start %s\n", getprogname(), prefix);
+ clear_function_table();
+ return false;
+ }
+ atomic_store_explicit(&__musl_libc_globals.so_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst);
+ atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst);
+
+ int ret_value = atexit(malloc_finalize);
+ if (ret_value != 0) {
+ // __musl_log(__MUSL_LOG_ERROR, "failed to set atexit cleanup function: %d\n", ret_value);
+ }
+ return true;
+}
+
+static bool is_empty_string(const char* str)
+{
+ while (*str) {
+ if (!isspace((unsigned char)(*str))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void install_ohos_malloc_hook(struct musl_libc_globals* globals)
+{
+ volatile void* shared_library_handle = (volatile void *)atomic_load_explicit(&ohos_malloc_hook_shared_liibrary, memory_order_acquire);
+ assert(shared_library_handle == NULL || shared_library_handle == (volatile void*)-1);
+ shared_library_handle = (volatile void*)load_malloc_hook_shared_library(__malloc_hook_shared_lib, __malloc_hook_function_prefix, &globals->malloc_dispatch_table);
+ if (shared_library_handle == NULL) {
+ // __musl_log(__MUSL_LOG_ERROR, "Can't load shared library '%s'\n", __malloc_hook_shared_lib);
+ return;
+ }
+
+ if (finish_install_ohos_malloc_hooks(globals, NULL, __malloc_hook_function_prefix)) {
+ atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)shared_library_handle, memory_order_seq_cst);
+ } else {
+ // __musl_log(__MUSL_LOG_ERROR, "finish_install_ohos_malloc_hooks failed\n");
+ dlclose((void *)shared_library_handle);
+ atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)0, memory_order_seq_cst);
+ }
+}
+
+static void* init_ohos_malloc_hook()
+{
+ bool flag = __set_hook_flag(false);
+ install_ohos_malloc_hook(&__musl_libc_globals);
+ __set_hook_flag(flag);
+ return NULL;
+}
+
+void* ohos_malloc_hook_init_function(size_t bytes)
+{
+ if (atomic_exchange(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL)) {
+ pthread_t thread_id;
+ if (pthread_create(&thread_id, NULL, init_ohos_malloc_hook, NULL) != 0) {
+ // __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_create\n", getprogname());
+ } else if (pthread_detach(thread_id) != 0) {
+ // __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_detach\n", getprogname());
+ }
+ }
+ void*ptr = MuslMalloc(malloc)(bytes);
+ return ptr;
+
+}
+
+static void __set_default_malloc()
+{
+ atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL, memory_order_seq_cst);
+}
+
+static void __install_malloc_hook()
+{
+ atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
+
+ volatile void* shared_library_handle = (volatile void* )atomic_load_explicit(&ohos_malloc_hook_shared_liibrary, memory_order_acquire);
+ if (shared_library_handle == NULL) {
+ if (__hook_mode == STEP_HOOK_MODE) {
+ atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)&__ohos_malloc_hook_init_dispatch, memory_order_seq_cst);
+ atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)-1, memory_order_seq_cst);
+ } else {
+ init_ohos_malloc_hook();
+ }
+ } else if (shared_library_handle != (void*)-1) {
+ bool flag = __set_hook_flag(false);
+ on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
+ if (start_func && !start_func()) {
+ // __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc\n", getprogname());
+ }
+ __set_hook_flag(flag);
+ volatile const struct MallocDispatchType* so_dispatch_value = (volatile const struct MallocDispatchType* )atomic_load_explicit(&__musl_libc_globals.so_dispatch_table, memory_order_acquire);
+ atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)so_dispatch_value, memory_order_seq_cst);
+ }
+}
+
+static void __uninstal_malloc_hook()
+{
+ atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
+
+ bool flag = __set_hook_flag(false);
+ __set_default_malloc();
+ on_end_func_t end_func = (on_end_func_t)(function_of_shared_lib[ON_END_FUNCTION]);
+ if (end_func) {
+ end_func();
+ }
+ __set_hook_flag(flag);
+}
+
+static void __install_malloc_hook_signal_handler()
+{
+ struct sigaction actionInstallHook = {};
+ actionInstallHook.sa_handler = __install_malloc_hook;
+ sigemptyset(&actionInstallHook.sa_mask);
+ sigaddset(&actionInstallHook.sa_mask, SIGUNHOOK);
+ sigaction(SIGHOOK, &actionInstallHook, NULL);
+
+ struct sigaction actionDef = {};
+ actionDef.sa_handler = __uninstal_malloc_hook;
+ sigemptyset(&actionDef.sa_mask);
+ sigaddset(&actionDef.sa_mask, SIGHOOK);
+ sigaction(SIGUNHOOK, &actionDef, NULL);
+}
+
+static void __initialize_malloc()
+{
+ __install_malloc_hook_signal_handler();
+}
+
+
+__attribute__((constructor(1))) static void __musl_initialize()
+{
+ atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
+ __set_default_malloc();
+ //__init_musl_log();
+ parse_hook_variable(&__hook_mode, __hook_process_path, sizeof(__hook_process_path));
+ if (__hook_mode == STATRUP_HOOK_MODE) {
+ readlink("/proc/self/exe", __progname, sizeof(__progname) - 1);
+ const char *pos = strrchr(__progname, '/');
+ const char* filename;
+ if (pos) {
+ filename = pos + 1;
+ } else {
+ filename = __progname;
+ }
+ if (strcmp(filename, __hook_process_path) == 0) {
+ atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
+ init_ohos_malloc_hook();
+ } else {
+ __hook_mode = STEP_HOOK_MODE;
+ }
+ }
+ __initialize_malloc();
+}
+#endif
diff --git a/src/hook/musl_preinit_common.c b/src/hook/musl_preinit_common.c
new file mode 100755
index 000000000000..7db57bc0223d
--- /dev/null
+++ b/src/hook/musl_preinit_common.c
@@ -0,0 +1,17 @@
+#ifdef HOOK_ENABLE
+#include "musl_preinit_common.h"
+#include "musl_malloc.h"
+#include <stdatomic.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+struct musl_libc_globals __musl_libc_globals;
+
+struct MallocDispatchType __libc_malloc_default_dispatch = {
+ .malloc = MuslMalloc(malloc),
+ .free = MuslMalloc(free),
+};
+
+volatile atomic_bool __hook_enable_hook_flag;
+
+#endif
diff --git a/src/hook/musl_preinit_common.h b/src/hook/musl_preinit_common.h
new file mode 100755
index 000000000000..b3920f58bd94
--- /dev/null
+++ b/src/hook/musl_preinit_common.h
@@ -0,0 +1,99 @@
+#ifndef _MUSL_PREINIT_COMMON_H
+#define _MUSL_PREINIT_COMMON_H
+
+#include <stdatomic.h>
+#include "musl_malloc_dispatch_table.h"
+#include "musl_malloc_dispatch.h"
+
+extern struct musl_libc_globals __musl_libc_globals;
+
+extern struct MallocDispatchType __libc_malloc_default_dispatch;
+
+extern volatile atomic_bool __hook_enable_hook_flag;
+
+enum EnumFunc {
+ INITIALIZE_FUNCTION,
+ FINALIZE_FUNCTION,
+ GET_HOOK_FLAG_FUNCTION,
+ SET_HOOK_FLAG_FUNCTION,
+ ON_START_FUNCTION,
+ ON_END_FUNCTION,
+ LAST_FUNCTION,
+};
+
+enum EnumHookMode {
+ STATRUP_HOOK_MODE,
+ DIRECT_HOOK_MODE,
+ STEP_HOOK_MODE,
+};
+
+extern void* function_of_shared_lib[];
+extern volatile atomic_llong ohos_malloc_hook_shared_liibrary;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__attribute__((always_inline))
+inline bool __get_global_hook_flag()
+{
+ volatile bool g_flag = atomic_load_explicit(&__hook_enable_hook_flag, memory_order_acquire);
+ return g_flag;
+}
+
+__attribute__((always_inline))
+inline bool __get_hook_flag()
+{
+ volatile void* impl_handle = (void *)atomic_load_explicit(&ohos_malloc_hook_shared_liibrary, memory_order_acquire);
+ if (impl_handle == NULL) {
+ return false;
+ }
+ else if (impl_handle == (void *)-1) {
+ return true;
+ }
+ else {
+ GetHookFlagType get_hook_func_ptr = (GetHookFlagType)(function_of_shared_lib[GET_HOOK_FLAG_FUNCTION]);
+ bool flag = get_hook_func_ptr();
+ return flag;
+ }
+}
+
+__attribute__((always_inline))
+inline bool __set_hook_flag(bool flag)
+{
+ volatile void* impl_handle = (void *)atomic_load_explicit(&ohos_malloc_hook_shared_liibrary, memory_order_acquire);
+ if (impl_handle == NULL) {
+ return false;
+ }
+ else if (impl_handle == (void *)-1) {
+ return true;
+ }
+ else {
+ SetHookFlagType set_hook_func_ptr = (SetHookFlagType)(function_of_shared_lib[SET_HOOK_FLAG_FUNCTION]);
+ return set_hook_func_ptr(flag);
+ }
+}
+
+__attribute__((always_inline))
+inline volatile const struct MallocDispatchType* get_current_dispatch_table()
+{
+ volatile const struct MallocDispatchType* ret = (struct MallocDispatchType *)atomic_load_explicit(&__musl_libc_globals.current_dispatch_table, memory_order_acquire);
+ if (ret != NULL) {
+ if (!__get_global_hook_flag()) {
+ ret = NULL;
+ }
+ else if (!__get_hook_flag()) {
+ ret = NULL;
+ }
+ }
+ return ret;
+}
+
+#define MUSL_HOOK_PARAM_NAME "libc.hook_mode"
+#define OHOS_PARAM_MAX_SIZE 96
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h
index 764e3a1a8fa9..6b9492753595 100644
--- a/src/internal/dynlink.h
+++ b/src/internal/dynlink.h
@@ -98,6 +98,7 @@ struct fdpic_dummy_loadmap {
typedef void (*stage2_func)(unsigned char *, size_t *);
hidden void *__dlsym(void *restrict, const char *restrict, void *restrict);
+hidden int __dlclose(void *p);
hidden void __dl_seterr(const char *, ...);
hidden int __dl_invalid_handle(void *);
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
index 5742dfc55cb9..816cfa7dbe99 100644
--- a/src/internal/pthread_impl.h
+++ b/src/internal/pthread_impl.h
@@ -75,12 +75,22 @@ struct __timer {
#define _a_sched __u.__i[3*__SU+1]
#define _a_policy __u.__i[3*__SU+2]
#define _a_prio __u.__i[3*__SU+3]
+
+/* we define the original value of _m_* in include/pthread.h
+ * as macros MUTEX_* to make the user be able to
+ * access the inner attribute of the mutex struct.
+ * Then, we modify the value of _m_* macros to MUTEX_* here,
+ * so that we can immediately be aware of the changes that
+ * the open source society has made to these original macros,
+ * because patching will fail if the value of the _m_* are
+ * changed by musl society */
#define _m_type __u.__i[0]
#define _m_lock __u.__vi[1]
#define _m_waiters __u.__vi[2]
#define _m_prev __u.__p[3]
#define _m_next __u.__p[4]
#define _m_count __u.__i[5]
+
#define _c_shared __u.__p[0]
#define _c_seq __u.__vi[2]
#define _c_waiters __u.__vi[3]
@@ -173,6 +183,7 @@ hidden void __inhibit_ptc(void);
hidden void __tl_lock(void);
hidden void __tl_unlock(void);
hidden void __tl_sync(pthread_t);
+hidden struct pthread* __pthread_list_find(pthread_t, const char*);
extern hidden volatile int __thread_list_lock;
diff --git a/src/internal/syscall.h b/src/internal/syscall.h
index 975a0031d4fb..fb64c282263d 100644
--- a/src/internal/syscall.h
+++ b/src/internal/syscall.h
@@ -278,10 +278,6 @@ hidden long __syscall_ret(unsigned long),
#define SYS_utimensat SYS_utimensat_time64
#endif
-#ifndef SYS_pselect6
-#define SYS_pselect6 SYS_pselect6_time64
-#endif
-
#ifndef SYS_ppoll
#define SYS_ppoll SYS_ppoll_time64
#endif
diff --git a/src/ldso/dlclose.c b/src/ldso/dlclose.c
index e437422a675a..566c8c3b61aa 100644
--- a/src/ldso/dlclose.c
+++ b/src/ldso/dlclose.c
@@ -1,7 +1,14 @@
#include <dlfcn.h>
#include "dynlink.h"
-int dlclose(void *p)
+static int dummy(void *p)
{
return __dl_invalid_handle(p);
}
+weak_alias(dummy, __dlclose);
+
+int dlclose(void *p)
+{
+ return __dlclose(p);
+}
+
diff --git a/src/legacy/ulimit.c b/src/legacy/ulimit.c
index 1f59e8e619f5..d1620e6e2812 100644
--- a/src/legacy/ulimit.c
+++ b/src/legacy/ulimit.c
@@ -1,6 +1,7 @@
#include <sys/resource.h>
#include <ulimit.h>
#include <stdarg.h>
+#include <limits.h>
long ulimit(int cmd, ...)
{
@@ -15,5 +16,5 @@ long ulimit(int cmd, ...)
rl.rlim_cur = 512ULL * val;
if (setrlimit(RLIMIT_FSIZE, &rl)) return -1;
}
- return rl.rlim_cur / 512;
+ return rl.rlim_cur == RLIM_INFINITY? LONG_MAX : rl.rlim_cur / 512;
}
diff --git a/src/linux/gettid.c b/src/linux/gettid.c
new file mode 100644
index 000000000000..70767137e92f
--- /dev/null
+++ b/src/linux/gettid.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "pthread_impl.h"
+
+pid_t gettid(void)
+{
+ return __pthread_self()->tid;
+}
diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c
index 51fa4a3ac399..45a1a936bac5 100644
--- a/src/malloc/malloc.c
+++ b/src/malloc/malloc.c
@@ -9,11 +9,17 @@
#include "atomic.h"
#include "pthread_impl.h"
#include "malloc_impl.h"
+#include <sys/prctl.h>
#if defined(__GNUC__) && defined(__PIC__)
#define inline inline __attribute__((always_inline))
#endif
+#ifdef HOOK_ENABLE
+void *__libc_malloc(size_t);
+void __libc_free(void *p);
+#endif
+
static struct {
volatile uint64_t binmap;
struct bin bins[64];
@@ -281,7 +287,11 @@ static void trim(struct chunk *self, size_t n)
__bin_chunk(split);
}
+#ifdef HOOK_ENABLE
+void *__libc_malloc(size_t n)
+#else
void *malloc(size_t n)
+#endif
{
struct chunk *c;
int i, j;
@@ -376,6 +386,10 @@ void *realloc(void *p, size_t n)
void *new;
if (!p) return malloc(n);
+ if (!n) {
+ free(p);
+ return NULL;
+ }
if (adjust_size(&n) < 0) return 0;
@@ -519,7 +533,11 @@ static void unmap_chunk(struct chunk *self)
__munmap(base, len);
}
+#ifdef HOOK_ENABLE
+void __libc_free(void *p)
+#else
void free(void *p)
+#endif
{
if (!p) return;
diff --git a/src/multibyte/wcsnrtombs.c b/src/multibyte/wcsnrtombs.c
index 676932b5dcaa..95e25e708dd9 100644
--- a/src/multibyte/wcsnrtombs.c
+++ b/src/multibyte/wcsnrtombs.c
@@ -1,41 +1,33 @@
#include <wchar.h>
+#include <limits.h>
+#include <string.h>
size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
{
- size_t l, cnt=0, n2;
- char *s, buf[256];
const wchar_t *ws = *wcs;
- const wchar_t *tmp_ws;
-
- if (!dst) s = buf, n = sizeof buf;
- else s = dst;
-
- while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
- if (n2>=n) n2=n;
- tmp_ws = ws;
- l = wcsrtombs(s, &ws, n2, 0);
- if (!(l+1)) {
- cnt = l;
- n = 0;
+ size_t cnt = 0;
+ if (!dst) n=0;
+ while (ws && wn) {
+ char tmp[MB_LEN_MAX];
+ size_t l = wcrtomb(n<MB_LEN_MAX ? tmp : dst, *ws, 0);
+ if (l==-1) {
+ cnt = -1;
break;
}
- if (s != buf) {
- s += l;
+ if (dst) {
+ if (n<MB_LEN_MAX) {
+ if (l>n) break;
+ memcpy(dst, tmp, l);
+ }
+ dst += l;
n -= l;
}
- wn = ws ? wn - (ws - tmp_ws) : 0;
- cnt += l;
- }
- if (ws) while (n && wn) {
- l = wcrtomb(s, *ws, 0);
- if ((l+1)<=1) {
- if (!l) ws = 0;
- else cnt = l;
+ if (!*ws) {
+ ws = 0;
break;
}
- ws++; wn--;
- /* safe - this loop runs fewer than sizeof(buf) times */
- s+=l; n-=l;
+ ws++;
+ wn--;
cnt += l;
}
if (dst) *wcs = ws;
diff --git a/src/network/inet_legacy.c b/src/network/inet_legacy.c
index 621b47b05086..6d91b6e179f6 100644
--- a/src/network/inet_legacy.c
+++ b/src/network/inet_legacy.c
@@ -12,12 +12,12 @@ struct in_addr inet_makeaddr(in_addr_t n, in_addr_t h)
if (n < 256) h |= n<<24;
else if (n < 65536) h |= n<<16;
else h |= n<<8;
- return (struct in_addr){ h };
+ return (struct in_addr){ htonl(h) };
}
in_addr_t inet_lnaof(struct in_addr in)
{
- uint32_t h = in.s_addr;
+ uint32_t h = ntohl(in.s_addr);
if (h>>24 < 128) return h & 0xffffff;
if (h>>24 < 192) return h & 0xffff;
return h & 0xff;
@@ -25,7 +25,7 @@ in_addr_t inet_lnaof(struct in_addr in)
in_addr_t inet_netof(struct in_addr in)
{
- uint32_t h = in.s_addr;
+ uint32_t h = ntohl(in.s_addr);
if (h>>24 < 128) return h >> 24;
if (h>>24 < 192) return h >> 16;
return h >> 8;
diff --git a/src/passwd/getspnam_r.c b/src/passwd/getspnam_r.c
index 541e85314d56..e738d656cfb7 100644
--- a/src/passwd/getspnam_r.c
+++ b/src/passwd/getspnam_r.c
@@ -15,8 +15,15 @@
static long xatol(char **s)
{
long x;
+ int sign;
if (**s == ':' || **s == '\n') return -1;
+
+ sign = (int)(unsigned char)**s;
+ if (sign == '-' || sign == '+') ++*s;
+
for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
+
+ if (sign == '-') return -x;
return x;
}
diff --git a/src/sched/sched_getparam.c b/src/sched/sched_getparam.c
index 76f10e49d987..b31f00892ef2 100644
--- a/src/sched/sched_getparam.c
+++ b/src/sched/sched_getparam.c
@@ -1,8 +1,20 @@
-#include <sched.h>
-#include <errno.h>
-#include "syscall.h"
-
-int sched_getparam(pid_t pid, struct sched_param *param)
-{
- return __syscall_ret(-ENOSYS);
-}
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+#include <string.h>
+
+int sched_getparam(pid_t pid, struct sched_param *param)
+{
+ int r;
+ if (!param) {
+ r = -EINVAL;
+ goto exit;
+ }
+ memset(param, 0, sizeof(struct sched_param));
+ r = __syscall(SYS_sched_getparam, pid , param);
+ if (r >= 0) {
+ r = 0;
+ }
+exit:
+ return __syscall_ret(r);
+}
diff --git a/src/sched/sched_getscheduler.c b/src/sched/sched_getscheduler.c
index 394e508b467c..454ac8bcec16 100644
--- a/src/sched/sched_getscheduler.c
+++ b/src/sched/sched_getscheduler.c
@@ -1,8 +1,9 @@
-#include <sched.h>
-#include <errno.h>
-#include "syscall.h"
-
-int sched_getscheduler(pid_t pid)
-{
- return __syscall_ret(-ENOSYS);
-}
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_getscheduler(pid_t pid)
+{
+ int r = __syscall(SYS_sched_getscheduler, pid);
+ return __syscall_ret(r);
+}
\ No newline at end of file
diff --git a/src/sched/sched_setparam.c b/src/sched/sched_setparam.c
index 18623ee49b15..2e0f79bff69d 100644
--- a/src/sched/sched_setparam.c
+++ b/src/sched/sched_setparam.c
@@ -1,8 +1,15 @@
-#include <sched.h>
-#include <errno.h>
-#include "syscall.h"
-
-int sched_setparam(pid_t pid, const struct sched_param *param)
-{
- return __syscall_ret(-ENOSYS);
-}
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_setparam(pid_t pid, const struct sched_param *param)
+{
+ int r;
+ if (!param) {
+ r = -EINVAL;
+ goto exit;
+ }
+ r = __syscall(SYS_sched_setparam, pid, param);
+exit:
+ return __syscall_ret(r);
+}
\ No newline at end of file
diff --git a/src/sched/sched_setscheduler.c b/src/sched/sched_setscheduler.c
index 4435f2164671..fcb5873f59b1 100644
--- a/src/sched/sched_setscheduler.c
+++ b/src/sched/sched_setscheduler.c
@@ -4,5 +4,12 @@
int sched_setscheduler(pid_t pid, int sched, const struct sched_param *param)
{
- return __syscall_ret(-ENOSYS);
-}
+ int r;
+ if (!param) {
+ r = -EINVAL;
+ goto exit;
+ }
+ r = __syscall(SYS_sched_setscheduler, pid , sched , param);
+exit:
+ return __syscall_ret(r);
+}
\ No newline at end of file
diff --git a/src/thread/arm/clone.s b/src/thread/arm/clone.s
index bb0965dafe82..2070dd51bd27 100644
--- a/src/thread/arm/clone.s
+++ b/src/thread/arm/clone.s
@@ -3,8 +3,14 @@
.global __clone
.hidden __clone
.type __clone,%function
+.cfi_startproc
__clone:
stmfd sp!,{r4,r5,r6,r7}
+ .cfi_def_cfa_offset 16
+ .cfi_rel_offset r4, 0
+ .cfi_rel_offset r5, 4
+ .cfi_rel_offset r6, 8
+ .cfi_rel_offset r7, 12
mov r7,#120
mov r6,r3
mov r5,r0
@@ -17,6 +23,7 @@ __clone:
tst r0,r0
beq 1f
ldmfd sp!,{r4,r5,r6,r7}
+ .cfi_def_cfa_offset 0
bx lr
1: mov r0,r6
@@ -26,3 +33,4 @@ __clone:
b 2b
3: bx r5
+.cfi_endproc
\ No newline at end of file
diff --git a/src/thread/arm/syscall_cp.s b/src/thread/arm/syscall_cp.s
index e607dd426afc..03a83dc952b9 100644
--- a/src/thread/arm/syscall_cp.s
+++ b/src/thread/arm/syscall_cp.s
@@ -7,11 +7,16 @@
.hidden __cp_cancel
.hidden __cancel
.global __syscall_cp_asm
-.hidden __syscall_cp_asm
.type __syscall_cp_asm,%function
+.cfi_startproc
__syscall_cp_asm:
mov ip,sp
stmfd sp!,{r4,r5,r6,r7}
+ .cfi_def_cfa_offset 16
+ .cfi_rel_offset r4, 0
+ .cfi_rel_offset r5, 4
+ .cfi_rel_offset r6, 8
+ .cfi_rel_offset r7, 12
__cp_begin:
ldr r0,[r0]
cmp r0,#0
@@ -23,7 +28,10 @@ __cp_begin:
svc 0
__cp_end:
ldmfd sp!,{r4,r5,r6,r7}
+ .cfi_def_cfa_offset 0
bx lr
__cp_cancel:
ldmfd sp!,{r4,r5,r6,r7}
+ .cfi_def_cfa_offset 0
b __cancel
+.cfi_endproc
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment