summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/map_object.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/rtld-elf/map_object.c')
-rw-r--r--libexec/rtld-elf/map_object.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c
index 028ac80..6de0c9e 100644
--- a/libexec/rtld-elf/map_object.c
+++ b/libexec/rtld-elf/map_object.c
@@ -180,37 +180,43 @@ map_object(int fd, const char *path, const struct stat *sb)
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 (mprotect(bss_addr, bss_vlimit - bss_vaddr, data_prot) == -1) {
+ /* 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))) {
OpenPOWER on IntegriCloud