Subversion Repositories HelenOS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2933 svoboda 1
/*
2
 * Copyright (c) 2008 Jiri Svoboda
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
 
29
/** @addtogroup rtld rtld
30
 * @brief
31
 * @{
32
 */
33
/**
34
 * @file
35
 */
36
 
37
void _rtld_main(void);
38
 
39
#define ELF32_R_SYM(i) ((i)>>8)
40
#define ELF32_R_TYPE(i) ((unsigned char)(i))
41
 
42
typedef struct {
43
    int d_tag;
44
    union {
45
        unsigned d_val;
46
        unsigned *d_ptr;
47
    } d_un;
48
} elf32_dyn;
49
 
50
typedef struct {
51
    unsigned r_offset;
52
    unsigned r_info;
53
} elf32_rel;
54
 
55
typedef struct {
56
    unsigned st_name;
57
    unsigned st_value;
58
    unsigned st_size;
59
    unsigned char st_info;
60
    unsigned char st_other;
61
    unsigned short st_shndx;
62
} elf32_sym;
63
 
64
static void kputint(unsigned i)
65
{
66
    unsigned dummy;
67
    asm volatile (
68
        "movl $30, %%eax;"
69
        "int $0x30"
70
        : "=d" (dummy) /* output - %edx clobbered */
71
        : "d" (i) /* input */
72
        : "%eax","%ecx" /* all scratch registers clobbered */
73
    ); 
74
}
75
 
76
void __bootstrap(void)
77
{
78
    unsigned bias;
79
    unsigned *got;
80
    elf32_dyn *dynamic;
81
    unsigned *dptr;
82
    unsigned dval;
83
    int i;
84
 
85
    unsigned rel_entries;
86
    unsigned r_offset;
87
    unsigned r_info;
88
    unsigned rel_type;
89
    unsigned sym_idx;
90
    unsigned sym_addr;
91
 
92
    elf32_sym *sym_table;
93
    elf32_rel *rel_table;
94
 
95
    asm volatile (
96
    "movl $30, %eax;"
97
    "int $0x30"
98
    );
99
 
100
    /* Copied from libc/arch/ia32/entry.s */
101
/*asm volatile (
102
    "mov %ss, %ax;"
103
    "mov %ax, %ds;"
104
    "mov %ax, %es;"
105
    "mov %ax, %fs;"
106
);*/
107
 
108
 
109
asm volatile (
110
    /* Calculate the bias into %0 */
111
"   call .L0;"
112
".L0:   pop %0;"
113
"   subl $.L0, %0;"
114
 
115
    /* Calculate run-time address of _DYNAMIC into %1 */
116
"   movl $_DYNAMIC, %1;"    /* Again, at link time 0-based VMA gets in */
117
"   addl %0, %1;"       /* Add bias to compute run-time address */
118
 
119
: "=r" (bias), "=r" (dynamic)
120
);
121
 
122
    kputint(bias);
123
    kputint((unsigned)dynamic);
124
 
125
    /* parse DYNAMIC */
126
    got = 0;
127
    sym_table = 0;
128
    rel_table = 0;
129
    rel_entries = 0;
130
 
131
    i = 0;
132
    while (dynamic[i].d_tag != 0) {
133
        dptr = (unsigned *)(dynamic[i].d_un.d_val + bias);
134
        dval = dynamic[i].d_un.d_val;
135
 
136
        switch (dynamic[i].d_tag) {
137
        case 3 /* DT_PLTGOT */:
138
            /* GOT address */
139
            got = dptr; break;
140
        case 6 /* DT_SYMTAB */ : sym_table = dptr; break;
141
        case 17 /* DT_REL */ : rel_table = dptr; break;
142
        case 18 /* DT_RELSZ */ : rel_entries = dval / 8; break;
143
        default: break;
144
        }
145
 
146
        ++i;
147
    }
148
 
149
    kputint(1);
150
    kputint((unsigned)sym_table);
151
    kputint((unsigned)rel_table);
152
    kputint((unsigned)rel_entries);
153
 
154
    /* Now relocate all our dynsyms */
155
    kputint(-1);
156
 
157
    for (i=0; i<rel_entries; i++) {
158
        kputint(i);
159
        r_offset = rel_table[i].r_offset;
160
        r_info = rel_table[i].r_info;
161
 
162
        rel_type = ELF32_R_TYPE(r_info);
163
 
164
        kputint(rel_type);
165
        kputint(r_offset);
166
 
167
        if (rel_type == 7 /* R_386_JUMP_SLOT */) {
168
            kputint(16);
169
            sym_idx = ELF32_R_SYM(r_info);
170
 
171
            sym_addr = sym_table[sym_idx].st_value + bias;
172
            kputint(sym_idx);
173
            kputint(sym_addr);
174
 
175
            *(unsigned *)(r_offset+bias) = sym_addr;
176
        }
177
    }
178
 
179
    kputint(-1);
180
 
181
    kputint(32);
182
 
183
    _rtld_main();
184
 
185
    asm (
186
        "movl $250, %%eax;"
187
        "int $0x30"
188
        : /* output */
189
        : /* input */
190
        : "%eax","%ecx","%edx" /* all scratch registers clobbered */
191
    );
192
}
193
 
194
/** @}
195
 */