~jsvoboda/helenos/initbin

« back to all changes in this revision

Viewing changes to kernel/generic/src/lib/elf.c

  • Committer: Jiri Svoboda
  • Date: 2010-11-17 21:45:46 UTC
  • Revision ID: jiri@wiwaxia-20101117214546-yt46xsohd2zsqn0y
Isolate processing of init binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
 */
38
38
 
39
39
#include <lib/elf.h>
 
40
#include <lib/elfld.h>
40
41
#include <debug.h>
41
42
#include <typedefs.h>
42
43
#include <mm/as.h>
56
57
        "irrecoverable error"
57
58
};
58
59
 
 
60
static int elf_header_check(elf_header_t *);
59
61
static int segment_header(elf_segment_header_t *, elf_header_t *, as_t *,
60
62
    unsigned int);
61
63
static int section_header(elf_section_header_t *, elf_header_t *, as_t *);
72
74
 */
73
75
unsigned int elf_load(elf_header_t *header, as_t *as, unsigned int flags)
74
76
{
 
77
        int rc;
 
78
 
 
79
        rc = elf_header_check(header);
 
80
        if (rc != EE_OK)
 
81
                return rc;
 
82
        
 
83
        /* Check if the ELF image starts on a page boundary */
 
84
        if (ALIGN_UP((uintptr_t) header, PAGE_SIZE) != (uintptr_t) header)
 
85
                return EE_UNSUPPORTED;
 
86
        
 
87
        /* Walk through all segment headers and process them. */
 
88
        elf_half i;
 
89
        for (i = 0; i < header->e_phnum; i++) {
 
90
                elf_segment_header_t *seghdr =
 
91
                    &((elf_segment_header_t *)(((uint8_t *) header) +
 
92
                    header->e_phoff))[i];
 
93
                
 
94
                int rc = segment_header(seghdr, header, as, flags);
 
95
                if (rc != EE_OK)
 
96
                        return rc;
 
97
        }
 
98
        
 
99
        /* Inspect all section headers and proccess them. */
 
100
        for (i = 0; i < header->e_shnum; i++) {
 
101
                elf_section_header_t *sechdr =
 
102
                    &((elf_section_header_t *)(((uint8_t *) header) +
 
103
                    header->e_shoff))[i];
 
104
                
 
105
                int rc = section_header(sechdr, header, as);
 
106
                if (rc != EE_OK)
 
107
                        return rc;
 
108
        }
 
109
        
 
110
        return EE_OK;
 
111
}
 
112
 
 
113
/** Get ELF image type.
 
114
 *
 
115
 * @param image         Pointer to image
 
116
 * @param etype         Place to store type.
 
117
 * @return              EE_OK on success.
 
118
 */
 
119
int elf_get_type(void *image, elf_type_t *etype)
 
120
{
 
121
        elf_header_t *header;
 
122
        int rc;
 
123
 
 
124
        header = (elf_header_t *) image;
 
125
 
 
126
        rc = elf_header_check(header);
 
127
        if (rc != EE_OK)
 
128
                return rc;
 
129
 
 
130
        /* Walk through all segment headers. */
 
131
        elf_half i;
 
132
        for (i = 0; i < header->e_phnum; i++) {
 
133
                elf_segment_header_t *seghdr =
 
134
                    &((elf_segment_header_t *)(((uint8_t *) header) +
 
135
                    header->e_phoff))[i];
 
136
 
 
137
                if (seghdr->p_type == PT_INTERP) {
 
138
                        /* TODO: Check interpreter string */
 
139
                        *etype = etype_loader;
 
140
                        return EE_OK;
 
141
                }
 
142
        }
 
143
 
 
144
        *etype = etype_exec;
 
145
        return EE_OK;
 
146
}
 
147
 
 
148
/** Verify ELF header.
 
149
 *
 
150
 * @param header        ELF header.
 
151
 * @return              EE_OK if valid.
 
152
 */
 
153
static int elf_header_check(elf_header_t *header)
 
154
{
75
155
        /* Identify ELF */
76
156
        if ((header->e_ident[EI_MAG0] != ELFMAG0) ||
77
157
            (header->e_ident[EI_MAG1] != ELFMAG1) ||
96
176
        /* Check if the object type is supported. */
97
177
        if (header->e_type != ET_EXEC)
98
178
                return EE_UNSUPPORTED;
99
 
        
100
 
        /* Check if the ELF image starts on a page boundary */
101
 
        if (ALIGN_UP((uintptr_t) header, PAGE_SIZE) != (uintptr_t) header)
102
 
                return EE_UNSUPPORTED;
103
 
        
104
 
        /* Walk through all segment headers and process them. */
105
 
        elf_half i;
106
 
        for (i = 0; i < header->e_phnum; i++) {
107
 
                elf_segment_header_t *seghdr =
108
 
                    &((elf_segment_header_t *)(((uint8_t *) header) +
109
 
                    header->e_phoff))[i];
110
 
                
111
 
                int rc = segment_header(seghdr, header, as, flags);
112
 
                if (rc != EE_OK)
113
 
                        return rc;
114
 
        }
115
 
        
116
 
        /* Inspect all section headers and proccess them. */
117
 
        for (i = 0; i < header->e_shnum; i++) {
118
 
                elf_section_header_t *sechdr =
119
 
                    &((elf_section_header_t *)(((uint8_t *) header) +
120
 
                    header->e_shoff))[i];
121
 
                
122
 
                int rc = section_header(sechdr, header, as);
123
 
                if (rc != EE_OK)
124
 
                        return rc;
125
 
        }
126
 
        
 
179
 
127
180
        return EE_OK;
128
181
}
129
182