Index: libexec/rtld-elf/map_object.c =================================================================== --- libexec/rtld-elf/map_object.c +++ libexec/rtld-elf/map_object.c @@ -73,6 +73,7 @@ Elf_Addr data_vaddr; Elf_Addr data_vlimit; caddr_t data_addr; + caddr_t last_limit; int data_prot; int data_flags; Elf_Addr clear_vaddr; @@ -201,12 +202,23 @@ 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; + + /* Assume segments are sorted by vaddr, per SysV ABI 4.1. */ + if (i > 0 && data_addr > last_limit) { + if (munmap(last_limit, data_addr - last_limit) == -1) { + _rtld_error("%s: munmap of unoccupied segment failed: %s", + path, rtld_strerror(errno)); + goto error1; + } + } + if (mmap(data_addr, data_vlimit - data_vaddr, data_prot, data_flags | MAP_PREFAULT_READ, fd, data_offset) == (caddr_t) -1) { _rtld_error("%s: mmap of data failed: %s", path, rtld_strerror(errno)); goto error1; } + last_limit = data_addr + (data_vlimit - data_vaddr); /* Do BSS setup */ if (segs[i]->p_filesz != segs[i]->p_memsz) { @@ -243,6 +255,7 @@ rtld_strerror(errno)); goto error1; } + last_limit = bss_addr + (bss_vlimit - bss_vaddr); } }