00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <unistd.h>
00040 #include <fcntl.h>
00041 #include <adt/list.h>
00042 #include <loader/pcb.h>
00043
00044 #include <rtld/rtld.h>
00045 #include <rtld/rtld_debug.h>
00046 #include <rtld/dynamic.h>
00047 #include <rtld/rtld_arch.h>
00048 #include <rtld/module.h>
00049 #include <elf_load.h>
00050
00055 void module_process_relocs(module_t *m)
00056 {
00057 DPRINTF("module_process_relocs('%s')\n", m->dyn.soname);
00058
00059
00060 if (m->relocated) return;
00061
00062 module_process_pre_arch(m);
00063
00064 if (m->dyn.plt_rel == DT_REL) {
00065 DPRINTF("table type DT_REL\n");
00066 if (m->dyn.rel != NULL) {
00067 DPRINTF("non-empty\n");
00068 rel_table_process(m, m->dyn.rel, m->dyn.rel_sz);
00069 }
00070
00071 if (m->dyn.jmp_rel != NULL) {
00072 DPRINTF("table type jmp-rel\n");
00073 DPRINTF("non-empty\n");
00074 rel_table_process(m, m->dyn.jmp_rel, m->dyn.plt_rel_sz);
00075 }
00076 } else {
00077 DPRINTF("table type DT_RELA\n");
00078 if (m->dyn.rela != NULL) {
00079 DPRINTF("non-empty\n");
00080 rela_table_process(m, m->dyn.rela, m->dyn.rela_sz);
00081 }
00082 }
00083
00084 m->relocated = true;
00085 }
00086
00093 module_t *module_find(const char *name)
00094 {
00095 link_t *head = &runtime_env->modules_head;
00096
00097 link_t *cur;
00098 module_t *m;
00099 const char *p, *soname;
00100
00101 DPRINTF("module_find('%s')\n", name);
00102
00103
00104
00105
00106
00107
00108 p = str_rchr(name, '/');
00109 soname = p ? (p + 1) : name;
00110
00111
00112 DPRINTF("head = %p\n", head);
00113 for (cur = head->next; cur != head; cur = cur->next) {
00114 DPRINTF("cur = %p\n", cur);
00115 m = list_get_instance(cur, module_t, modules_link);
00116 if (str_cmp(m->dyn.soname, soname) == 0) {
00117 return m;
00118 }
00119 }
00120
00121 return NULL;
00122 }
00123
00124 #define NAME_BUF_SIZE 64
00125
00130 module_t *module_load(const char *name)
00131 {
00132 elf_info_t info;
00133 char name_buf[NAME_BUF_SIZE];
00134 module_t *m;
00135 int rc;
00136
00137 m = malloc(sizeof(module_t));
00138 if (!m) {
00139 printf("malloc failed\n");
00140 exit(1);
00141 }
00142
00143 if (str_size(name) > NAME_BUF_SIZE - 2) {
00144 printf("soname too long. increase NAME_BUF_SIZE\n");
00145 exit(1);
00146 }
00147
00148
00149 str_cpy(name_buf, NAME_BUF_SIZE, "/lib/");
00150 str_cpy(name_buf + 5, NAME_BUF_SIZE - 5, name);
00151
00152
00153 m->bias = runtime_env->next_bias;
00154 runtime_env->next_bias += 0x100000;
00155
00156 DPRINTF("filename:'%s'\n", name_buf);
00157 DPRINTF("load '%s' at 0x%x\n", name_buf, m->bias);
00158
00159 rc = elf_load_file(name_buf, m->bias, ELDF_RW, &info);
00160 if (rc != EE_OK) {
00161 printf("Failed to load '%s'\n", name_buf);
00162 exit(1);
00163 }
00164
00165 if (info.dynamic == NULL) {
00166 printf("Error: '%s' is not a dynamically-linked object.\n",
00167 name_buf);
00168 exit(1);
00169 }
00170
00171
00172 m->relocated = false;
00173
00174 DPRINTF("parse dynamic section\n");
00175
00176 dynamic_parse(info.dynamic, m->bias, &m->dyn);
00177
00178
00179 list_append(&m->modules_link, &runtime_env->modules_head);
00180
00181 return m;
00182 }
00183
00186 void module_load_deps(module_t *m)
00187 {
00188 elf_dyn_t *dp;
00189 char *dep_name;
00190 module_t *dm;
00191 size_t n, i;
00192
00193 DPRINTF("module_load_deps('%s')\n", m->dyn.soname);
00194
00195
00196
00197 dp = m->dyn.dynamic;
00198 n = 0;
00199
00200 while (dp->d_tag != DT_NULL) {
00201 if (dp->d_tag == DT_NEEDED) ++n;
00202 ++dp;
00203 }
00204
00205
00206
00207 m->n_deps = n;
00208
00209 if (n == 0) {
00210
00211 m->deps = NULL;
00212 return;
00213 }
00214
00215 m->deps = malloc(n * sizeof(module_t *));
00216 if (!m->deps) {
00217 printf("malloc failed\n");
00218 exit(1);
00219 }
00220
00221 i = 0;
00222 dp = m->dyn.dynamic;
00223
00224 while (dp->d_tag != DT_NULL) {
00225 if (dp->d_tag == DT_NEEDED) {
00226 dep_name = m->dyn.str_tab + dp->d_un.d_val;
00227
00228 DPRINTF("%s needs %s\n", m->dyn.soname, dep_name);
00229 dm = module_find(dep_name);
00230 if (!dm) {
00231 dm = module_load(dep_name);
00232 module_load_deps(dm);
00233 }
00234
00235
00236 m->deps[i++] = dm;
00237 }
00238 ++dp;
00239 }
00240 }
00241
00249 void modules_process_relocs(module_t *start)
00250 {
00251 link_t *head = &runtime_env->modules_head;
00252
00253 link_t *cur;
00254 module_t *m;
00255
00256 for (cur = head->next; cur != head; cur = cur->next) {
00257 m = list_get_instance(cur, module_t, modules_link);
00258
00259
00260 if (m != &runtime_env->rtld) {
00261 module_process_relocs(m);
00262 }
00263 }
00264 }
00265
00268 void modules_untag(void)
00269 {
00270 link_t *head = &runtime_env->modules_head;
00271
00272 link_t *cur;
00273 module_t *m;
00274
00275 for (cur = head->next; cur != head; cur = cur->next) {
00276 m = list_get_instance(cur, module_t, modules_link);
00277 m->bfs_tag = false;
00278 }
00279 }
00280