Subversion Repositories HelenOS

Rev

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

Rev 2981 Rev 2998
Line 40... Line 40...
40
 
40
 
41
#include <rtld.h>
41
#include <rtld.h>
42
#include <symbol.h>
42
#include <symbol.h>
43
#include <elf.h>
43
#include <elf.h>
44
 
44
 
-
 
45
/*
-
 
46
 * Hash tables are 32-bit (elf_word) even for 64-bit ELF files.
-
 
47
 */
-
 
48
static elf_word elf_hash(const unsigned char *name)
-
 
49
{
-
 
50
    elf_word h = 0, g;
-
 
51
 
-
 
52
    while (*name) {
-
 
53
        h = (h << 4) + *name++;
-
 
54
        g = h & 0xf0000000;
-
 
55
        if (g != 0) h ^= g >> 24;
-
 
56
        h &= ~g;
-
 
57
    }
-
 
58
 
-
 
59
    return h;
-
 
60
}
-
 
61
 
45
static elf_symbol_t *def_find_in_module(char *name, module_t *m)
62
static elf_symbol_t *def_find_in_module(char *name, module_t *m)
46
{
63
{
47
    elf_symbol_t *sym_table;
64
    elf_symbol_t *sym_table;
48
    elf_symbol_t *sym;
65
    elf_symbol_t *s, *sym;
-
 
66
    elf_word nbucket;
49
    elf_word nchain;
67
    elf_word nchain;
50
    size_t i;
68
    elf_word i;
51
    char *s_name;
69
    char *s_name;
52
    char *module_name;
70
    elf_word bucket;
53
 
71
 
54
    module_name = m->dyn.soname;
72
//  module_name = m->dyn.soname;
55
//  printf("def_find_in_module('%s', %s)\n", name, module_name);
73
//  printf("def_find_in_module('%s', %s)\n", name, module_name);
56
 
74
 
57
    sym_table = m->dyn.sym_tab;
75
    sym_table = m->dyn.sym_tab;
-
 
76
    nbucket = m->dyn.hash[0];
58
    nchain = m->dyn.hash[1];
77
    nchain = m->dyn.hash[1];
59
 
78
 
-
 
79
    bucket = elf_hash((unsigned char *)name) % nbucket;
-
 
80
    i = m->dyn.hash[2 + bucket];
-
 
81
 
-
 
82
    sym = NULL;
60
    for (i = 0; i < nchain; ++i) {
83
    while (i != STN_UNDEF) {
61
        sym = &sym_table[i];
84
        s = &sym_table[i];
62
        s_name = m->dyn.str_tab + sym->st_name;
85
        s_name = m->dyn.str_tab + s->st_name;
63
//      printf("cmp sym '%s'\n", s_name);
-
 
-
 
86
 
64
        if (strcmp(name, s_name) == 0) {
87
        if (strcmp(name, s_name) == 0) {
65
//          printf("name match\n");
-
 
66
            if (sym->st_shndx != SHN_UNDEF) {
-
 
67
//              printf("definition found. idx=%d\n", i);
-
 
68
                return sym;
88
            sym = s;
69
            } else {
89
            break;
70
//              printf("not a definition\n");
-
 
71
            }
-
 
72
        }
90
        }
-
 
91
 
-
 
92
        i = m->dyn.hash[2 + nbucket + i];
73
    }
93
    }
74
 
94
 
-
 
95
    if (!sym)
75
//  printf("not found\n");
96
        return NULL;    /* Not found */
-
 
97
 
-
 
98
    if (sym->st_shndx == SHN_UNDEF) {
-
 
99
        /* Not a definition */
76
    return NULL;
100
        return NULL;
-
 
101
    }
-
 
102
 
-
 
103
    return sym; /* Found */
77
}
104
}
78
 
105
 
79
 
106
 
80
elf_symbol_t *symbol_def_find(char *name, module_t **m)
107
elf_symbol_t *symbol_def_find(char *name, module_t **m)
81
{
108
{
Line 93... Line 120...
93
    printf("symbol found nowhere\n");
120
    printf("symbol found nowhere\n");
94
    *m = NULL;
121
    *m = NULL;
95
    return NULL;
122
    return NULL;
96
}
123
}
97
 
124
 
-
 
125
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m)
-
 
126
{
-
 
127
    if (sym->st_shndx == SHN_ABS) {
-
 
128
        /* Do not add bias to absolute symbols */
-
 
129
        return sym->st_value;
-
 
130
    } else {
-
 
131
        return sym->st_value + m->bias;
-
 
132
    }
-
 
133
}
-
 
134
 
98
/** @}
135
/** @}
99
 */
136
 */