Subversion Repositories HelenOS

Rev

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

Rev 2990 Rev 2992
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,
-
 
160
            sizeof(elf_segment_header_t));
159
        return EE_INCOMPATIBLE;
161
        return EE_INCOMPATIBLE;
-
 
162
    }
160
 
163
 
161
    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,
-
 
166
            sizeof(elf_section_header_t));
162
        return EE_INCOMPATIBLE;
167
        return EE_INCOMPATIBLE;
-
 
168
    }
163
 
169
 
164
    /* Check if the object type is supported. */
170
    /* Check if the object type is supported. */
165
    if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
171
    if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
166
        printf("Object type %d is not supported\n", header->e_type);
172
        printf("Object type %d is not supported\n", header->e_type);
167
        return EE_UNSUPPORTED;
173
        return EE_UNSUPPORTED;
168
    }
174
    }
169
 
175
 
170
    /* Shared objects can be loaded with a bias */
176
    /* Shared objects can be loaded with a bias */
171
    printf("Object type: %d\n", header->e_type);
177
    printf("Object type: %d\n", header->e_type);
172
    if (header->e_type == ET_DYN)
178
    if (header->e_type == ET_DYN)
173
        elf->bias = so_bias;
179
        elf->bias = so_bias;
174
    else
180
    else
175
        elf->bias = 0;
181
        elf->bias = 0;
176
 
182
 
177
    printf("Bias set to 0x%x\n", elf->bias);
183
    printf("Bias set to 0x%x\n", elf->bias);
178
 
184
 
179
    printf("parse segments\n");
185
    printf("parse segments\n");
180
 
186
 
181
    /* Walk through all segment headers and process them. */
187
    /* Walk through all segment headers and process them. */
182
    for (i = 0; i < header->e_phnum; i++) {
188
    for (i = 0; i < header->e_phnum; i++) {
183
        elf_segment_header_t segment_hdr;
189
        elf_segment_header_t segment_hdr;
184
 
190
 
185
        /* Seek to start of segment header */
191
        /* Seek to start of segment header */
186
        lseek(elf->fd, header->e_phoff
192
        lseek(elf->fd, header->e_phoff
187
                + i * sizeof(elf_segment_header_t), SEEK_SET);
193
                + i * sizeof(elf_segment_header_t), SEEK_SET);
188
 
194
 
189
        rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t));
195
        rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t));
190
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
196
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
191
 
197
 
192
        rc = segment_header(elf, &segment_hdr);
198
        rc = segment_header(elf, &segment_hdr);
193
        if (rc != EE_OK)
199
        if (rc != EE_OK)
194
            return rc;
200
            return rc;
195
    }
201
    }
196
 
202
 
197
    printf("parse sections\n");
203
    printf("parse sections\n");
198
 
204
 
199
    /* Inspect all section headers and proccess them. */
205
    /* Inspect all section headers and proccess them. */
200
    for (i = 0; i < header->e_shnum; i++) {
206
    for (i = 0; i < header->e_shnum; i++) {
201
        elf_section_header_t section_hdr;
207
        elf_section_header_t section_hdr;
202
 
208
 
203
        /* Seek to start of section header */
209
        /* Seek to start of section header */
204
        lseek(elf->fd, header->e_shoff
210
        lseek(elf->fd, header->e_shoff
205
            + i * sizeof(elf_section_header_t), SEEK_SET);
211
            + i * sizeof(elf_section_header_t), SEEK_SET);
206
 
212
 
207
        rc = read(elf->fd, &section_hdr, sizeof(elf_section_header_t));
213
        rc = read(elf->fd, &section_hdr, sizeof(elf_section_header_t));
208
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
214
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
209
 
215
 
210
        rc = section_header(elf, &section_hdr);
216
        rc = section_header(elf, &section_hdr);
211
        if (rc != EE_OK)
217
        if (rc != EE_OK)
212
            return rc;
218
            return rc;
213
    }
219
    }
214
 
220
 
215
    elf->info->entry =
221
    elf->info->entry =
216
        (entry_point_t)((uint8_t *)header->e_entry + elf->bias);
222
        (entry_point_t)((uint8_t *)header->e_entry + elf->bias);
217
 
223
 
218
    printf("done\n");
224
    printf("done\n");
219
 
225
 
220
    return EE_OK;
226
    return EE_OK;
221
}
227
}
222
 
228
 
223
/** Print error message according to error code.
229
/** Print error message according to error code.
224
 *
230
 *
225
 * @param rc Return code returned by elf_load().
231
 * @param rc Return code returned by elf_load().
226
 *
232
 *
227
 * @return NULL terminated description of error.
233
 * @return NULL terminated description of error.
228
 */
234
 */
229
char *elf_error(unsigned int rc)
235
char *elf_error(unsigned int rc)
230
{
236
{
231
    assert(rc < sizeof(error_codes) / sizeof(char *));
237
    assert(rc < sizeof(error_codes) / sizeof(char *));
232
 
238
 
233
    return error_codes[rc];
239
    return error_codes[rc];
234
}
240
}
235
 
241
 
236
/** Process segment header.
242
/** Process segment header.
237
 *
243
 *
238
 * @param entry Segment header.
244
 * @param entry Segment header.
239
 * @param elf ELF header.
245
 * @param elf ELF header.
240
 *
246
 *
241
 * @return EE_OK on success, error code otherwise.
247
 * @return EE_OK on success, error code otherwise.
242
 */
248
 */
243
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
249
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
244
{
250
{
245
    switch (entry->p_type) {
251
    switch (entry->p_type) {
246
    case PT_NULL:
252
    case PT_NULL:
247
    case PT_PHDR:
253
    case PT_PHDR:
248
        break;
254
        break;
249
    case PT_LOAD:
255
    case PT_LOAD:
250
        return load_segment(elf, entry);
256
        return load_segment(elf, entry);
251
        break;
257
        break;
252
    case PT_DYNAMIC:
258
    case PT_DYNAMIC:
253
    case PT_INTERP:
259
    case PT_INTERP:
254
    case PT_SHLIB:
260
    case PT_SHLIB:
255
    case PT_NOTE:
261
    case PT_NOTE:
256
    case PT_LOPROC:
262
    case PT_LOPROC:
257
    case PT_HIPROC:
263
    case PT_HIPROC:
258
    default:
264
    default:
259
        printf("segment p_type %d unknown\n", entry->p_type);
265
        printf("segment p_type %d unknown\n", entry->p_type);
260
        return EE_UNSUPPORTED;
266
        return EE_UNSUPPORTED;
261
        break;
267
        break;
262
    }
268
    }
263
    return EE_OK;
269
    return EE_OK;
264
}
270
}
265
 
271
 
266
/** Load segment described by program header entry.
272
/** Load segment described by program header entry.
267
 *
273
 *
268
 * @param entry Program header entry describing segment to be loaded.
274
 * @param entry Program header entry describing segment to be loaded.
269
 * @param elf ELF header.
275
 * @param elf ELF header.
270
 *
276
 *
271
 * @return EE_OK on success, error code otherwise.
277
 * @return EE_OK on success, error code otherwise.
272
 */
278
 */
273
int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
279
int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
274
{
280
{
275
    void *a;
281
    void *a;
276
    int flags = 0;
282
    int flags = 0;
277
    uintptr_t bias;
283
    uintptr_t bias;
278
    int rc;
284
    int rc;
279
 
285
 
280
    printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
286
    printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
281
        entry->p_memsz);
287
        entry->p_memsz);
282
   
288
   
283
    bias = elf->bias;
289
    bias = elf->bias;
284
 
290
 
285
    if (entry->p_align > 1) {
291
    if (entry->p_align > 1) {
286
        if ((entry->p_offset % entry->p_align) !=
292
        if ((entry->p_offset % entry->p_align) !=
287
            (entry->p_vaddr % entry->p_align)) {
293
            (entry->p_vaddr % entry->p_align)) {
288
            printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n",
294
            printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n",
289
            entry->p_offset % entry->p_align,
295
            entry->p_offset % entry->p_align,
290
            entry->p_vaddr % entry->p_align
296
            entry->p_vaddr % entry->p_align
291
            );
297
            );
292
            return EE_INVALID;
298
            return EE_INVALID;
293
        }
299
        }
294
    }
300
    }
295
 
301
 
-
 
302
    /* Final flags that will be set for the memory area */
-
 
303
 
296
    if (entry->p_flags & PF_X)
304
    if (entry->p_flags & PF_X)
297
        flags |= AS_AREA_EXEC;
305
        flags |= AS_AREA_EXEC;
298
    if (entry->p_flags & PF_W)
306
    if (entry->p_flags & PF_W)
299
        flags |= AS_AREA_WRITE;
307
        flags |= AS_AREA_WRITE;
300
    if (entry->p_flags & PF_R)
308
    if (entry->p_flags & PF_R)
301
        flags |= AS_AREA_READ;
309
        flags |= AS_AREA_READ;
302
    flags |= AS_AREA_CACHEABLE;
310
    flags |= AS_AREA_CACHEABLE;
303
 
311
 
304
    /* Final flags for the memory area */
-
 
305
    flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
-
 
306
 
-
 
307
    /*
312
    /*
308
     * Check if the virtual address starts on page boundary.
313
     * Check if the virtual address starts on page boundary.
309
     */
314
     */
310
    if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr) {
315
    if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr) {
311
        printf("align check 2 failed - not page-aligned\n");
316
        printf("align check 2 failed - not page-aligned\n");
312
        printf("vaddr = 0x%x, should be 0x%x\n",
317
        printf("vaddr = 0x%x, should be 0x%x\n",
313
            entry->p_vaddr, ALIGN_UP(entry->p_vaddr, PAGE_SIZE));
318
            entry->p_vaddr, ALIGN_UP(entry->p_vaddr, PAGE_SIZE));
314
        return EE_UNSUPPORTED;
319
        return EE_UNSUPPORTED;
315
    }
320
    }
316
   
321
   
317
    printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + bias,
322
    printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + bias,
318
    entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
323
    entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
319
 
324
 
320
    /*
325
    /*
321
     * For the course of loading, the area needs to be readable
326
     * For the course of loading, the area needs to be readable
322
     * and writeable.
327
     * and writeable.
323
     */
328
     */
324
    a = as_area_create((uint8_t *)entry->p_vaddr + bias,
329
    a = as_area_create((uint8_t *)entry->p_vaddr + bias,
325
        entry->p_memsz, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
330
        entry->p_memsz, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
326
    if (a == (void *)(-1)) {
331
    if (a == (void *)(-1)) {
327
        printf("memory mapping failed\n");
332
        printf("memory mapping failed\n");
328
        return EE_MEMORY;
333
        return EE_MEMORY;
329
    }
334
    }
330
 
335
 
331
    printf("as_area_create(0x%x, 0x%x, %d) -> 0x%x\n",
336
    printf("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
332
        entry->p_vaddr+bias, entry->p_memsz, flags, (unsigned)a);
337
        entry->p_vaddr+bias, entry->p_memsz, flags, (uintptr_t)a);
333
 
338
 
334
    /*
339
    /*
335
     * Load segment data
340
     * Load segment data
336
     */
341
     */
337
    printf("seek to %d\n", entry->p_offset);
342
    printf("seek to %d\n", entry->p_offset);
338
    rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
343
    rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
339
    if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
344
    if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
340
 
345
 
341
    printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
346
    printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
342
/*  rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
347
/*  rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
343
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
348
    if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
344
    unsigned left, now;
349
    unsigned left, now;
345
    uint8_t *dp;
350
    uint8_t *dp;
346
 
351
 
347
    left = entry->p_filesz;
352
    left = entry->p_filesz;
348
    dp = (uint8_t *)(entry->p_vaddr + bias);
353
    dp = (uint8_t *)(entry->p_vaddr + bias);
349
 
354
 
350
    while (left > 0) {
355
    while (left > 0) {
351
        now = 16384;
356
        now = 16384;
352
        if (now > left) now=left;
357
        if (now > left) now=left;
353
        printf("read %d...", now);
358
        printf("read %d...", now);
354
        rc = read(elf->fd, dp, now);
359
        rc = read(elf->fd, dp, now);
355
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
360
        if (rc < 0) { printf("read error\n"); return EE_INVALID; }
356
        printf("->%d\n", rc);
361
        printf("->%d\n", rc);
357
        left -= now;
362
        left -= now;
358
        dp += now;
363
        dp += now;
359
    }
364
    }
360
 
365
 
361
    printf("set area flags to %d\n", flags);
366
    printf("set area flags to %d\n", flags);
362
    rc = as_area_change_flags((uint8_t *)entry->p_vaddr + bias, flags);
367
    rc = as_area_change_flags((uint8_t *)entry->p_vaddr + bias, flags);
363
    if (rc != 0) {
368
    if (rc != 0) {
364
        printf("failed to set memory area flags\n");
369
        printf("failed to set memory area flags\n");
365
        return EE_MEMORY;
370
        return EE_MEMORY;
366
    }
371
    }
367
 
372
 
368
    return EE_OK;
373
    return EE_OK;
369
}
374
}
370
 
375
 
371
/** Process section header.
376
/** Process section header.
372
 *
377
 *
373
 * @param entry Segment header.
378
 * @param entry Segment header.
374
 * @param elf ELF header.
379
 * @param elf ELF header.
375
 *
380
 *
376
 * @return EE_OK on success, error code otherwise.
381
 * @return EE_OK on success, error code otherwise.
377
 */
382
 */
378
static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
383
static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
379
{
384
{
380
    switch (entry->sh_type) {
385
    switch (entry->sh_type) {
381
    case SHT_PROGBITS:
386
    case SHT_PROGBITS:
382
        if (entry->sh_flags & SHF_TLS) {
387
        if (entry->sh_flags & SHF_TLS) {
383
            /* .tdata */
388
            /* .tdata */
384
        }
389
        }
385
        break;
390
        break;
386
    case SHT_NOBITS:
391
    case SHT_NOBITS:
387
        if (entry->sh_flags & SHF_TLS) {
392
        if (entry->sh_flags & SHF_TLS) {
388
            /* .tbss */
393
            /* .tbss */
389
        }
394
        }
390
        break;
395
        break;
391
    case SHT_DYNAMIC:
396
    case SHT_DYNAMIC:
392
        elf->info->dynamic =
397
        elf->info->dynamic =
393
            (void *)((uint8_t *)entry->sh_addr + elf->bias);
398
            (void *)((uint8_t *)entry->sh_addr + elf->bias);
394
        printf("dynamic section found at 0x%x\n",
399
        printf("dynamic section found at 0x%x\n",
395
            (uintptr_t)elf->info->dynamic);
400
            (uintptr_t)elf->info->dynamic);
396
        break;
401
        break;
397
    default:
402
    default:
398
        break;
403
        break;
399
    }
404
    }
400
   
405
   
401
    return EE_OK;
406
    return EE_OK;
402
}
407
}
403
 
408
 
404
/** @}
409
/** @}
405
 */
410
 */
406
 
411