Rev 3222 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3222 | Rev 3425 | ||
---|---|---|---|
Line 69... | Line 69... | ||
69 | static unsigned int elf_load(elf_ld_t *elf, size_t so_bias); |
69 | static unsigned int elf_load(elf_ld_t *elf, size_t so_bias); |
70 | static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry); |
70 | static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry); |
71 | static int section_header(elf_ld_t *elf, elf_section_header_t *entry); |
71 | static int section_header(elf_ld_t *elf, elf_section_header_t *entry); |
72 | static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); |
72 | static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); |
73 | 73 | ||
- | 74 | /** Read until the buffer is read in its entirety. */ |
|
- | 75 | static int my_read(int fd, char *buf, size_t len) |
|
- | 76 | { |
|
- | 77 | int cnt = 0; |
|
- | 78 | do { |
|
- | 79 | buf += cnt; |
|
- | 80 | len -= cnt; |
|
- | 81 | cnt = read(fd, buf, len); |
|
- | 82 | } while ((cnt > 0) && ((len - cnt) > 0)); |
|
- | 83 | ||
- | 84 | return cnt; |
|
- | 85 | } |
|
- | 86 | ||
74 | /** Load ELF binary from a file. |
87 | /** Load ELF binary from a file. |
75 | * |
88 | * |
76 | * Load an ELF binary from the specified file. If the file is |
89 | * Load an ELF binary from the specified file. If the file is |
77 | * an executable program, it is loaded unbiased. If it is a shared |
90 | * an executable program, it is loaded unbiased. If it is a shared |
78 | * object, it is loaded with the bias @a so_bias. Some information |
91 | * object, it is loaded with the bias @a so_bias. Some information |
Line 154... | Line 167... | ||
154 | { |
167 | { |
155 | elf_header_t header_buf; |
168 | elf_header_t header_buf; |
156 | elf_header_t *header = &header_buf; |
169 | elf_header_t *header = &header_buf; |
157 | int i, rc; |
170 | int i, rc; |
158 | 171 | ||
159 | rc = read(elf->fd, header, sizeof(elf_header_t)); |
172 | rc = my_read(elf->fd, header, sizeof(elf_header_t)); |
160 | if (rc < 0) { |
173 | if (rc < 0) { |
161 | printf("read error\n"); |
174 | printf("read error\n"); |
162 | return EE_INVALID; |
175 | return EE_INVALID; |
163 | } |
176 | } |
164 | 177 | ||
Line 221... | Line 234... | ||
221 | 234 | ||
222 | /* Seek to start of segment header */ |
235 | /* Seek to start of segment header */ |
223 | lseek(elf->fd, header->e_phoff |
236 | lseek(elf->fd, header->e_phoff |
224 | + i * sizeof(elf_segment_header_t), SEEK_SET); |
237 | + i * sizeof(elf_segment_header_t), SEEK_SET); |
225 | 238 | ||
- | 239 | rc = my_read(elf->fd, &segment_hdr, |
|
226 | rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t)); |
240 | sizeof(elf_segment_header_t)); |
- | 241 | if (rc < 0) { |
|
227 | if (rc < 0) { printf("read error\n"); return EE_INVALID; } |
242 | printf("read error\n"); |
- | 243 | return EE_INVALID; |
|
- | 244 | } |
|
228 | 245 | ||
229 | rc = segment_header(elf, &segment_hdr); |
246 | rc = segment_header(elf, &segment_hdr); |
230 | if (rc != EE_OK) |
247 | if (rc != EE_OK) |
231 | return rc; |
248 | return rc; |
232 | } |
249 | } |
Line 239... | Line 256... | ||
239 | 256 | ||
240 | /* Seek to start of section header */ |
257 | /* Seek to start of section header */ |
241 | lseek(elf->fd, header->e_shoff |
258 | lseek(elf->fd, header->e_shoff |
242 | + i * sizeof(elf_section_header_t), SEEK_SET); |
259 | + i * sizeof(elf_section_header_t), SEEK_SET); |
243 | 260 | ||
- | 261 | rc = my_read(elf->fd, §ion_hdr, |
|
244 | rc = read(elf->fd, §ion_hdr, sizeof(elf_section_header_t)); |
262 | sizeof(elf_section_header_t)); |
- | 263 | if (rc < 0) { |
|
245 | if (rc < 0) { printf("read error\n"); return EE_INVALID; } |
264 | printf("read error\n"); |
- | 265 | return EE_INVALID; |
|
- | 266 | } |
|
246 | 267 | ||
247 | rc = section_header(elf, §ion_hdr); |
268 | rc = section_header(elf, §ion_hdr); |
248 | if (rc != EE_OK) |
269 | if (rc != EE_OK) |
249 | return rc; |
270 | return rc; |
250 | } |
271 | } |
Line 324... | Line 345... | ||
324 | bias = elf->bias; |
345 | bias = elf->bias; |
325 | 346 | ||
326 | if (entry->p_align > 1) { |
347 | if (entry->p_align > 1) { |
327 | if ((entry->p_offset % entry->p_align) != |
348 | if ((entry->p_offset % entry->p_align) != |
328 | (entry->p_vaddr % entry->p_align)) { |
349 | (entry->p_vaddr % entry->p_align)) { |
329 | printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n", |
350 | printf("align check 1 failed offset%%align=%d, " |
- | 351 | "vaddr%%align=%d\n", |
|
330 | entry->p_offset % entry->p_align, |
352 | entry->p_offset % entry->p_align, |
331 | entry->p_vaddr % entry->p_align |
353 | entry->p_vaddr % entry->p_align |
332 | ); |
354 | ); |
333 | return EE_INVALID; |
355 | return EE_INVALID; |
334 | } |
356 | } |
335 | } |
357 | } |
336 | 358 | ||
Line 352... | Line 374... | ||
352 | 374 | ||
353 | /* |
375 | /* |
354 | * For the course of loading, the area needs to be readable |
376 | * For the course of loading, the area needs to be readable |
355 | * and writeable. |
377 | * and writeable. |
356 | */ |
378 | */ |
357 | a = as_area_create((uint8_t *)base + bias, |
379 | a = as_area_create((uint8_t *)base + bias, mem_sz, |
358 | mem_sz, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE); |
380 | AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE); |
359 | if (a == (void *)(-1)) { |
381 | if (a == (void *)(-1)) { |
360 | printf("memory mapping failed\n"); |
382 | printf("memory mapping failed\n"); |
361 | return EE_MEMORY; |
383 | return EE_MEMORY; |
362 | } |
384 | } |
363 | 385 | ||
Line 367... | Line 389... | ||
367 | /* |
389 | /* |
368 | * Load segment data |
390 | * Load segment data |
369 | */ |
391 | */ |
370 | // printf("seek to %d\n", entry->p_offset); |
392 | // printf("seek to %d\n", entry->p_offset); |
371 | rc = lseek(elf->fd, entry->p_offset, SEEK_SET); |
393 | rc = lseek(elf->fd, entry->p_offset, SEEK_SET); |
- | 394 | if (rc < 0) { |
|
372 | if (rc < 0) { printf("seek error\n"); return EE_INVALID; } |
395 | printf("seek error\n"); |
- | 396 | return EE_INVALID; |
|
- | 397 | } |
|
373 | 398 | ||
374 | // printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias); |
399 | // printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias); |
375 | /* rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz); |
400 | /* rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz); |
376 | if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/ |
401 | if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/ |
377 | 402 | ||
Line 386... | Line 411... | ||
386 | while (left > 0) { |
411 | while (left > 0) { |
387 | now = 16384; |
412 | now = 16384; |
388 | if (now > left) now = left; |
413 | if (now > left) now = left; |
389 | 414 | ||
390 | // printf("read %d...", now); |
415 | // printf("read %d...", now); |
391 | rc = read(elf->fd, dp, now); |
416 | rc = my_read(elf->fd, dp, now); |
392 | // printf("->%d\n", rc); |
417 | // printf("->%d\n", rc); |
393 | 418 | ||
- | 419 | if (rc < 0) { |
|
394 | if (rc < 0) { printf("read error\n"); return EE_INVALID; } |
420 | printf("read error\n"); |
- | 421 | return EE_INVALID; |
|
- | 422 | } |
|
395 | 423 | ||
396 | left -= now; |
424 | left -= now; |
397 | dp += now; |
425 | dp += now; |
398 | } |
426 | } |
399 | 427 |