2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #ifdef PRELOAD_ACTIVATE
21 #define PRELOAD_FILE SHARE_PREFIX"/preload_list.txt"
22 #define PRELOAD_FILE_WRT SHARE_PREFIX"/preload_list_wrt.txt"
24 #define EFL_PREINIT_FUNC "elm_quicklaunch_init"
25 #define EFL_SHUTDOWN_FUNC "elm_quicklaunch_shutdown"
27 static int preload_initialized = 0;
30 static size_t max_cmdline_size = 0;
32 static int (*dl_einit) () = NULL;
33 static int (*dl_efini) () = NULL;
35 static inline void __preload_init(int argc, char **argv)
38 char soname[MAX_LOCAL_BUFSZ] = {0, };
45 for (i = 0; i < argc; i++) {
46 max_cmdline_size += (strlen(argv[i]) + 1);
48 _D("max_cmdline_size = %d", max_cmdline_size);
50 preload_list = fopen(PRELOAD_FILE, "rt");
51 if (preload_list == NULL) {
56 while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) > (char*)0) {
57 soname[MAX_LOCAL_BUFSZ-1] = 0;
58 handle = dlopen(soname, RTLD_NOW);
61 _D("preload %s# - handle : %x\n", soname, handle);
63 func = dlsym(handle, EFL_PREINIT_FUNC);
65 _D("get pre-initialization function\n");
67 func = dlsym(handle, EFL_SHUTDOWN_FUNC);
69 _D("get shutdown function\n");
76 preload_initialized = 1;
79 static inline int preinit_init()
83 _D("pre-initialzation on");
87 static inline int preinit_fini()
91 _D("pre-initialization off");
95 /* TODO : how to set cmdline gracefully ?? */
96 static inline int __change_cmdline(char *cmdline)
98 if (strlen(cmdline) > max_cmdline_size + 1) {
99 _E("cmdline exceed max size : %d", max_cmdline_size);
103 memset(g_argv[0], '\0', max_cmdline_size);
104 snprintf(g_argv[0], max_cmdline_size, "%s", cmdline);
109 static inline void __preload_exec(int argc, char **argv)
112 int (*dl_main) (int, char **);
114 if (!preload_initialized)
117 handle = dlopen(argv[0], RTLD_LAZY | RTLD_GLOBAL);
118 if (handle == NULL) {
122 dl_main = dlsym(handle, "main");
123 if (dl_main != NULL) {
124 #ifndef NATIVE_LAUNCHPAD
127 if (__change_cmdline(argv[0]) < 0) {
128 _E("change cmdline fail");
134 _E("dlsym not founded. bad preloaded app - check fpie pie");
140 static int g_dlopen_size = 5;
141 static int g_dlopen_count = 0;
142 static void** g_dlopen_handle_list = NULL;
144 static inline int __preload_save_dlopen_handle(void *handle)
149 if (g_dlopen_count == g_dlopen_size || !g_dlopen_handle_list) {
150 void** tmp = realloc(g_dlopen_handle_list, 2 * g_dlopen_size * sizeof(void *));
152 _E("out of memory\n");
157 g_dlopen_handle_list = tmp;
159 g_dlopen_handle_list[g_dlopen_count++] = handle;
163 static inline void __preload_fini_for_wrt()
166 if (!g_dlopen_handle_list)
168 for (i = 0; i < g_dlopen_count; ++i)
170 void *handle = g_dlopen_handle_list[i];
172 if (0 != dlclose(handle)) {
173 _E("dlclose failed\n");
177 free(g_dlopen_handle_list);
178 g_dlopen_handle_list = NULL;
183 static inline void __preload_init_for_wrt()
185 if (0 != atexit(__preload_fini_for_wrt)) {
186 _E("Cannot register atexit callback. Libraries will not be unloaded");
189 char soname[MAX_LOCAL_BUFSZ];
192 preload_list = fopen(PRELOAD_FILE_WRT, "rt");
193 if (preload_list == NULL) {
194 _E("no wrt preload\n");
198 while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) != NULL) {
199 size_t len = strnlen(soname, MAX_LOCAL_BUFSZ);
201 soname[len - 1] = '\0';
202 handle = dlopen(soname, RTLD_NOW|RTLD_GLOBAL);
205 if (0 != __preload_save_dlopen_handle(handle)) {
206 _E("Cannot save handle, no more preloads");
209 _D("preload %s# - handle : %x\n", soname, handle);
212 fclose(preload_list);
217 static inline void __preload_init(int argc, char **argv);
218 static inline void __preload_exec(int argc, char **argv);
219 static inline void __preload_init_for_wrt();