Subversion Repositories HelenOS

Rev

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

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