Subversion Repositories HelenOS

Rev

Rev 2089 | Rev 2745 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2089 Rev 2574
Line 54... Line 54...
54
    "incompatible image",
54
    "incompatible image",
55
    "unsupported image type",
55
    "unsupported image type",
56
    "irrecoverable error"
56
    "irrecoverable error"
57
};
57
};
58
 
58
 
59
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, as_t *as);
59
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
-
 
60
    as_t *as);
60
static int section_header(elf_section_header_t *entry, elf_header_t *elf, as_t *as);
61
static int section_header(elf_section_header_t *entry, elf_header_t *elf,
-
 
62
    as_t *as);
61
static int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as);
63
static int load_segment(elf_segment_header_t *entry, elf_header_t *elf,
-
 
64
    as_t *as);
62
 
65
 
63
/** ELF loader
66
/** ELF loader
64
 *
67
 *
65
 * @param header Pointer to ELF header in memory
68
 * @param header Pointer to ELF header in memory
66
 * @param as Created and properly mapped address space
69
 * @param as Created and properly mapped address space
Line 69... Line 72...
69
int elf_load(elf_header_t *header, as_t * as)
72
int elf_load(elf_header_t *header, as_t * as)
70
{
73
{
71
    int i, rc;
74
    int i, rc;
72
 
75
 
73
    /* Identify ELF */
76
    /* Identify ELF */
-
 
77
    if (header->e_ident[EI_MAG0] != ELFMAG0 ||
74
    if (header->e_ident[EI_MAG0] != ELFMAG0 || header->e_ident[EI_MAG1] != ELFMAG1 ||
78
        header->e_ident[EI_MAG1] != ELFMAG1 ||
75
        header->e_ident[EI_MAG2] != ELFMAG2 || header->e_ident[EI_MAG3] != ELFMAG3) {
79
        header->e_ident[EI_MAG2] != ELFMAG2 ||
-
 
80
        header->e_ident[EI_MAG3] != ELFMAG3) {
76
        return EE_INVALID;
81
        return EE_INVALID;
77
    }
82
    }
78
   
83
   
79
    /* Identify ELF compatibility */
84
    /* Identify ELF compatibility */
80
    if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING || header->e_machine != ELF_MACHINE ||
85
    if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING ||
-
 
86
        header->e_machine != ELF_MACHINE ||
81
        header->e_ident[EI_VERSION] != EV_CURRENT || header->e_version != EV_CURRENT ||
87
        header->e_ident[EI_VERSION] != EV_CURRENT ||
-
 
88
        header->e_version != EV_CURRENT ||
82
        header->e_ident[EI_CLASS] != ELF_CLASS) {
89
        header->e_ident[EI_CLASS] != ELF_CLASS) {
83
        return EE_INCOMPATIBLE;
90
        return EE_INCOMPATIBLE;
84
    }
91
    }
85
 
92
 
86
    if (header->e_phentsize != sizeof(elf_segment_header_t))
93
    if (header->e_phentsize != sizeof(elf_segment_header_t))
Line 93... Line 100...
93
    if (header->e_type != ET_EXEC)
100
    if (header->e_type != ET_EXEC)
94
        return EE_UNSUPPORTED;
101
        return EE_UNSUPPORTED;
95
 
102
 
96
    /* Walk through all segment headers and process them. */
103
    /* Walk through all segment headers and process them. */
97
    for (i = 0; i < header->e_phnum; i++) {
104
    for (i = 0; i < header->e_phnum; i++) {
-
 
105
        elf_segment_header_t *seghdr;
-
 
106
 
98
        rc = segment_header(&((elf_segment_header_t *)(((uint8_t *) header) + header->e_phoff))[i], header, as);
107
        seghdr = &((elf_segment_header_t *)(((uint8_t *) header) +
-
 
108
            header->e_phoff))[i];
-
 
109
        rc = segment_header(seghdr, header, as);
99
        if (rc != EE_OK)
110
        if (rc != EE_OK)
100
            return rc;
111
            return rc;
101
    }
112
    }
102
 
113
 
103
    /* Inspect all section headers and proccess them. */
114
    /* Inspect all section headers and proccess them. */
104
    for (i = 0; i < header->e_shnum; i++) {
115
    for (i = 0; i < header->e_shnum; i++) {
-
 
116
        elf_section_header_t *sechdr;
-
 
117
 
105
        rc = section_header(&((elf_section_header_t *)(((uint8_t *) header) + header->e_shoff))[i], header, as);
118
        sechdr = &((elf_section_header_t *)(((uint8_t *) header) +
-
 
119
            header->e_shoff))[i];
-
 
120
        rc = section_header(sechdr, header, as);
106
        if (rc != EE_OK)
121
        if (rc != EE_OK)
107
            return rc;
122
            return rc;
108
    }
123
    }
109
 
124
 
110
    return EE_OK;
125
    return EE_OK;
Line 116... Line 131...
116
 *
131
 *
117
 * @return NULL terminated description of error.
132
 * @return NULL terminated description of error.
118
 */
133
 */
119
char *elf_error(int rc)
134
char *elf_error(int rc)
120
{
135
{
121
    ASSERT(rc < sizeof(error_codes)/sizeof(char *));
136
    ASSERT(rc < sizeof(error_codes) / sizeof(char *));
122
 
137
 
123
    return error_codes[rc];
138
    return error_codes[rc];
124
}
139
}
125
 
140
 
126
/** Process segment header.
141
/** Process segment header.
Line 129... Line 144...
129
 * @param elf ELF header.
144
 * @param elf ELF header.
130
 * @param as Address space into wich the ELF is being loaded.
145
 * @param as Address space into wich the ELF is being loaded.
131
 *
146
 *
132
 * @return EE_OK on success, error code otherwise.
147
 * @return EE_OK on success, error code otherwise.
133
 */
148
 */
134
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
149
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
-
 
150
    as_t *as)
135
{
151
{
136
    switch (entry->p_type) {
152
    switch (entry->p_type) {
137
    case PT_NULL:
153
    case PT_NULL:
138
    case PT_PHDR:
154
    case PT_PHDR:
139
        break;
155
        break;
Line 169... Line 185...
169
   
185
   
170
    backend_data.elf = elf;
186
    backend_data.elf = elf;
171
    backend_data.segment = entry;
187
    backend_data.segment = entry;
172
 
188
 
173
    if (entry->p_align > 1) {
189
    if (entry->p_align > 1) {
174
        if ((entry->p_offset % entry->p_align) != (entry->p_vaddr % entry->p_align)) {
190
        if ((entry->p_offset % entry->p_align) !=
-
 
191
            (entry->p_vaddr % entry->p_align)) {
175
            return EE_INVALID;
192
            return EE_INVALID;
176
        }
193
        }
177
    }
194
    }
178
 
195
 
179
    if (entry->p_flags & PF_X)
196
    if (entry->p_flags & PF_X)
Line 188... Line 205...
188
     * Check if the virtual address starts on page boundary.
205
     * Check if the virtual address starts on page boundary.
189
     */
206
     */
190
    if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr)
207
    if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr)
191
        return EE_UNSUPPORTED;
208
        return EE_UNSUPPORTED;
192
 
209
 
193
    a = as_area_create(as, flags, entry->p_memsz, entry->p_vaddr, AS_AREA_ATTR_NONE,
210
    a = as_area_create(as, flags, entry->p_memsz, entry->p_vaddr,
194
        &elf_backend, &backend_data);
211
        AS_AREA_ATTR_NONE, &elf_backend, &backend_data);
195
    if (!a)
212
    if (!a)
196
        return EE_MEMORY;
213
        return EE_MEMORY;
197
   
214
   
198
    /*
215
    /*
199
     * The segment will be mapped on demand by elf_page_fault().
216
     * The segment will be mapped on demand by elf_page_fault().
Line 208... Line 225...
208
 * @param elf ELF header.
225
 * @param elf ELF header.
209
 * @param as Address space into wich the ELF is being loaded.
226
 * @param as Address space into wich the ELF is being loaded.
210
 *
227
 *
211
 * @return EE_OK on success, error code otherwise.
228
 * @return EE_OK on success, error code otherwise.
212
 */
229
 */
213
static int section_header(elf_section_header_t *entry, elf_header_t *elf, as_t *as)
230
static int section_header(elf_section_header_t *entry, elf_header_t *elf,
-
 
231
    as_t *as)
214
{
232
{
215
    switch (entry->sh_type) {
233
    switch (entry->sh_type) {
-
 
234
    case SHT_PROGBITS:
-
 
235
        if (entry->sh_flags & SHF_TLS) {
-
 
236
            /* .tdata */
-
 
237
        }
-
 
238
        break;
-
 
239
    case SHT_NOBITS:
-
 
240
        if (entry->sh_flags & SHF_TLS) {
-
 
241
            /* .tbss */
-
 
242
        }
-
 
243
        break;
216
    default:
244
    default:
217
        break;
245
        break;
218
    }
246
    }
219
   
247
   
220
    return EE_OK;
248
    return EE_OK;