Property changes on: . ___________________________________________________________________ Modified: svn:mergeinfo Merged /head/libexec/rtld-elf:r190885,195743 Index: map_object.c =================================================================== --- map_object.c (revision 200098) +++ map_object.c (working copy) @@ -153,8 +153,8 @@ mapsize = base_vlimit - base_vaddr; base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL; - mapbase = mmap(base_addr, mapsize, convert_prot(segs[0]->p_flags), - convert_flags(segs[0]->p_flags), fd, base_offset); + mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE | + MAP_NOCORE, -1, 0); if (mapbase == (caddr_t) -1) { _rtld_error("%s: mmap of entire address space failed: %s", path, strerror(errno)); @@ -175,45 +175,49 @@ data_addr = mapbase + (data_vaddr - base_vaddr); data_prot = convert_prot(segs[i]->p_flags); data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED; - /* Do not call mmap on the first segment - this is redundant */ - if (i && mmap(data_addr, data_vlimit - data_vaddr, data_prot, + if (mmap(data_addr, data_vlimit - data_vaddr, data_prot, data_flags, fd, data_offset) == (caddr_t) -1) { _rtld_error("%s: mmap of data failed: %s", path, strerror(errno)); return NULL; } - /* Clear any BSS in the last page of the segment. */ - clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz; - clear_addr = mapbase + (clear_vaddr - base_vaddr); - clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr); - if ((nclear = data_vlimit - clear_vaddr) > 0) { - /* Make sure the end of the segment is writable */ - if ((data_prot & PROT_WRITE) == 0 && - -1 == mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) { + /* Do BSS setup */ + if (segs[i]->p_filesz != segs[i]->p_memsz) { + + /* Clear any BSS in the last page of the segment. */ + clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz; + clear_addr = mapbase + (clear_vaddr - base_vaddr); + clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr); + + if ((nclear = data_vlimit - clear_vaddr) > 0) { + /* Make sure the end of the segment is writable */ + if ((data_prot & PROT_WRITE) == 0 && -1 == + mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) { _rtld_error("%s: mprotect failed: %s", path, strerror(errno)); return NULL; - } + } - memset(clear_addr, 0, nclear); + memset(clear_addr, 0, nclear); - /* Reset the data protection back */ - if ((data_prot & PROT_WRITE) == 0) - mprotect(clear_page, PAGE_SIZE, data_prot); - } + /* Reset the data protection back */ + if ((data_prot & PROT_WRITE) == 0) + mprotect(clear_page, PAGE_SIZE, data_prot); + } - /* Overlay the BSS segment onto the proper region. */ - bss_vaddr = data_vlimit; - bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz); - bss_addr = mapbase + (bss_vaddr - base_vaddr); - if (bss_vlimit > bss_vaddr) { /* There is something to do */ - if (mmap(bss_addr, bss_vlimit - bss_vaddr, data_prot, - MAP_PRIVATE|MAP_FIXED|MAP_ANON, -1, 0) == (caddr_t) -1) { - _rtld_error("%s: mmap of bss failed: %s", path, + /* Overlay the BSS segment onto the proper region. */ + bss_vaddr = data_vlimit; + bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz); + bss_addr = mapbase + (bss_vaddr - base_vaddr); + if (bss_vlimit > bss_vaddr) { /* There is something to do */ + if (mprotect(bss_addr, bss_vlimit - bss_vaddr, data_prot) == -1) { + _rtld_error("%s: mprotect of bss failed: %s", path, strerror(errno)); - return NULL; + return NULL; + } } } + if (phdr_vaddr == 0 && data_offset <= hdr->e_phoff && (data_vlimit - data_vaddr + data_offset) >= (hdr->e_phoff + hdr->e_phnum * sizeof (Elf_Phdr))) {