Rev 3400 | Rev 3552 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3400 | Rev 3403 | ||
|---|---|---|---|
| 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 | ||