Subversion Repositories HelenOS

Rev

Rev 3400 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3400 Rev 3552
1
/*
1
/*
2
 * Copyright (c) 2008 Jiri Svoboda
2
 * Copyright (c) 2008 Jiri Svoboda
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
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
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.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup rtld rtld
29
/** @addtogroup rtld rtld
30
 * @brief
30
 * @brief
31
 * @{
31
 * @{
32
 */
32
 */
33
/**
33
/**
34
 * @file
34
 * @file
35
 */
35
 */
36
 
36
 
37
#include <loader/pcb.h>
37
#include <loader/pcb.h>
38
#include <elf_dyn.h>
38
#include <elf_dyn.h>
39
#include <rtld.h>
39
#include <rtld.h>
40
 
40
 
41
void __main(pcb_t *pcb);
41
void __main(pcb_t *pcb);
42
//void __io_init(void);
42
//void __io_init(void);
43
void __exit(void);
43
void __exit(void);
44
 
44
 
45
static void kputint(unsigned i)
45
static void kputint(unsigned i)
46
{
46
{
47
    unsigned dummy;
47
    unsigned dummy;
48
    asm volatile (
48
    asm volatile (
49
        "movl $32, %%eax;"
49
        "movl $32, %%eax;"
50
        "int $0x30"
50
        "int $0x30"
51
        : "=d" (dummy) /* output - %edx clobbered */
51
        : "=d" (dummy) /* output - %edx clobbered */
52
        : "d" (i) /* input */
52
        : "d" (i) /* input */
53
        : "%eax","%ecx" /* all scratch registers clobbered */
53
        : "%eax","%ecx" /* all scratch registers clobbered */
54
    );
54
    );
55
}
55
}
56
 
56
 
57
void __bootstrap(pcb_t *pcb)
57
void __bootstrap(pcb_t *pcb)
58
{
58
{
59
    unsigned bias;
59
    unsigned bias;
60
    unsigned *got;
60
    unsigned *got;
61
    elf_dyn_t *dynamic;
61
    elf_dyn_t *dynamic;
62
    void *dptr;
62
    void *dptr;
63
    unsigned dval;
63
    unsigned dval;
64
    int i;
64
    int i;
65
 
65
 
66
    size_t rel_entries;
66
    size_t rel_entries;
67
    size_t r_offset;
67
    size_t r_offset;
68
    elf_word r_info;
68
    elf_word r_info;
69
    unsigned rel_type;
69
    unsigned rel_type;
70
    elf_word sym_idx;
70
    elf_word sym_idx;
71
    uintptr_t sym_addr;
71
    uintptr_t sym_addr;
72
   
72
   
73
    elf_symbol_t *sym_table;
73
    elf_symbol_t *sym_table;
74
    elf_rel_t *rel_table;
74
    elf_rel_t *rel_table;
75
    elf_rel_t *jmp_rel_table;
75
    elf_rel_t *jmp_rel_table;
76
    size_t jmp_rel_entries;
76
    size_t jmp_rel_entries;
77
 
77
 
78
    /* The program loader kindly provided us with these */
78
    /* The program loader kindly provided us with these */
79
    dynamic = pcb->rtld_dynamic;
79
    dynamic = pcb->rtld_dynamic;
80
    bias = pcb->rtld_bias;
80
    bias = pcb->rtld_bias;
81
/*
81
/*
82
asm volatile (
82
asm volatile (
83
    // Calculate the bias into %0
83
    // Calculate the bias into %0
84
    // Generates "fake" R_386_RELATIVE run-time relocation
84
    // Generates "fake" R_386_RELATIVE run-time relocation
85
"   call .L0;"
85
"   call .L0;"
86
".L0:   pop %0;"
86
".L0:   pop %0;"
87
"   subl $.L0, %0;"
87
"   subl $.L0, %0;"
88
 
88
 
89
    // Calculate run-time address of _DYNAMIC into %1
89
    // Calculate run-time address of _DYNAMIC into %1
90
    // Generates "fake" R_386_RELATIVE run-time relocation
90
    // Generates "fake" R_386_RELATIVE run-time relocation
91
"   movl $_DYNAMIC, %1;"    // Again, at link time 0-based VMA gets in
91
"   movl $_DYNAMIC, %1;"    // Again, at link time 0-based VMA gets in
92
"   addl %0, %1;"       // Add bias to compute run-time address
92
"   addl %0, %1;"       // Add bias to compute run-time address
93
 
93
 
94
: "=r" (bias), "=r" (dynamic)
94
: "=r" (bias), "=r" (dynamic)
95
);
95
);
96
*/
96
*/
97
    kputint(pcb);
97
    kputint(pcb);
98
    kputint(bias);
98
    kputint(bias);
99
    kputint((unsigned)dynamic);
99
    kputint((unsigned)dynamic);
100
 
100
 
101
    /* parse DYNAMIC */
101
    /* parse DYNAMIC */
102
    got = 0;
102
    got = 0;
103
    sym_table = 0;
103
    sym_table = 0;
104
    rel_table = 0;
104
    rel_table = 0;
105
    rel_entries = 0;
105
    rel_entries = 0;
106
    jmp_rel_table = 0;
106
    jmp_rel_table = 0;
107
    jmp_rel_entries = 0;
107
    jmp_rel_entries = 0;
108
 
108
/*
109
    i = 0;
109
    i = 0;
110
    while (dynamic[i].d_tag != 0) {
110
    while (dynamic[i].d_tag != 0) {
111
        dptr = (void *)(dynamic[i].d_un.d_val + bias);
111
        dptr = (void *)(dynamic[i].d_un.d_val + bias);
112
        dval = dynamic[i].d_un.d_val;
112
        dval = dynamic[i].d_un.d_val;
113
 
113
 
114
        switch (dynamic[i].d_tag) {
114
        switch (dynamic[i].d_tag) {
115
        case DT_PLTRELSZ: jmp_rel_entries = dval/8; break;
115
        case DT_PLTRELSZ: jmp_rel_entries = dval/8; break;
116
        case DT_JMPREL: jmp_rel_table = dptr; break;
116
        case DT_JMPREL: jmp_rel_table = dptr; break;
117
        case DT_PLTGOT:
117
        case DT_PLTGOT:*/
118
            /* GOT address */
118
            /* GOT address */
119
            got = dptr; break;
119
            /*got = dptr; break;
120
        case DT_SYMTAB: sym_table = dptr; break;
120
        case DT_SYMTAB: sym_table = dptr; break;
121
        case DT_REL: rel_table = dptr; break;
121
        case DT_REL: rel_table = dptr; break;
122
        case DT_RELSZ: rel_entries = dval / 8; break;
122
        case DT_RELSZ: rel_entries = dval / 8; break;
123
        default: break;
123
        default: break;
124
        }
124
        }
125
 
125
 
126
        ++i;
126
        ++i;
127
    }
127
    }
128
   
128
    */
129
//  kputint(1);
129
//  kputint(1);
130
//  kputint((unsigned)sym_table);
130
//  kputint((unsigned)sym_table);
131
//  kputint((unsigned)rel_table);
131
//  kputint((unsigned)rel_table);
132
//  kputint((unsigned)rel_entries);
132
//  kputint((unsigned)rel_entries);
133
 
133
 
134
    /* Now relocate all our dynsyms */
134
    /* Now relocate all our dynsyms */
135
//  kputint(-1);
135
//  kputint(-1);
136
   
136
/* 
137
    for (i=0; i<rel_entries; i++) {
137
    for (i=0; i<rel_entries; i++) {
138
        kputint(i);
138
        kputint(i);
139
        r_offset = rel_table[i].r_offset;
139
        r_offset = rel_table[i].r_offset;
140
        r_info = rel_table[i].r_info;
140
        r_info = rel_table[i].r_info;
141
 
141
 
142
        rel_type = ELF32_R_TYPE(r_info);
142
        rel_type = ELF32_R_TYPE(r_info);
143
 
143
 
144
        kputint(rel_type);
144
        kputint(rel_type);
145
        kputint(r_offset);
145
        kputint(r_offset);
146
 
146
 
147
        switch (rel_type) {
147
        switch (rel_type) {
148
        case R_386_GLOB_DAT:
148
        case R_386_GLOB_DAT:
149
        case R_386_JUMP_SLOT:
149
        case R_386_JUMP_SLOT:
150
            kputint(16);
150
            kputint(16);
151
            sym_idx = ELF32_R_SYM(r_info);
151
            sym_idx = ELF32_R_SYM(r_info);
152
 
152
 
153
            sym_addr = sym_table[sym_idx].st_value + bias;
153
            sym_addr = sym_table[sym_idx].st_value + bias;
154
            kputint(sym_idx);
154
            kputint(sym_idx);
155
            kputint(sym_addr);
155
            kputint(sym_addr);
156
 
156
 
157
            *(unsigned *)(r_offset+bias) = sym_addr;
157
            *(unsigned *)(r_offset+bias) = sym_addr;
158
            break;
158
            break;
159
 
159
 
160
        case R_386_32:
160
        case R_386_32:
161
            kputint(16);
161
            kputint(16);
162
            sym_idx = ELF32_R_SYM(r_info);
162
            sym_idx = ELF32_R_SYM(r_info);
163
 
163
 
164
            sym_addr = sym_table[sym_idx].st_value + bias;
164
            sym_addr = sym_table[sym_idx].st_value + bias;
165
            kputint(sym_idx);
165
            kputint(sym_idx);
166
            kputint(sym_addr);
166
            kputint(sym_addr);
167
 
167
 
168
            *(unsigned *)(r_offset+bias) += sym_addr;
168
            *(unsigned *)(r_offset+bias) += sym_addr;
169
            break;
169
            break;
170
           
170
           
171
        case R_386_RELATIVE:
171
        case R_386_RELATIVE:
172
            kputint(16);
172
            kputint(16);
173
            *(unsigned *)(r_offset+bias) += bias;
173
            *(unsigned *)(r_offset+bias) += bias;
174
            break;
174
            break;
175
        }
175
        }
176
    }
176
    }
177
 
177
*/
178
    kputint(-1);
178
    kputint(-1);
179
   
179
/* 
180
    for (i=0; i<jmp_rel_entries; i++) {
180
    for (i=0; i<jmp_rel_entries; i++) {
181
        kputint(i);
181
        kputint(i);
182
        r_offset = jmp_rel_table[i].r_offset;
182
        r_offset = jmp_rel_table[i].r_offset;
183
        r_info = jmp_rel_table[i].r_info;
183
        r_info = jmp_rel_table[i].r_info;
184
 
184
 
185
        rel_type = ELF32_R_TYPE(r_info);
185
        rel_type = ELF32_R_TYPE(r_info);
186
 
186
 
187
        kputint(rel_type);
187
        kputint(rel_type);
188
        kputint(r_offset);
188
        kputint(r_offset);
189
 
189
 
190
        switch (rel_type) {
190
        switch (rel_type) {
191
        case R_386_GLOB_DAT:
191
        case R_386_GLOB_DAT:
192
        case R_386_JUMP_SLOT:
192
        case R_386_JUMP_SLOT:
193
            kputint(16);
193
            kputint(16);
194
            sym_idx = ELF32_R_SYM(r_info);
194
            sym_idx = ELF32_R_SYM(r_info);
195
 
195
 
196
            sym_addr = sym_table[sym_idx].st_value + bias;
196
            sym_addr = sym_table[sym_idx].st_value + bias;
197
            kputint(sym_idx);
197
            kputint(sym_idx);
198
            kputint(sym_addr);
198
            kputint(sym_addr);
199
 
199
 
200
            *(unsigned *)(r_offset+bias) = sym_addr;
200
            *(unsigned *)(r_offset+bias) = sym_addr;
201
            break;
201
            break;
202
 
202
 
203
        case R_386_32:
203
        case R_386_32:
204
            kputint(16);
204
            kputint(16);
205
            sym_idx = ELF32_R_SYM(r_info);
205
            sym_idx = ELF32_R_SYM(r_info);
206
 
206
 
207
            sym_addr = sym_table[sym_idx].st_value + bias;
207
            sym_addr = sym_table[sym_idx].st_value + bias;
208
            kputint(sym_idx);
208
            kputint(sym_idx);
209
            kputint(sym_addr);
209
            kputint(sym_addr);
210
 
210
 
211
            *(unsigned *)(r_offset+bias) += sym_addr;
211
            *(unsigned *)(r_offset+bias) += sym_addr;
212
            break;
212
            break;
213
           
213
           
214
        case R_386_RELATIVE:
214
        case R_386_RELATIVE:
215
            kputint(16);
215
            kputint(16);
216
            *(unsigned *)(r_offset+bias) += bias;
216
            *(unsigned *)(r_offset+bias) += bias;
217
            break;
217
            break;
218
        }
218
        }
219
    }
219
    }
220
 
220
*/
221
    kputint(-1);
221
    kputint(-1);
222
    kputint(0x42);
222
    kputint(0x42);
223
 
223
 
224
    /* This will come in handy */
224
    /* This will come in handy */
225
    __pcb = pcb;
225
    __pcb = pcb;
226
    runtime_env.rtld_dynamic = dynamic;
226
    runtime_env.rtld_dynamic = dynamic;
227
    runtime_env.rtld.bias = bias;
227
    runtime_env.rtld.bias = bias;
228
 
228
 
229
    kputint(0x43);
229
    kputint(0x43);
230
   
230
   
231
    /* Init libc and run rtld main */
231
    /* Init libc and run rtld main */
232
    __main(pcb);
232
    __main(pcb);
233
 
233
 
234
    kputint(0x44);
234
    kputint(0x44);
235
 
235
 
236
//  kputint(33);
236
//  kputint(33);
237
//  __io_init();
237
//  __io_init();
238
    kputint(34);
238
    kputint(34);
239
    _rtld_main();
239
    _rtld_main();
240
    kputint(35);
240
    kputint(35);
241
    __exit();
241
    __exit();
242
 
242
 
243
    kputint(36);
243
    kputint(36);
244
 
244
 
245
    asm (
245
    asm (
246
        "movl $250, %%eax;"
246
        "movl $250, %%eax;"
247
        "int $0x30"
247
        "int $0x30"
248
        : /* output */
248
        : /* output */
249
        : /* input */
249
        : /* input */
250
        : "%eax","%ecx","%edx" /* all scratch registers clobbered */
250
        : "%eax","%ecx","%edx" /* all scratch registers clobbered */
251
    );
251
    );
252
}
252
}
253
 
253
 
254
/** @}
254
/** @}
255
 */
255
 */
256
 
256