|
Lines 511-517
__elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
Link Here
|
| 511 |
size_t map_len; |
511 |
size_t map_len; |
| 512 |
vm_map_t map; |
512 |
vm_map_t map; |
| 513 |
vm_object_t object; |
513 |
vm_object_t object; |
| 514 |
vm_offset_t map_addr; |
514 |
vm_offset_t off, map_addr; |
| 515 |
int error, rv, cow; |
515 |
int error, rv, cow; |
| 516 |
size_t copy_len; |
516 |
size_t copy_len; |
| 517 |
vm_ooffset_t file_addr; |
517 |
vm_ooffset_t file_addr; |
|
Lines 525-531
__elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
Link Here
|
| 525 |
* While I'm here, might as well check for something else that |
525 |
* While I'm here, might as well check for something else that |
| 526 |
* is invalid: filsz cannot be greater than memsz. |
526 |
* is invalid: filsz cannot be greater than memsz. |
| 527 |
*/ |
527 |
*/ |
| 528 |
if ((off_t)filsz + offset > imgp->attr->va_size || filsz > memsz) { |
528 |
if ((filsz != 0 && (off_t)filsz + offset > imgp->attr->va_size) || |
|
|
529 |
filsz > memsz) { |
| 529 |
uprintf("elf_load_section: truncated ELF file\n"); |
530 |
uprintf("elf_load_section: truncated ELF file\n"); |
| 530 |
return (ENOEXEC); |
531 |
return (ENOEXEC); |
| 531 |
} |
532 |
} |
|
Lines 541-546
__elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
Link Here
|
| 541 |
* early and copy the initialized data into that first page. We |
542 |
* early and copy the initialized data into that first page. We |
| 542 |
* choose the second. |
543 |
* choose the second. |
| 543 |
*/ |
544 |
*/ |
|
|
545 |
if (filsz == 0) |
| 546 |
map_len = 0; |
| 544 |
if (memsz > filsz) |
547 |
if (memsz > filsz) |
| 545 |
map_len = trunc_page_ps(offset + filsz, pagesize) - file_addr; |
548 |
map_len = trunc_page_ps(offset + filsz, pagesize) - file_addr; |
| 546 |
else |
549 |
else |
|
Lines 562-570
__elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
Link Here
|
| 562 |
return (EINVAL); |
565 |
return (EINVAL); |
| 563 |
|
566 |
|
| 564 |
/* we can stop now if we've covered it all */ |
567 |
/* we can stop now if we've covered it all */ |
| 565 |
if (memsz == filsz) { |
568 |
if (memsz == filsz) |
| 566 |
return (0); |
569 |
return (0); |
| 567 |
} |
|
|
| 568 |
} |
570 |
} |
| 569 |
|
571 |
|
| 570 |
|
572 |
|
|
Lines 574-580
__elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
Link Here
|
| 574 |
* segment in the file is extended to provide bss. It's a neat idea |
576 |
* segment in the file is extended to provide bss. It's a neat idea |
| 575 |
* to try and save a page, but it's a pain in the behind to implement. |
577 |
* to try and save a page, but it's a pain in the behind to implement. |
| 576 |
*/ |
578 |
*/ |
| 577 |
copy_len = (offset + filsz) - trunc_page_ps(offset + filsz, pagesize); |
579 |
copy_len = filsz == 0 ? 0 : (offset + filsz) - trunc_page_ps(offset + |
|
|
580 |
filsz, pagesize); |
| 578 |
map_addr = trunc_page_ps((vm_offset_t)vmaddr + filsz, pagesize); |
581 |
map_addr = trunc_page_ps((vm_offset_t)vmaddr + filsz, pagesize); |
| 579 |
map_len = round_page_ps((vm_offset_t)vmaddr + memsz, pagesize) - |
582 |
map_len = round_page_ps((vm_offset_t)vmaddr + memsz, pagesize) - |
| 580 |
map_addr; |
583 |
map_addr; |
|
Lines 583-596
__elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
Link Here
|
| 583 |
if (map_len != 0) { |
586 |
if (map_len != 0) { |
| 584 |
rv = __elfN(map_insert)(imgp, map, NULL, 0, map_addr, |
587 |
rv = __elfN(map_insert)(imgp, map, NULL, 0, map_addr, |
| 585 |
map_addr + map_len, VM_PROT_ALL, 0); |
588 |
map_addr + map_len, VM_PROT_ALL, 0); |
| 586 |
if (rv != KERN_SUCCESS) { |
589 |
if (rv != KERN_SUCCESS) |
| 587 |
return (EINVAL); |
590 |
return (EINVAL); |
| 588 |
} |
|
|
| 589 |
} |
591 |
} |
| 590 |
|
592 |
|
| 591 |
if (copy_len != 0) { |
593 |
if (copy_len != 0) { |
| 592 |
vm_offset_t off; |
|
|
| 593 |
|
| 594 |
sf = vm_imgact_map_page(object, offset + filsz); |
594 |
sf = vm_imgact_map_page(object, offset + filsz); |
| 595 |
if (sf == NULL) |
595 |
if (sf == NULL) |
| 596 |
return (EIO); |
596 |
return (EIO); |
|
Lines 601-614
__elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
Link Here
|
| 601 |
error = copyout((caddr_t)sf_buf_kva(sf) + off, |
601 |
error = copyout((caddr_t)sf_buf_kva(sf) + off, |
| 602 |
(caddr_t)map_addr, copy_len); |
602 |
(caddr_t)map_addr, copy_len); |
| 603 |
vm_imgact_unmap_page(sf); |
603 |
vm_imgact_unmap_page(sf); |
| 604 |
if (error) { |
604 |
if (error != 0) |
| 605 |
return (error); |
605 |
return (error); |
| 606 |
} |
|
|
| 607 |
} |
606 |
} |
| 608 |
|
607 |
|
| 609 |
/* |
608 |
/* |
| 610 |
* set it to the specified protection. |
609 |
* set it to the specified protection. |
| 611 |
* XXX had better undo the damage from pasting over the cracks here! |
|
|
| 612 |
*/ |
610 |
*/ |
| 613 |
vm_map_protect(map, trunc_page(map_addr), round_page(map_addr + |
611 |
vm_map_protect(map, trunc_page(map_addr), round_page(map_addr + |
| 614 |
map_len), prot, FALSE); |
612 |
map_len), prot, FALSE); |