1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <dlfcn.h>
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <sys/wait.h>
21 #include <string.h>
22 #include <errno.h>
23 #include "test.h"
24
25 typedef void (* ATEXIT_CB)();
26
27 #define TEST_DSO "/data/tests/libc-test/src/libatexit_dlclose_dso.so"
28 #define ATEXIT_CB_NAME "atexit_cb"
29 #define ATEXIT_WATCHPOINT_NAME "g_watchpoint"
30 #define LIBATEXIT_DLCLOSE_DSO_ABSOLUTE_PATH "/data/tests/libc-test/src/libatexit_dlclose_dso.so"
31
fork_main(char * exe)32 int fork_main(char *exe)
33 {
34 char buf[512];
35 void *handler = NULL;
36 ATEXIT_CB cb = NULL;
37 unsigned int *wp_ptr = NULL;
38 unsigned int wp = 0;
39
40 int err = 0;
41
42 if(!t_pathrel(buf, sizeof(buf), exe, TEST_DSO)) {
43 t_error("failed to obtain relative path to " TEST_DSO "\n");
44 return 1;
45 }
46
47 handler = dlopen(LIBATEXIT_DLCLOSE_DSO_ABSOLUTE_PATH, RTLD_LAZY|RTLD_LOCAL);
48 if(!handler) {
49 t_error("dlopen %s failed: %s\n", buf, dlerror());
50 return 2;
51 }
52
53 cb = (ATEXIT_CB)dlsym(handler, ATEXIT_CB_NAME);
54 if (!cb) {
55 t_error("dlsym %s failed: %s\n", ATEXIT_CB_NAME, dlerror());
56 return 3;
57 }
58
59 wp_ptr = (unsigned int *)dlsym(handler, ATEXIT_WATCHPOINT_NAME);
60 if (!wp_ptr) {
61 t_error("dlsym %s failed: %s\n", ATEXIT_WATCHPOINT_NAME, dlerror());
62 return 3;
63 }
64
65 wp_ptr = ℘
66
67 err = atexit(cb);
68
69 if(dlclose( handler)) {
70 t_error("dlclose failed: %s\n", dlerror());
71 return 4;
72 }
73
74 if (wp == 0xFFFF) {
75 t_error("error, atexit callback called");
76 return 5;
77 }
78
79 return 0;
80 }
81
main(int argc,char * argv[])82 int main(int argc, char *argv[])
83 {
84 pid_t pid, w;
85 int err;
86 int wstatus;
87
88 pid = fork();
89 if (pid == 0) { // child process
90 return fork_main(argv[0]);
91 } else if (pid > 0) { // parent process
92 w = waitpid(pid, &wstatus, 0);
93 if (w == -1) {
94 t_error("wait for child process failed");
95 return 1;
96 }
97
98 if (WIFEXITED(wstatus)) {
99 err = WEXITSTATUS(wstatus);
100 t_error("exited with status=%d\n", err);
101 return err;
102 } else if (WIFSIGNALED(wstatus)) {
103 t_error("killed by signal %d\n", WTERMSIG(wstatus));
104 return 9;
105 } else if (WIFSTOPPED(wstatus)) {
106 t_error("stopped by signal %d\n", WSTOPSIG(wstatus));
107 return 9;
108 } else {
109 t_error("stopped by signal %d\n", WSTOPSIG(wstatus));
110 return 9;
111 }
112 } else {
113 t_error("fork failed: %s\n", strerror(errno));
114 return 1;
115 }
116 }
117
118