Subversion Repositories HelenOS

Rev

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

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