Subversion Repositories HelenOS

Rev

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

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