Subversion Repositories HelenOS

Rev

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

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