Subversion Repositories HelenOS

Rev

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

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