Subversion Repositories HelenOS

Rev

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

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