Subversion Repositories HelenOS

Rev

Rev 3010 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3010 Rev 3101
1
/*
1
/*
2
 * Copyright (c) 2006 Sergey Bondari
2
 * Copyright (c) 2006 Sergey Bondari
3
 * Copyright (c) 2006 Jakub Jermar
3
 * Copyright (c) 2006 Jakub Jermar
4
 * Copyright (c) 2008 Jiri Svoboda
4
 * Copyright (c) 2008 Jiri Svoboda
5
 * All rights reserved.
5
 * All rights reserved.
6
 *
6
 *
7
 * Redistribution and use in source and binary forms, with or without
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
8
 * modification, are permitted provided that the following conditions
9
 * are met:
9
 * are met:
10
 *
10
 *
11
 * - Redistributions of source code must retain the above copyright
11
 * - Redistributions of source code must retain the above copyright
12
 *   notice, this list of conditions and the following disclaimer.
12
 *   notice, this list of conditions and the following disclaimer.
13
 * - Redistributions in binary form must reproduce the above copyright
13
 * - Redistributions in binary form must reproduce the above copyright
14
 *   notice, this list of conditions and the following disclaimer in the
14
 *   notice, this list of conditions and the following disclaimer in the
15
 *   documentation and/or other materials provided with the distribution.
15
 *   documentation and/or other materials provided with the distribution.
16
 * - The name of the author may not be used to endorse or promote products
16
 * - The name of the author may not be used to endorse or promote products
17
 *   derived from this software without specific prior written permission.
17
 *   derived from this software without specific prior written permission.
18
 *
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 */
29
 */
30
 
30
 
31
/** @addtogroup generic
31
/** @addtogroup generic
32
 * @{
32
 * @{
33
 */
33
 */
34
 
34
 
35
/**
35
/**
36
 * @file
36
 * @file
37
 * @brief   Kernel ELF loader.
37
 * @brief   Userspace ELF loader.
-
 
38
 *
-
 
39
 * This module allows loading ELF binaries (both executables and
-
 
40
 * shared objects) from VFS. The current implementation allocates
-
 
41
 * anonymous memory, fills it with segment data and then adjusts
-
 
42
 * the memory areas' flags to the final value. In the future,
-
 
43
 * the segments will be mapped directly from the file.
38
 */
44
 */
39
 
45
 
40
#include <stdio.h>
46
#include <stdio.h>
41
#include <sys/types.h>
47
#include <sys/types.h>
42
#include <align.h>
48
#include <align.h>
43
#include <assert.h>
49
#include <assert.h>
44
#include <as.h>
50
#include <as.h>
45
#include <unistd.h>
51
#include <unistd.h>
46
#include <fcntl.h>
52
#include <fcntl.h>
47
 
53
 
48
#include "elf.h"
54
#include "elf.h"
49
#include "pcb.h"
55
#include "pcb.h"
50
#include "elf_load.h"
56
#include "elf_load.h"
51
 
57
 
52
static char *error_codes[] = {
58
static char *error_codes[] = {
53
    "no error",
59
    "no error",
54
    "invalid image",
60
    "invalid image",
55
    "address space error",
61
    "address space error",
56
    "incompatible image",
62
    "incompatible image",
57
    "unsupported image type",
63
    "unsupported image type",
58
    "irrecoverable error"
64
    "irrecoverable error"
59
};
65
};
60
 
66
 
61
static unsigned int elf_load(elf_ld_t *elf, size_t so_bias);
67
static unsigned int elf_load(elf_ld_t *elf, size_t so_bias);
62
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
68
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
63
static int section_header(elf_ld_t *elf, elf_section_header_t *entry);
69
static int section_header(elf_ld_t *elf, elf_section_header_t *entry);
64
static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
70
static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
65
 
71
 
-
 
72
/** Load ELF binary from a file.
-
 
73
 *
-
 
74
 * Load an ELF binary from the specified file. If the file is
-
 
75
 * an executable program, it is loaded unbiased. If it is a shared
-
 
76
 * object, it is loaded with the bias @a so_bias. Some information
-
 
77
 * extracted from the binary is stored in a elf_info_t structure
-
 
78
 * pointed to by @a info.
-
 
79
 *
-
 
80
 * @param file_name Path to the ELF file.
-
 
81
 * @param so_bias   Bias to use if the file is a shared object.
-
 
82
 * @param info      Pointer to a structure for storing information
-
 
83
 *          extracted from the binary.
-
 
84
 *
-
 
85
 * @return EOK on success or negative error code.
-
 
86
 */
66
int elf_load_file(char *file_name, size_t so_bias, elf_info_t *info)
87
int elf_load_file(char *file_name, size_t so_bias, elf_info_t *info)
67
{
88
{
68
    elf_ld_t elf;
89
    elf_ld_t elf;
69
 
90
 
70
    int fd;
91
    int fd;
71
    int rc;
92
    int rc;
72
 
93
 
73
    printf("open and read '%s'...\n", file_name);
94
    printf("open and read '%s'...\n", file_name);
74
 
95
 
75
    fd = open(file_name, 0);
96
    fd = open(file_name, O_RDONLY);
76
    if (fd < 0) {
97
    if (fd < 0) {
77
        printf("failed opening file\n");
98
        printf("failed opening file\n");
78
        return -1;
99
        return -1;
79
    }
100
    }
80
 
101
 
81
    elf.fd = fd;
102
    elf.fd = fd;
82
    elf.info = info;
103
    elf.info = info;
83
 
104
 
84
    rc = elf_load(&elf, so_bias);
105
    rc = elf_load(&elf, so_bias);
85
    printf("elf_load() -> %d\n", rc);
106
    printf("elf_load() -> %d\n", rc);
86
 
107
 
87
    close(fd);
108
    close(fd);
88
 
109
 
89
    return rc;
110
    return rc;
90
}
111
}
91
 
112
 
-
 
113
/** Run an ELF executable.
-
 
114
 *
-
 
115
 * Transfers control to the entry point of an ELF executable loaded
-
 
116
 * earlier with elf_load_file(). This function does not return.
-
 
117
 *
-
 
118
 * @param info  Info structure filled earlier by elf_load_file()
-
 
119
 */
92
void elf_run(elf_info_t *info)
120
void elf_run(elf_info_t *info)
93
{
121
{
94
    (*info->entry)();
122
    (*info->entry)();
95
 
123
 
96
    /* not reached */
124
    /* not reached */
97
}
125
}
98
 
126
 
-
 
127
/** Create the program control block (PCB).
-
 
128
 *
-
 
129
 * Create and install the program control block, initialising it
-
 
130
 * with program information from @a info.
-
 
131
 *
-
 
132
 * @param info  Program info structure
-
 
133
 * @return EOK on success or negative error code
-
 
134
 */
99
int elf_create_pcb(elf_info_t *info)
135
int elf_create_pcb(elf_info_t *info)
100
{
136
{
101
    pcb_t *pcb;
137
    pcb_t *pcb;
102
    void *a;
138
    void *a;
103
 
139
 
104
    pcb = __pcb_get();
140
    pcb = __pcb_get();
105
 
141
 
106
    a = as_area_create(pcb, sizeof(pcb_t), AS_AREA_READ | AS_AREA_WRITE);
142
    a = as_area_create(pcb, sizeof(pcb_t), AS_AREA_READ | AS_AREA_WRITE);
107
    if (a == (void *)(-1)) {
143
    if (a == (void *)(-1)) {
108
        printf("elf_create_pcb: memory mapping failed\n");
144
        printf("elf_create_pcb: memory mapping failed\n");
109
        return EE_MEMORY;
145
        return EE_MEMORY;
110
    }
146
    }
111
 
147
 
112
    pcb->entry = info->entry;
148
    pcb->entry = info->entry;
113
    pcb->dynamic = info->dynamic;
149
    pcb->dynamic = info->dynamic;
114
 
150
 
115
    return 0;
151
    return 0;
116
}
152
}
117
 
153
 
118
 
154
 
119
/** ELF loader
155
/** Load an ELF binary.
-
 
156
 *
-
 
157
 * The @a elf structure contains the loader state, including
-
 
158
 * an open file, from which the binary will be loaded,
-
 
159
 * a pointer to the @c info structure etc.
120
 *
160
 *
121
 * @param header Pointer to ELF header in memory
161
 * @param elf       Pointer to loader state buffer.
-
 
162
 * @param so_bias   Bias to use if the file is a shared object.
122
 * @return EE_OK on success
163
 * @return EE_OK on success or EE_xx error code.
123
 */
164
 */
124
static unsigned int elf_load(elf_ld_t *elf, size_t so_bias)
165
static unsigned int elf_load(elf_ld_t *elf, size_t so_bias)
125
{
166
{
126
    elf_header_t header_buf;
167
    elf_header_t header_buf;
127
    elf_header_t *header = &header_buf;
168
    elf_header_t *header = &header_buf;
128
    int i, rc;
169
    int i, rc;
129
 
170
 
130
    rc = read(elf->fd, header, sizeof(elf_header_t));
171
    rc = read(elf->fd, header, sizeof(elf_header_t));
131
    if (rc < 0) {
172
    if (rc < 0) {
132
        printf("read error\n");
173
        printf("read error\n");
133
        return EE_INVALID;
174
        return EE_INVALID;
134
    }
175
    }
135
 
176
 
136
    elf->header = header;
177
    elf->header = header;
137
 
178
 
138
    printf("ELF-load:");
179
    printf("ELF-load:");
139
    /* Identify ELF */
180
    /* Identify ELF */
140
    if (header->e_ident[EI_MAG0] != ELFMAG0 ||
181
    if (header->e_ident[EI_MAG0] != ELFMAG0 ||
141
        header->e_ident[EI_MAG1] != ELFMAG1 ||
182
        header->e_ident[EI_MAG1] != ELFMAG1 ||
142
        header->e_ident[EI_MAG2] != ELFMAG2 ||
183
        header->e_ident[EI_MAG2] != ELFMAG2 ||
143
        header->e_ident[EI_MAG3] != ELFMAG3) {
184
        header->e_ident[EI_MAG3] != ELFMAG3) {
144
        printf("invalid header\n");
185
        printf("invalid header\n");
145
        return EE_INVALID;
186
        return EE_INVALID;
146
    }
187
    }
147
   
188
   
148
    /* Identify ELF compatibility */
189
    /* Identify ELF compatibility */
149
    if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING ||
190
    if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING ||
150
        header->e_machine != ELF_MACHINE ||
191
        header->e_machine != ELF_MACHINE ||
151
        header->e_ident[EI_VERSION] != EV_CURRENT ||
192
        header->e_ident[EI_VERSION] != EV_CURRENT ||
152
        header->e_version != EV_CURRENT ||
193
        header->e_version != EV_CURRENT ||
153
        header->e_ident[EI_CLASS] != ELF_CLASS) {
194
        header->e_ident[EI_CLASS] != ELF_CLASS) {
154
        printf("incompatible data/version/class\n");
195
        printf("incompatible data/version/class\n");
155
        return EE_INCOMPATIBLE;
196
        return EE_INCOMPATIBLE;
156
    }
197
    }
157
 
198
 
158
    if (header->e_phentsize != sizeof(elf_segment_header_t)) {
199
    if (header->e_phentsize != sizeof(elf_segment_header_t)) {
159
        printf("e_phentsize:%d != %d\n", header->e_phentsize,
200
        printf("e_phentsize:%d != %d\n", header->e_phentsize,
160
            sizeof(elf_segment_header_t));
201
            sizeof(elf_segment_header_t));
161
        return EE_INCOMPATIBLE;
202
        return EE_INCOMPATIBLE;
162
    }
203
    }
163
 
204
 
164
    if (header->e_shentsize != sizeof(elf_section_header_t)) {
205
    if (header->e_shentsize != sizeof(elf_section_header_t)) {
165
        printf("e_shentsize:%d != %d\n", header->e_shentsize,
206
        printf("e_shentsize:%d != %d\n", header->e_shentsize,
166
            sizeof(elf_section_header_t));
207
            sizeof(elf_section_header_t));
167
        return EE_INCOMPATIBLE;
208
        return EE_INCOMPATIBLE;
168
    }
209
    }
169
 
210
 
170
    /* Check if the object type is supported. */
211
    /* Check if the object type is supported. */
171
    if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
212
    if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
172
        printf("Object type %d is not supported\n", header->e_type);
213
        printf("Object type %d is not supported\n", header->e_type);
173
        return EE_UNSUPPORTED;
214
        return EE_UNSUPPORTED;
174
    }
215
    }
175
 
216
 
176
    /* Shared objects can be loaded with a bias */
217
    /* Shared objects can be loaded with a bias */
177
    printf("Object type: %d\n", header->e_type);
218
    printf("Object type: %d\n", header->e_type);
178
    if (header->e_type == ET_DYN)
219
    if (header->e_type == ET_DYN)
179
        elf->bias = so_bias;
220
        elf->bias = so_bias;
180
    else
221
    else
181
        elf->bias = 0;
222
        elf->bias = 0;
182
 
223
 
183
    printf("Bias set to 0x%x\n", elf->bias);
224
    printf("Bias set to 0x%x\n", elf->bias);
184
    elf->info->interp = NULL;
225
    elf->info->interp = NULL;
185
    elf->info->dynamic = NULL;
226
    elf->info->dynamic = NULL;
186
 
227
 
187
    printf("parse segments\n");
228
    printf("parse segments\n");
188
 
229
 
189
    /* Walk through all segment headers and process them. */
230
    /* Walk through all segment headers and process them. */
190
    for (i = 0; i < header->e_phnum; i++) {
231
    for (i = 0; i < header->e_phnum; i++) {
191
        elf_segment_header_t segment_hdr;
232
        elf_segment_header_t segment_hdr;
192
 
233
 
193
        /* Seek to start of segment header */
234
        /* Seek to start of segment header */
194
        lseek(elf->fd, header->e_phoff
235
        lseek(elf->fd, header->e_phoff
195
                + i * sizeof(elf_segment_header_t), SEEK_SET);
236
                + i * sizeof(elf_segment_header_t), SEEK_SET);
196
 
237
 
197
        rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t));
238
        rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t));
198
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
239
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
199
 
240
 
200
        rc = segment_header(elf, &segment_hdr);
241
        rc = segment_header(elf, &segment_hdr);
201
        if (rc != EE_OK)
242
        if (rc != EE_OK)
202
            return rc;
243
            return rc;
203
    }
244
    }
204
 
245
 
205
    printf("parse sections\n");
246
    printf("parse sections\n");
206
 
247
 
207
    /* Inspect all section headers and proccess them. */
248
    /* Inspect all section headers and proccess them. */
208
    for (i = 0; i < header->e_shnum; i++) {
249
    for (i = 0; i < header->e_shnum; i++) {
209
        elf_section_header_t section_hdr;
250
        elf_section_header_t section_hdr;
210
 
251
 
211
        /* Seek to start of section header */
252
        /* Seek to start of section header */
212
        lseek(elf->fd, header->e_shoff
253
        lseek(elf->fd, header->e_shoff
213
            + i * sizeof(elf_section_header_t), SEEK_SET);
254
            + i * sizeof(elf_section_header_t), SEEK_SET);
214
 
255
 
215
        rc = read(elf->fd, &section_hdr, sizeof(elf_section_header_t));
256
        rc = read(elf->fd, &section_hdr, sizeof(elf_section_header_t));
216
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
257
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
217
 
258
 
218
        rc = section_header(elf, &section_hdr);
259
        rc = section_header(elf, &section_hdr);
219
        if (rc != EE_OK)
260
        if (rc != EE_OK)
220
            return rc;
261
            return rc;
221
    }
262
    }
222
 
263
 
223
    elf->info->entry =
264
    elf->info->entry =
224
        (entry_point_t)((uint8_t *)header->e_entry + elf->bias);
265
        (entry_point_t)((uint8_t *)header->e_entry + elf->bias);
225
 
266
 
226
    printf("done\n");
267
    printf("done\n");
227
 
268
 
228
    return EE_OK;
269
    return EE_OK;
229
}
270
}
230
 
271
 
231
/** Print error message according to error code.
272
/** Print error message according to error code.
232
 *
273
 *
233
 * @param rc Return code returned by elf_load().
274
 * @param rc Return code returned by elf_load().
234
 *
275
 *
235
 * @return NULL terminated description of error.
276
 * @return NULL terminated description of error.
236
 */
277
 */
237
char *elf_error(unsigned int rc)
278
char *elf_error(unsigned int rc)
238
{
279
{
239
    assert(rc < sizeof(error_codes) / sizeof(char *));
280
    assert(rc < sizeof(error_codes) / sizeof(char *));
240
 
281
 
241
    return error_codes[rc];
282
    return error_codes[rc];
242
}
283
}
243
 
284
 
244
/** Process segment header.
285
/** Process segment header.
245
 *
286
 *
246
 * @param entry Segment header.
287
 * @param entry Segment header.
247
 * @param elf ELF header.
-
 
248
 *
288
 *
249
 * @return EE_OK on success, error code otherwise.
289
 * @return EE_OK on success, error code otherwise.
250
 */
290
 */
251
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
291
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
252
{
292
{
253
    switch (entry->p_type) {
293
    switch (entry->p_type) {
254
    case PT_NULL:
294
    case PT_NULL:
255
    case PT_PHDR:
295
    case PT_PHDR:
256
        break;
296
        break;
257
    case PT_LOAD:
297
    case PT_LOAD:
258
        return load_segment(elf, entry);
298
        return load_segment(elf, entry);
259
        break;
299
        break;
260
    case PT_INTERP:
300
    case PT_INTERP:
261
        /* Assume silently interp == "/rtld.so" */
301
        /* Assume silently interp == "/rtld.so" */
262
        elf->info->interp = "/rtld.so";
302
        elf->info->interp = "/rtld.so";
263
        break;
303
        break;
264
    case PT_DYNAMIC:
304
    case PT_DYNAMIC:
265
    case PT_SHLIB:
305
    case PT_SHLIB:
266
    case PT_NOTE:
306
    case PT_NOTE:
267
    case PT_LOPROC:
307
    case PT_LOPROC:
268
    case PT_HIPROC:
308
    case PT_HIPROC:
269
    default:
309
    default:
270
        printf("segment p_type %d unknown\n", entry->p_type);
310
        printf("segment p_type %d unknown\n", entry->p_type);
271
        return EE_UNSUPPORTED;
311
        return EE_UNSUPPORTED;
272
        break;
312
        break;
273
    }
313
    }
274
    return EE_OK;
314
    return EE_OK;
275
}
315
}
276
 
316
 
277
/** Load segment described by program header entry.
317
/** Load segment described by program header entry.
278
 *
318
 *
-
 
319
 * @param elf   Loader state.
279
 * @param entry Program header entry describing segment to be loaded.
320
 * @param entry Program header entry describing segment to be loaded.
280
 * @param elf ELF header.
-
 
281
 *
321
 *
282
 * @return EE_OK on success, error code otherwise.
322
 * @return EE_OK on success, error code otherwise.
283
 */
323
 */
284
int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
324
int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
285
{
325
{
286
    void *a;
326
    void *a;
287
    int flags = 0;
327
    int flags = 0;
288
    uintptr_t bias;
328
    uintptr_t bias;
289
    uintptr_t base;
329
    uintptr_t base;
290
    size_t mem_sz;
330
    size_t mem_sz;
291
    int rc;
331
    int rc;
292
 
332
 
293
    printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
333
    printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
294
        entry->p_memsz);
334
        entry->p_memsz);
295
   
335
   
296
    bias = elf->bias;
336
    bias = elf->bias;
297
 
337
 
298
    if (entry->p_align > 1) {
338
    if (entry->p_align > 1) {
299
        if ((entry->p_offset % entry->p_align) !=
339
        if ((entry->p_offset % entry->p_align) !=
300
            (entry->p_vaddr % entry->p_align)) {
340
            (entry->p_vaddr % entry->p_align)) {
301
            printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n",
341
            printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n",
302
            entry->p_offset % entry->p_align,
342
            entry->p_offset % entry->p_align,
303
            entry->p_vaddr % entry->p_align
343
            entry->p_vaddr % entry->p_align
304
            );
344
            );
305
            return EE_INVALID;
345
            return EE_INVALID;
306
        }
346
        }
307
    }
347
    }
308
 
348
 
309
    /* Final flags that will be set for the memory area */
349
    /* Final flags that will be set for the memory area */
310
 
350
 
311
    if (entry->p_flags & PF_X)
351
    if (entry->p_flags & PF_X)
312
        flags |= AS_AREA_EXEC;
352
        flags |= AS_AREA_EXEC;
313
    if (entry->p_flags & PF_W)
353
    if (entry->p_flags & PF_W)
314
        flags |= AS_AREA_WRITE;
354
        flags |= AS_AREA_WRITE;
315
    if (entry->p_flags & PF_R)
355
    if (entry->p_flags & PF_R)
316
        flags |= AS_AREA_READ;
356
        flags |= AS_AREA_READ;
317
    flags |= AS_AREA_CACHEABLE;
357
    flags |= AS_AREA_CACHEABLE;
318
   
358
   
319
    base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
359
    base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
320
    mem_sz = entry->p_memsz + (entry->p_vaddr - base);
360
    mem_sz = entry->p_memsz + (entry->p_vaddr - base);
321
 
361
 
322
    printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + bias,
362
    printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + bias,
323
    entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
363
    entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
324
 
364
 
325
    /*
365
    /*
326
     * For the course of loading, the area needs to be readable
366
     * For the course of loading, the area needs to be readable
327
     * and writeable.
367
     * and writeable.
328
     */
368
     */
329
    a = as_area_create((uint8_t *)base + bias,
369
    a = as_area_create((uint8_t *)base + bias,
330
        mem_sz, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
370
        mem_sz, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
331
    if (a == (void *)(-1)) {
371
    if (a == (void *)(-1)) {
332
        printf("memory mapping failed\n");
372
        printf("memory mapping failed\n");
333
        return EE_MEMORY;
373
        return EE_MEMORY;
334
    }
374
    }
335
 
375
 
336
    printf("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
376
    printf("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
337
        entry->p_vaddr+bias, entry->p_memsz, flags, (uintptr_t)a);
377
        entry->p_vaddr+bias, entry->p_memsz, flags, (uintptr_t)a);
338
 
378
 
339
    /*
379
    /*
340
     * Load segment data
380
     * Load segment data
341
     */
381
     */
342
    printf("seek to %d\n", entry->p_offset);
382
    printf("seek to %d\n", entry->p_offset);
343
    rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
383
    rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
344
    if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
384
    if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
345
 
385
 
346
    printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
386
    printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
347
/*  rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
387
/*  rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
348
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
388
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
-
 
389
 
-
 
390
    /* Long reads are not possible yet. Load segment picewise */
-
 
391
 
349
    unsigned left, now;
392
    unsigned left, now;
350
    uint8_t *dp;
393
    uint8_t *dp;
351
 
394
 
352
    left = entry->p_filesz;
395
    left = entry->p_filesz;
353
    dp = (uint8_t *)(entry->p_vaddr + bias);
396
    dp = (uint8_t *)(entry->p_vaddr + bias);
354
 
397
 
355
    while (left > 0) {
398
    while (left > 0) {
356
        now = 16384;
399
        now = 16384;
357
        if (now > left) now=left;
400
        if (now > left) now = left;
-
 
401
 
358
        printf("read %d...", now);
402
        printf("read %d...", now);
359
        rc = read(elf->fd, dp, now);
403
        rc = read(elf->fd, dp, now);
360
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
-
 
361
        printf("->%d\n", rc);
404
        printf("->%d\n", rc);
-
 
405
 
-
 
406
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
-
 
407
 
362
        left -= now;
408
        left -= now;
363
        dp += now;
409
        dp += now;
364
    }
410
    }
365
 
411
 
366
    printf("set area flags to %d\n", flags);
412
    printf("set area flags to %d\n", flags);
367
    rc = as_area_change_flags((uint8_t *)entry->p_vaddr + bias, flags);
413
    rc = as_area_change_flags((uint8_t *)entry->p_vaddr + bias, flags);
368
    if (rc != 0) {
414
    if (rc != 0) {
369
        printf("failed to set memory area flags\n");
415
        printf("failed to set memory area flags\n");
370
        return EE_MEMORY;
416
        return EE_MEMORY;
371
    }
417
    }
372
 
418
 
373
    return EE_OK;
419
    return EE_OK;
374
}
420
}
375
 
421
 
376
/** Process section header.
422
/** Process section header.
377
 *
423
 *
-
 
424
 * @param elf   Loader state.
378
 * @param entry Segment header.
425
 * @param entry Segment header.
379
 * @param elf ELF header.
-
 
380
 *
426
 *
381
 * @return EE_OK on success, error code otherwise.
427
 * @return EE_OK on success, error code otherwise.
382
 */
428
 */
383
static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
429
static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
384
{
430
{
385
    switch (entry->sh_type) {
431
    switch (entry->sh_type) {
386
    case SHT_PROGBITS:
432
    case SHT_PROGBITS:
387
        if (entry->sh_flags & SHF_TLS) {
433
        if (entry->sh_flags & SHF_TLS) {
388
            /* .tdata */
434
            /* .tdata */
389
        }
435
        }
390
        break;
436
        break;
391
    case SHT_NOBITS:
437
    case SHT_NOBITS:
392
        if (entry->sh_flags & SHF_TLS) {
438
        if (entry->sh_flags & SHF_TLS) {
393
            /* .tbss */
439
            /* .tbss */
394
        }
440
        }
395
        break;
441
        break;
396
    case SHT_DYNAMIC:
442
    case SHT_DYNAMIC:
-
 
443
        /* Record pointer to dynamic section into info structure */
397
        elf->info->dynamic =
444
        elf->info->dynamic =
398
            (void *)((uint8_t *)entry->sh_addr + elf->bias);
445
            (void *)((uint8_t *)entry->sh_addr + elf->bias);
399
        printf("dynamic section found at 0x%x\n",
446
        printf("dynamic section found at 0x%x\n",
400
            (uintptr_t)elf->info->dynamic);
447
            (uintptr_t)elf->info->dynamic);
401
        break;
448
        break;
402
    default:
449
    default:
403
        break;
450
        break;
404
    }
451
    }
405
   
452
   
406
    return EE_OK;
453
    return EE_OK;
407
}
454
}
408
 
455
 
409
/** @}
456
/** @}
410
 */
457
 */
411
 
458