Subversion Repositories HelenOS

Rev

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

Rev 2996 Rev 3004
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   Kernel ELF loader.
38
 */
38
 */
39
 
39
 
40
#include <stdio.h>
40
#include <stdio.h>
41
#include <sys/types.h>
41
#include <sys/types.h>
42
#include <align.h>
42
#include <align.h>
43
#include <assert.h>
43
#include <assert.h>
44
#include <as.h>
44
#include <as.h>
45
#include <unistd.h>
45
#include <unistd.h>
46
#include <fcntl.h>
46
#include <fcntl.h>
47
 
47
 
48
#include "elf.h"
48
#include "elf.h"
49
#include "pcb.h"
49
#include "pcb.h"
50
#include "elf_load.h"
50
#include "elf_load.h"
51
 
51
 
52
static char *error_codes[] = {
52
static char *error_codes[] = {
53
    "no error",
53
    "no error",
54
    "invalid image",
54
    "invalid image",
55
    "address space error",
55
    "address space error",
56
    "incompatible image",
56
    "incompatible image",
57
    "unsupported image type",
57
    "unsupported image type",
58
    "irrecoverable error"
58
    "irrecoverable error"
59
};
59
};
60
 
60
 
61
static unsigned int elf_load(elf_ld_t *elf, size_t so_bias);
61
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);
62
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);
63
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);
64
static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
65
 
65
 
66
int elf_load_file(char *file_name, size_t so_bias, elf_info_t *info)
66
int elf_load_file(char *file_name, size_t so_bias, elf_info_t *info)
67
{
67
{
68
    elf_ld_t elf;
68
    elf_ld_t elf;
69
 
69
 
70
    int fd;
70
    int fd;
71
    int rc;
71
    int rc;
72
 
72
 
73
    printf("open and read '%s'...\n", file_name);
73
    printf("open and read '%s'...\n", file_name);
74
 
74
 
75
    fd = open(file_name, 0);
75
    fd = open(file_name, 0);
76
    if (fd < 0) {
76
    if (fd < 0) {
77
        printf("failed opening file\n");
77
        printf("failed opening file\n");
78
        return -1;
78
        return -1;
79
    }
79
    }
80
 
80
 
81
    elf.fd = fd;
81
    elf.fd = fd;
82
    elf.info = info;
82
    elf.info = info;
83
 
83
 
84
    rc = elf_load(&elf, so_bias);
84
    rc = elf_load(&elf, so_bias);
85
    printf("elf_load() -> %d\n", rc);
85
    printf("elf_load() -> %d\n", rc);
86
 
86
 
87
    close(fd);
87
    close(fd);
88
 
88
 
89
    return rc;
89
    return rc;
90
}
90
}
91
 
91
 
92
void elf_run(elf_info_t *info)
92
void elf_run(elf_info_t *info)
93
{
93
{
94
    (*info->entry)();
94
    (*info->entry)();
95
 
95
 
96
    /* not reached */
96
    /* not reached */
97
}
97
}
98
 
98
 
99
int elf_create_pcb(elf_info_t *info)
99
int elf_create_pcb(elf_info_t *info)
100
{
100
{
101
    pcb_t *pcb;
101
    pcb_t *pcb;
102
    void *a;
102
    void *a;
103
 
103
 
104
    pcb = __pcb_get();
104
    pcb = __pcb_get();
105
 
105
 
106
    a = as_area_create(pcb, sizeof(pcb_t), AS_AREA_READ | AS_AREA_WRITE);
106
    a = as_area_create(pcb, sizeof(pcb_t), AS_AREA_READ | AS_AREA_WRITE);
107
    if (a == (void *)(-1)) {
107
    if (a == (void *)(-1)) {
108
        printf("elf_create_pcb: memory mapping failed\n");
108
        printf("elf_create_pcb: memory mapping failed\n");
109
        return EE_MEMORY;
109
        return EE_MEMORY;
110
    }
110
    }
111
 
111
 
112
    pcb->entry = info->entry;
112
    pcb->entry = info->entry;
113
    pcb->dynamic = info->dynamic;
113
    pcb->dynamic = info->dynamic;
114
 
114
 
115
    return 0;
115
    return 0;
116
}
116
}
117
 
117
 
118
 
118
 
119
/** ELF loader
119
/** ELF loader
120
 *
120
 *
121
 * @param header Pointer to ELF header in memory
121
 * @param header Pointer to ELF header in memory
122
 * @return EE_OK on success
122
 * @return EE_OK on success
123
 */
123
 */
124
static unsigned int elf_load(elf_ld_t *elf, size_t so_bias)
124
static unsigned int elf_load(elf_ld_t *elf, size_t so_bias)
125
{
125
{
126
    elf_header_t header_buf;
126
    elf_header_t header_buf;
127
    elf_header_t *header = &header_buf;
127
    elf_header_t *header = &header_buf;
128
    int i, rc;
128
    int i, rc;
129
 
129
 
130
    rc = read(elf->fd, header, sizeof(elf_header_t));
130
    rc = read(elf->fd, header, sizeof(elf_header_t));
131
    if (rc < 0) {
131
    if (rc < 0) {
132
        printf("read error\n");
132
        printf("read error\n");
133
        return EE_INVALID;
133
        return EE_INVALID;
134
    }
134
    }
135
 
135
 
136
    elf->header = header;
136
    elf->header = header;
137
 
137
 
138
    printf("ELF-load:");
138
    printf("ELF-load:");
139
    /* Identify ELF */
139
    /* Identify ELF */
140
    if (header->e_ident[EI_MAG0] != ELFMAG0 ||
140
    if (header->e_ident[EI_MAG0] != ELFMAG0 ||
141
        header->e_ident[EI_MAG1] != ELFMAG1 ||
141
        header->e_ident[EI_MAG1] != ELFMAG1 ||
142
        header->e_ident[EI_MAG2] != ELFMAG2 ||
142
        header->e_ident[EI_MAG2] != ELFMAG2 ||
143
        header->e_ident[EI_MAG3] != ELFMAG3) {
143
        header->e_ident[EI_MAG3] != ELFMAG3) {
144
        printf("invalid header\n");
144
        printf("invalid header\n");
145
        return EE_INVALID;
145
        return EE_INVALID;
146
    }
146
    }
147
   
147
   
148
    /* Identify ELF compatibility */
148
    /* Identify ELF compatibility */
149
    if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING ||
149
    if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING ||
150
        header->e_machine != ELF_MACHINE ||
150
        header->e_machine != ELF_MACHINE ||
151
        header->e_ident[EI_VERSION] != EV_CURRENT ||
151
        header->e_ident[EI_VERSION] != EV_CURRENT ||
152
        header->e_version != EV_CURRENT ||
152
        header->e_version != EV_CURRENT ||
153
        header->e_ident[EI_CLASS] != ELF_CLASS) {
153
        header->e_ident[EI_CLASS] != ELF_CLASS) {
154
        printf("incompatible data/version/class\n");
154
        printf("incompatible data/version/class\n");
155
        return EE_INCOMPATIBLE;
155
        return EE_INCOMPATIBLE;
156
    }
156
    }
157
 
157
 
158
    if (header->e_phentsize != sizeof(elf_segment_header_t)) {
158
    if (header->e_phentsize != sizeof(elf_segment_header_t)) {
159
        printf("e_phentsize:%d != %d\n", header->e_phentsize,
159
        printf("e_phentsize:%d != %d\n", header->e_phentsize,
160
            sizeof(elf_segment_header_t));
160
            sizeof(elf_segment_header_t));
161
        return EE_INCOMPATIBLE;
161
        return EE_INCOMPATIBLE;
162
    }
162
    }
163
 
163
 
164
    if (header->e_shentsize != sizeof(elf_section_header_t)) {
164
    if (header->e_shentsize != sizeof(elf_section_header_t)) {
165
        printf("e_shentsize:%d != %d\n", header->e_shentsize,
165
        printf("e_shentsize:%d != %d\n", header->e_shentsize,
166
            sizeof(elf_section_header_t));
166
            sizeof(elf_section_header_t));
167
        return EE_INCOMPATIBLE;
167
        return EE_INCOMPATIBLE;
168
    }
168
    }
169
 
169
 
170
    /* Check if the object type is supported. */
170
    /* Check if the object type is supported. */
171
    if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
171
    if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
172
        printf("Object type %d is not supported\n", header->e_type);
172
        printf("Object type %d is not supported\n", header->e_type);
173
        return EE_UNSUPPORTED;
173
        return EE_UNSUPPORTED;
174
    }
174
    }
175
 
175
 
176
    /* Shared objects can be loaded with a bias */
176
    /* Shared objects can be loaded with a bias */
177
    printf("Object type: %d\n", header->e_type);
177
    printf("Object type: %d\n", header->e_type);
178
    if (header->e_type == ET_DYN)
178
    if (header->e_type == ET_DYN)
179
        elf->bias = so_bias;
179
        elf->bias = so_bias;
180
    else
180
    else
181
        elf->bias = 0;
181
        elf->bias = 0;
182
 
182
 
183
    printf("Bias set to 0x%x\n", elf->bias);
183
    printf("Bias set to 0x%x\n", elf->bias);
-
 
184
    elf->info->interp = NULL;
-
 
185
    elf->info->dynamic = NULL;
184
 
186
 
185
    printf("parse segments\n");
187
    printf("parse segments\n");
186
 
188
 
187
    /* Walk through all segment headers and process them. */
189
    /* Walk through all segment headers and process them. */
188
    for (i = 0; i < header->e_phnum; i++) {
190
    for (i = 0; i < header->e_phnum; i++) {
189
        elf_segment_header_t segment_hdr;
191
        elf_segment_header_t segment_hdr;
190
 
192
 
191
        /* Seek to start of segment header */
193
        /* Seek to start of segment header */
192
        lseek(elf->fd, header->e_phoff
194
        lseek(elf->fd, header->e_phoff
193
                + i * sizeof(elf_segment_header_t), SEEK_SET);
195
                + i * sizeof(elf_segment_header_t), SEEK_SET);
194
 
196
 
195
        rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t));
197
        rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t));
196
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
198
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
197
 
199
 
198
        rc = segment_header(elf, &segment_hdr);
200
        rc = segment_header(elf, &segment_hdr);
199
        if (rc != EE_OK)
201
        if (rc != EE_OK)
200
            return rc;
202
            return rc;
201
    }
203
    }
202
 
204
 
203
    printf("parse sections\n");
205
    printf("parse sections\n");
204
    elf->info->dynamic = NULL;
-
 
205
 
206
 
206
    /* Inspect all section headers and proccess them. */
207
    /* Inspect all section headers and proccess them. */
207
    for (i = 0; i < header->e_shnum; i++) {
208
    for (i = 0; i < header->e_shnum; i++) {
208
        elf_section_header_t section_hdr;
209
        elf_section_header_t section_hdr;
209
 
210
 
210
        /* Seek to start of section header */
211
        /* Seek to start of section header */
211
        lseek(elf->fd, header->e_shoff
212
        lseek(elf->fd, header->e_shoff
212
            + i * sizeof(elf_section_header_t), SEEK_SET);
213
            + i * sizeof(elf_section_header_t), SEEK_SET);
213
 
214
 
214
        rc = read(elf->fd, &section_hdr, sizeof(elf_section_header_t));
215
        rc = read(elf->fd, &section_hdr, sizeof(elf_section_header_t));
215
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
216
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
216
 
217
 
217
        rc = section_header(elf, &section_hdr);
218
        rc = section_header(elf, &section_hdr);
218
        if (rc != EE_OK)
219
        if (rc != EE_OK)
219
            return rc;
220
            return rc;
220
    }
221
    }
221
 
222
 
222
    elf->info->entry =
223
    elf->info->entry =
223
        (entry_point_t)((uint8_t *)header->e_entry + elf->bias);
224
        (entry_point_t)((uint8_t *)header->e_entry + elf->bias);
224
 
225
 
225
    printf("done\n");
226
    printf("done\n");
226
 
227
 
227
    return EE_OK;
228
    return EE_OK;
228
}
229
}
229
 
230
 
230
/** Print error message according to error code.
231
/** Print error message according to error code.
231
 *
232
 *
232
 * @param rc Return code returned by elf_load().
233
 * @param rc Return code returned by elf_load().
233
 *
234
 *
234
 * @return NULL terminated description of error.
235
 * @return NULL terminated description of error.
235
 */
236
 */
236
char *elf_error(unsigned int rc)
237
char *elf_error(unsigned int rc)
237
{
238
{
238
    assert(rc < sizeof(error_codes) / sizeof(char *));
239
    assert(rc < sizeof(error_codes) / sizeof(char *));
239
 
240
 
240
    return error_codes[rc];
241
    return error_codes[rc];
241
}
242
}
242
 
243
 
243
/** Process segment header.
244
/** Process segment header.
244
 *
245
 *
245
 * @param entry Segment header.
246
 * @param entry Segment header.
246
 * @param elf ELF header.
247
 * @param elf ELF header.
247
 *
248
 *
248
 * @return EE_OK on success, error code otherwise.
249
 * @return EE_OK on success, error code otherwise.
249
 */
250
 */
250
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
251
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
251
{
252
{
252
    switch (entry->p_type) {
253
    switch (entry->p_type) {
253
    case PT_NULL:
254
    case PT_NULL:
254
    case PT_PHDR:
255
    case PT_PHDR:
255
        break;
256
        break;
256
    case PT_LOAD:
257
    case PT_LOAD:
257
        return load_segment(elf, entry);
258
        return load_segment(elf, entry);
258
        break;
259
        break;
259
    case PT_DYNAMIC:
-
 
260
    case PT_INTERP:
260
    case PT_INTERP:
-
 
261
        /* Assume silently interp == "/rtld.so" */
-
 
262
        elf->info->interp = "/rtld.so";
-
 
263
        break;
-
 
264
    case PT_DYNAMIC:
261
    case PT_SHLIB:
265
    case PT_SHLIB:
262
    case PT_NOTE:
266
    case PT_NOTE:
263
    case PT_LOPROC:
267
    case PT_LOPROC:
264
    case PT_HIPROC:
268
    case PT_HIPROC:
265
    default:
269
    default:
266
        printf("segment p_type %d unknown\n", entry->p_type);
270
        printf("segment p_type %d unknown\n", entry->p_type);
267
        return EE_UNSUPPORTED;
271
        return EE_UNSUPPORTED;
268
        break;
272
        break;
269
    }
273
    }
270
    return EE_OK;
274
    return EE_OK;
271
}
275
}
272
 
276
 
273
/** Load segment described by program header entry.
277
/** Load segment described by program header entry.
274
 *
278
 *
275
 * @param entry Program header entry describing segment to be loaded.
279
 * @param entry Program header entry describing segment to be loaded.
276
 * @param elf ELF header.
280
 * @param elf ELF header.
277
 *
281
 *
278
 * @return EE_OK on success, error code otherwise.
282
 * @return EE_OK on success, error code otherwise.
279
 */
283
 */
280
int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
284
int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
281
{
285
{
282
    void *a;
286
    void *a;
283
    int flags = 0;
287
    int flags = 0;
284
    uintptr_t bias;
288
    uintptr_t bias;
285
    int rc;
289
    int rc;
286
 
290
 
287
    printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
291
    printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
288
        entry->p_memsz);
292
        entry->p_memsz);
289
   
293
   
290
    bias = elf->bias;
294
    bias = elf->bias;
291
 
295
 
292
    if (entry->p_align > 1) {
296
    if (entry->p_align > 1) {
293
        if ((entry->p_offset % entry->p_align) !=
297
        if ((entry->p_offset % entry->p_align) !=
294
            (entry->p_vaddr % entry->p_align)) {
298
            (entry->p_vaddr % entry->p_align)) {
295
            printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n",
299
            printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n",
296
            entry->p_offset % entry->p_align,
300
            entry->p_offset % entry->p_align,
297
            entry->p_vaddr % entry->p_align
301
            entry->p_vaddr % entry->p_align
298
            );
302
            );
299
            return EE_INVALID;
303
            return EE_INVALID;
300
        }
304
        }
301
    }
305
    }
302
 
306
 
303
    /* Final flags that will be set for the memory area */
307
    /* Final flags that will be set for the memory area */
304
 
308
 
305
    if (entry->p_flags & PF_X)
309
    if (entry->p_flags & PF_X)
306
        flags |= AS_AREA_EXEC;
310
        flags |= AS_AREA_EXEC;
307
    if (entry->p_flags & PF_W)
311
    if (entry->p_flags & PF_W)
308
        flags |= AS_AREA_WRITE;
312
        flags |= AS_AREA_WRITE;
309
    if (entry->p_flags & PF_R)
313
    if (entry->p_flags & PF_R)
310
        flags |= AS_AREA_READ;
314
        flags |= AS_AREA_READ;
311
    flags |= AS_AREA_CACHEABLE;
315
    flags |= AS_AREA_CACHEABLE;
312
 
316
 
313
    /*
317
    /*
314
     * Check if the virtual address starts on page boundary.
318
     * Check if the virtual address starts on page boundary.
315
     */
319
     */
316
    if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr) {
320
    if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr) {
317
        printf("align check 2 failed - not page-aligned\n");
321
        printf("align check 2 failed - not page-aligned\n");
318
        printf("vaddr = 0x%x, should be 0x%x\n",
322
        printf("vaddr = 0x%x, should be 0x%x\n",
319
            entry->p_vaddr, ALIGN_UP(entry->p_vaddr, PAGE_SIZE));
323
            entry->p_vaddr, ALIGN_UP(entry->p_vaddr, PAGE_SIZE));
320
        return EE_UNSUPPORTED;
324
        return EE_UNSUPPORTED;
321
    }
325
    }
322
   
326
   
323
    printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + bias,
327
    printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + bias,
324
    entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
328
    entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
325
 
329
 
326
    /*
330
    /*
327
     * For the course of loading, the area needs to be readable
331
     * For the course of loading, the area needs to be readable
328
     * and writeable.
332
     * and writeable.
329
     */
333
     */
330
    a = as_area_create((uint8_t *)entry->p_vaddr + bias,
334
    a = as_area_create((uint8_t *)entry->p_vaddr + bias,
331
        entry->p_memsz, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
335
        entry->p_memsz, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
332
    if (a == (void *)(-1)) {
336
    if (a == (void *)(-1)) {
333
        printf("memory mapping failed\n");
337
        printf("memory mapping failed\n");
334
        return EE_MEMORY;
338
        return EE_MEMORY;
335
    }
339
    }
336
 
340
 
337
    printf("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
341
    printf("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
338
        entry->p_vaddr+bias, entry->p_memsz, flags, (uintptr_t)a);
342
        entry->p_vaddr+bias, entry->p_memsz, flags, (uintptr_t)a);
339
 
343
 
340
    /*
344
    /*
341
     * Load segment data
345
     * Load segment data
342
     */
346
     */
343
    printf("seek to %d\n", entry->p_offset);
347
    printf("seek to %d\n", entry->p_offset);
344
    rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
348
    rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
345
    if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
349
    if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
346
 
350
 
347
    printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
351
    printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
348
/*  rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
352
/*  rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
349
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
353
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
350
    unsigned left, now;
354
    unsigned left, now;
351
    uint8_t *dp;
355
    uint8_t *dp;
352
 
356
 
353
    left = entry->p_filesz;
357
    left = entry->p_filesz;
354
    dp = (uint8_t *)(entry->p_vaddr + bias);
358
    dp = (uint8_t *)(entry->p_vaddr + bias);
355
 
359
 
356
    while (left > 0) {
360
    while (left > 0) {
357
        now = 16384;
361
        now = 16384;
358
        if (now > left) now=left;
362
        if (now > left) now=left;
359
        printf("read %d...", now);
363
        printf("read %d...", now);
360
        rc = read(elf->fd, dp, now);
364
        rc = read(elf->fd, dp, now);
361
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
365
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
362
        printf("->%d\n", rc);
366
        printf("->%d\n", rc);
363
        left -= now;
367
        left -= now;
364
        dp += now;
368
        dp += now;
365
    }
369
    }
366
 
370
 
367
    printf("set area flags to %d\n", flags);
371
    printf("set area flags to %d\n", flags);
368
    rc = as_area_change_flags((uint8_t *)entry->p_vaddr + bias, flags);
372
    rc = as_area_change_flags((uint8_t *)entry->p_vaddr + bias, flags);
369
    if (rc != 0) {
373
    if (rc != 0) {
370
        printf("failed to set memory area flags\n");
374
        printf("failed to set memory area flags\n");
371
        return EE_MEMORY;
375
        return EE_MEMORY;
372
    }
376
    }
373
 
377
 
374
    return EE_OK;
378
    return EE_OK;
375
}
379
}
376
 
380
 
377
/** Process section header.
381
/** Process section header.
378
 *
382
 *
379
 * @param entry Segment header.
383
 * @param entry Segment header.
380
 * @param elf ELF header.
384
 * @param elf ELF header.
381
 *
385
 *
382
 * @return EE_OK on success, error code otherwise.
386
 * @return EE_OK on success, error code otherwise.
383
 */
387
 */
384
static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
388
static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
385
{
389
{
386
    switch (entry->sh_type) {
390
    switch (entry->sh_type) {
387
    case SHT_PROGBITS:
391
    case SHT_PROGBITS:
388
        if (entry->sh_flags & SHF_TLS) {
392
        if (entry->sh_flags & SHF_TLS) {
389
            /* .tdata */
393
            /* .tdata */
390
        }
394
        }
391
        break;
395
        break;
392
    case SHT_NOBITS:
396
    case SHT_NOBITS:
393
        if (entry->sh_flags & SHF_TLS) {
397
        if (entry->sh_flags & SHF_TLS) {
394
            /* .tbss */
398
            /* .tbss */
395
        }
399
        }
396
        break;
400
        break;
397
    case SHT_DYNAMIC:
401
    case SHT_DYNAMIC:
398
        elf->info->dynamic =
402
        elf->info->dynamic =
399
            (void *)((uint8_t *)entry->sh_addr + elf->bias);
403
            (void *)((uint8_t *)entry->sh_addr + elf->bias);
400
        printf("dynamic section found at 0x%x\n",
404
        printf("dynamic section found at 0x%x\n",
401
            (uintptr_t)elf->info->dynamic);
405
            (uintptr_t)elf->info->dynamic);
402
        break;
406
        break;
403
    default:
407
    default:
404
        break;
408
        break;
405
    }
409
    }
406
   
410
   
407
    return EE_OK;
411
    return EE_OK;
408
}
412
}
409
 
413
 
410
/** @}
414
/** @}
411
 */
415
 */
412
 
416