Subversion Repositories HelenOS

Rev

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

Rev 2962 Rev 2964
Line 59... Line 59...
59
    "incompatible image",
59
    "incompatible image",
60
    "unsupported image type",
60
    "unsupported image type",
61
    "irrecoverable error"
61
    "irrecoverable error"
62
};
62
};
63
 
63
 
64
static unsigned int elf_load(int fd, elf_header_t *header);
64
static unsigned int elf_load(elf_ld_t *elf);
65
static int segment_header(int fd, elf_header_t *elf);
65
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
66
static int section_header(int fd, elf_header_t *elf);
66
static int section_header(elf_ld_t *elf, elf_section_header_t *entry);
67
static int load_segment(int fd, elf_segment_header_t *entry, elf_header_t *elf);
67
static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
68
 
68
 
69
typedef void (*entry_point_t)(void);
-
 
70
 
-
 
71
int elf_load_file(char *file_name, elf_header_t *header)
69
int elf_load_file(char *file_name, elf_info_t *info)
72
{
70
{
-
 
71
    elf_ld_t elf;
-
 
72
 
73
    int fd;
73
    int fd;
74
    int rc;
74
    int rc;
75
 
75
 
76
    printf("open and read '%s'...\n", file_name);
76
    printf("open and read '%s'...\n", file_name);
77
 
77
 
Line 79... Line 79...
79
    if (fd < 0) {
79
    if (fd < 0) {
80
        printf("failed opening file\n");
80
        printf("failed opening file\n");
81
        return -1;
81
        return -1;
82
    }
82
    }
83
 
83
 
-
 
84
    elf.fd = fd;
-
 
85
    elf.info = info;
-
 
86
 
84
    rc = elf_load(fd, header);
87
    rc = elf_load(&elf);
85
    printf("elf_load() -> %d\n", rc);
88
    printf("elf_load() -> %d\n", rc);
86
 
89
 
87
    close(fd);
90
    close(fd);
88
 
91
 
89
    return rc;
92
    return rc;
90
}
93
}
91
 
94
 
92
void elf_run(elf_header_t *header)
95
void elf_run(elf_info_t *info)
93
{
96
{
94
    entry_point_t entry_point;
-
 
95
 
-
 
96
    entry_point = (entry_point_t)header->e_entry;
-
 
97
    (*entry_point)();
97
    (*info->entry)();
98
 
98
 
99
    /* not reached */
99
    /* not reached */
100
}
100
}
101
 
101
 
102
int elf_create_pcb(elf_header_t *header)
102
int elf_create_pcb(elf_info_t *info)
103
{
103
{
104
    pcb_t *pcb;
104
    pcb_t *pcb;
105
    void *a;
105
    void *a;
106
 
106
 
107
    pcb = (pcb_t *)PCB_ADDRESS;
107
    pcb = (pcb_t *)PCB_ADDRESS;
Line 110... Line 110...
110
    if (a == (void *)(-1)) {
110
    if (a == (void *)(-1)) {
111
        printf("elf_create_pcb: memory mapping failed\n");
111
        printf("elf_create_pcb: memory mapping failed\n");
112
        return EE_MEMORY;
112
        return EE_MEMORY;
113
    }
113
    }
114
 
114
 
115
    pcb->entry = (entry_point_t)header->e_entry;
115
    pcb->entry = info->entry;
116
 
116
 
117
    return 0;
117
    return 0;
118
}
118
}
119
 
119
 
120
 
120
 
121
/** ELF loader
121
/** ELF loader
122
 *
122
 *
123
 * @param header Pointer to ELF header in memory
123
 * @param header Pointer to ELF header in memory
124
 * @return EE_OK on success
124
 * @return EE_OK on success
125
 */
125
 */
126
static unsigned int elf_load(int fd, elf_header_t *header)
126
static unsigned int elf_load(elf_ld_t *elf)
127
{
127
{
-
 
128
    elf_header_t header_buf;
-
 
129
    elf_header_t *header = &header_buf;
128
    int i, rc;
130
    int i, rc;
129
 
131
 
130
    rc = read(fd, header, sizeof(elf_header_t));
132
    rc = read(elf->fd, header, sizeof(elf_header_t));
131
    if (rc < 0) {
133
    if (rc < 0) {
132
        printf("read error\n");
134
        printf("read error\n");
133
        return EE_INVALID;
135
        return EE_INVALID;
134
    }
136
    }
135
 
137
 
-
 
138
    elf->header = header;
-
 
139
 
136
    printf("ELF-load:");
140
    printf("ELF-load:");
137
    /* Identify ELF */
141
    /* Identify ELF */
138
    if (header->e_ident[EI_MAG0] != ELFMAG0 ||
142
    if (header->e_ident[EI_MAG0] != ELFMAG0 ||
139
        header->e_ident[EI_MAG1] != ELFMAG1 ||
143
        header->e_ident[EI_MAG1] != ELFMAG1 ||
140
        header->e_ident[EI_MAG2] != ELFMAG2 ||
144
        header->e_ident[EI_MAG2] != ELFMAG2 ||
Line 162... Line 166...
162
    /* Check if the object type is supported. */
166
    /* Check if the object type is supported. */
163
    if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
167
    if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
164
        printf("Object type %d is not supported\n", header->e_type);
168
        printf("Object type %d is not supported\n", header->e_type);
165
        return EE_UNSUPPORTED;
169
        return EE_UNSUPPORTED;
166
    }
170
    }
-
 
171
 
-
 
172
    /* The run-time dynamic linker is loaded with a bias */
167
    if (header->e_type == ET_DYN) header->e_entry += RTLD_BIAS;
173
    if (header->e_type == ET_DYN)
-
 
174
        elf->bias = RTLD_BIAS;
-
 
175
    else
-
 
176
        elf->bias = 0;
168
 
177
 
169
    printf("parse segments\n");
178
    printf("parse segments\n");
170
 
179
 
171
    /* Walk through all segment headers and process them. */
180
    /* Walk through all segment headers and process them. */
172
    for (i = 0; i < header->e_phnum; i++) {
181
    for (i = 0; i < header->e_phnum; i++) {
-
 
182
        elf_segment_header_t segment_hdr;
173
 
183
 
174
        /* Seek to start of segment header */
184
        /* Seek to start of segment header */
-
 
185
        lseek(elf->fd, header->e_phoff
-
 
186
                + i * sizeof(elf_segment_header_t), SEEK_SET);
-
 
187
 
175
        lseek(fd, header->e_phoff + i * sizeof(elf_segment_header_t),
188
        rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t));
176
            SEEK_SET);
189
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
177
 
190
 
178
        rc = segment_header(fd, header);
191
        rc = segment_header(elf, &segment_hdr);
179
        if (rc != EE_OK)
192
        if (rc != EE_OK)
180
            return rc;
193
            return rc;
181
    }
194
    }
182
 
195
 
183
    printf("parse sections\n");
196
    printf("parse sections\n");
184
 
197
 
185
    /* Inspect all section headers and proccess them. */
198
    /* Inspect all section headers and proccess them. */
186
    for (i = 0; i < header->e_shnum; i++) {
199
    for (i = 0; i < header->e_shnum; i++) {
-
 
200
        elf_section_header_t section_hdr;
187
 
201
 
188
        /* Seek to start of section header */
202
        /* Seek to start of section header */
189
        lseek(fd, header->e_shoff + i * sizeof(elf_section_header_t),
203
        lseek(elf->fd, header->e_shoff
190
            SEEK_SET);
204
            + i * sizeof(elf_section_header_t), SEEK_SET);
191
 
205
 
-
 
206
        rc = read(elf->fd, &section_hdr, sizeof(elf_section_header_t));
-
 
207
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
-
 
208
 
192
        rc = section_header(fd, header);
209
        rc = section_header(elf, &section_hdr);
193
        if (rc != EE_OK)
210
        if (rc != EE_OK)
194
            return rc;
211
            return rc;
195
    }
212
    }
196
 
213
 
-
 
214
    elf->info->entry =
-
 
215
        (entry_point_t)((uint8_t *)header->e_entry + elf->bias);
-
 
216
 
197
    printf("done\n");
217
    printf("done\n");
198
 
218
 
199
    return EE_OK;
219
    return EE_OK;
200
}
220
}
201
 
221
 
Line 217... Line 237...
217
 * @param entry Segment header.
237
 * @param entry Segment header.
218
 * @param elf ELF header.
238
 * @param elf ELF header.
219
 *
239
 *
220
 * @return EE_OK on success, error code otherwise.
240
 * @return EE_OK on success, error code otherwise.
221
 */
241
 */
222
static int segment_header(int fd, elf_header_t *elf)
242
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
223
{
243
{
224
    static elf_segment_header_t entry_buf;
-
 
225
    elf_segment_header_t *entry = &entry_buf;
-
 
226
    int rc;
-
 
227
 
-
 
228
    rc = read(fd, entry, sizeof(elf_segment_header_t));
-
 
229
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }
-
 
230
 
-
 
231
    switch (entry->p_type) {
244
    switch (entry->p_type) {
232
    case PT_NULL:
245
    case PT_NULL:
233
    case PT_PHDR:
246
    case PT_PHDR:
234
        break;
247
        break;
235
    case PT_LOAD:
248
    case PT_LOAD:
236
        return load_segment(fd, entry, elf);
249
        return load_segment(elf, entry);
237
        break;
250
        break;
238
    case PT_DYNAMIC:
251
    case PT_DYNAMIC:
239
    case PT_INTERP:
252
    case PT_INTERP:
240
    case PT_SHLIB:
253
    case PT_SHLIB:
241
    case PT_NOTE:
254
    case PT_NOTE:
Line 254... Line 267...
254
 * @param entry Program header entry describing segment to be loaded.
267
 * @param entry Program header entry describing segment to be loaded.
255
 * @param elf ELF header.
268
 * @param elf ELF header.
256
 *
269
 *
257
 * @return EE_OK on success, error code otherwise.
270
 * @return EE_OK on success, error code otherwise.
258
 */
271
 */
259
int load_segment(int fd, elf_segment_header_t *entry, elf_header_t *elf)
272
int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
260
{
273
{
261
    void *a;
274
    void *a;
262
    int flags = 0;
275
    int flags = 0;
263
    uintptr_t bias;
276
    uintptr_t bias;
264
    int rc;
277
    int rc;
265
 
278
 
266
    printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
279
    printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
267
        entry->p_memsz);
280
        entry->p_memsz);
268
   
281
   
269
    bias = (elf->e_type == ET_DYN) ? RTLD_BIAS : 0;
282
    bias = elf->bias;
270
 
283
 
271
    if (entry->p_align > 1) {
284
    if (entry->p_align > 1) {
272
        if ((entry->p_offset % entry->p_align) !=
285
        if ((entry->p_offset % entry->p_align) !=
273
            (entry->p_vaddr % entry->p_align)) {
286
            (entry->p_vaddr % entry->p_align)) {
274
            printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n",
287
            printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n",
Line 316... Line 329...
316
 
329
 
317
    /*
330
    /*
318
     * Load segment data
331
     * Load segment data
319
     */
332
     */
320
    printf("seek to %d\n", entry->p_offset);
333
    printf("seek to %d\n", entry->p_offset);
321
    rc = lseek(fd, entry->p_offset, SEEK_SET);
334
    rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
322
    if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
335
    if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
323
 
336
 
324
    printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
337
    printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
325
/*  rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
338
/*  rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
326
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
339
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
Line 332... Line 345...
332
 
345
 
333
    while (left > 0) {
346
    while (left > 0) {
334
        now = 4096;
347
        now = 4096;
335
        if (now > left) now=left;
348
        if (now > left) now=left;
336
        printf("read %d...", now);
349
        printf("read %d...", now);
337
        rc = read(fd, dp, now);
350
        rc = read(elf->fd, dp, now);
338
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
351
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
339
        printf("->%d\n", rc);
352
        printf("->%d\n", rc);
340
        left -= now;
353
        left -= now;
341
        dp += now;
354
        dp += now;
342
    }
355
    }
Line 349... Line 362...
349
 * @param entry Segment header.
362
 * @param entry Segment header.
350
 * @param elf ELF header.
363
 * @param elf ELF header.
351
 *
364
 *
352
 * @return EE_OK on success, error code otherwise.
365
 * @return EE_OK on success, error code otherwise.
353
 */
366
 */
354
static int section_header(int fd, elf_header_t *elf)
367
static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
355
{
368
{
356
    static elf_section_header_t entry_buf;
-
 
357
    elf_section_header_t *entry = &entry_buf;
-
 
358
    int rc;
-
 
359
 
-
 
360
    rc = read(fd, entry, sizeof(elf_section_header_t));
-
 
361
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }
-
 
362
 
-
 
363
    switch (entry->sh_type) {
369
    switch (entry->sh_type) {
364
    case SHT_PROGBITS:
370
    case SHT_PROGBITS:
365
        if (entry->sh_flags & SHF_TLS) {
371
        if (entry->sh_flags & SHF_TLS) {
366
            /* .tdata */
372
            /* .tdata */
367
        }
373
        }
Line 370... Line 376...
370
        if (entry->sh_flags & SHF_TLS) {
376
        if (entry->sh_flags & SHF_TLS) {
371
            /* .tbss */
377
            /* .tbss */
372
        }
378
        }
373
        break;
379
        break;
374
    case SHT_DYNAMIC:
380
    case SHT_DYNAMIC:
-
 
381
        elf->info->dynamic =
-
 
382
            (void *)((uint8_t *)entry->sh_addr + elf->bias);
375
        printf("dynamic section found\n");
383
        printf("dynamic section found at 0x%x\n",
-
 
384
            (uintptr_t)elf->info->dynamic);
376
        break;
385
        break;
377
    default:
386
    default:
378
        break;
387
        break;
379
    }
388
    }
380
   
389