Subversion Repositories HelenOS

Rev

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

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