Subversion Repositories HelenOS

Rev

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

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