Subversion Repositories HelenOS

Rev

Rev 2999 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2999 Rev 3000
Line 115... Line 115...
115
 * @param mod       (output) Will be filled with a pointer to the module
115
 * @param mod       (output) Will be filled with a pointer to the module
116
 *          that contains the symbol.
116
 *          that contains the symbol.
117
 */
117
 */
118
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **mod)
118
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **mod)
119
{
119
{
120
    module_t *m;
120
    module_t *m, *dm;
121
    elf_symbol_t *sym;
121
    elf_symbol_t *sym, *s;
-
 
122
    link_t queue_head;
-
 
123
    size_t i;
122
 
124
 
-
 
125
    if (origin->dyn.symbolic) {
-
 
126
        /*
123
    /* FIXME: support DT_SYMBOLIC */
127
         * Origin module has a DT_SYMBOLIC flag.
-
 
128
         * Try this module first
-
 
129
         */
-
 
130
         s = def_find_in_module(name, origin);
-
 
131
         if (s != NULL) {
-
 
132
            /* Found */
124
    //m = origin;
133
            *mod = origin;
-
 
134
            return s;
-
 
135
         }
-
 
136
    }
125
 
137
 
126
    /* Start in the executable program */
138
    /* Otherwise start in the executable program */
127
    m = runtime_env.program;
-
 
128
 
139
 
-
 
140
    /*
-
 
141
     * Do a BFS using the queue_link and bfs_tag fields.
-
 
142
     * Vertices (modules) are tagged the moment they are inserted
-
 
143
     * into the queue. This prevents from visiting the same vertex
-
 
144
     * more times in case of circular dependencies.
-
 
145
     */
-
 
146
 
-
 
147
    /* Mark all vertices (modules) as unvisited */ 
129
    while (true) {
148
    modules_untag();
-
 
149
 
-
 
150
    /* Insert root (the program) into the queue and tag it */
-
 
151
    list_initialize(&queue_head);
-
 
152
    runtime_env.program->bfs_tag = true;
-
 
153
    list_append(&runtime_env.program->queue_link, &queue_head);
-
 
154
 
-
 
155
    /* If the symbol is found, it will be stored in 'sym' */
-
 
156
    sym = NULL;
-
 
157
 
-
 
158
    /* While queue is not empty */
-
 
159
    while (!list_empty(&queue_head)) {
-
 
160
        /* Pop first element from the queue */
-
 
161
        m = list_get_instance(queue_head.next, module_t, queue_link);
-
 
162
        list_remove(&m->queue_link);
-
 
163
 
130
        sym = def_find_in_module(name, m);
164
        s = def_find_in_module(name, m);
131
        if (sym != NULL) {
165
        if (s != NULL) {
-
 
166
            /* Symbol found */
-
 
167
            sym = s;
132
            *mod = m;
168
            *mod = m;
133
            return sym;
169
            break;
134
        }
170
        }
135
 
171
 
-
 
172
        /*
-
 
173
         * Insert m's untagged dependencies into the queue
-
 
174
         * and tag them.
-
 
175
         */
-
 
176
        for (i = 0; i < m->n_deps; ++i) {
136
        if (m->n_deps < 1) break;
177
            dm = m->deps[i];
137
 
178
 
138
        /* FIXME: support branching */
179
            if (dm->bfs_tag == false) {
139
        if (m->n_deps > 1) {
180
                dm->bfs_tag = true;
140
            printf("error: BFS unimplemented\n");
181
                list_append(&dm->queue_link, &queue_head);
141
            exit(1);
182
            }
142
        }
183
        }
-
 
184
    }
143
 
185
 
-
 
186
    /* Empty the queue so that we leave it in a clean state */
-
 
187
    while (!list_empty(&queue_head))
-
 
188
        list_remove(queue_head.next);
-
 
189
 
-
 
190
    if (!sym) {
-
 
191
        printf("Error, symbol '%s' not found anywhere\n", name);
144
        m = m->deps[0];
192
        exit(1);
-
 
193
        return NULL; /* Not found */
145
    }
194
    }
146
 
195
 
147
    printf("Error, symbol '%s' not found anywhere\n", name);
-
 
148
    exit(1);
-
 
149
    return NULL; /* Not found */
196
    return sym; /* Symbol found */
150
}
197
}
151
 
198
 
152
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m)
199
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m)
153
{
200
{
154
    if (sym->st_shndx == SHN_ABS) {
201
    if (sym->st_shndx == SHN_ABS) {