summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/exec/elf/elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/exec/elf/elf.c')
-rw-r--r--usr/src/uts/common/exec/elf/elf.c57
1 files changed, 26 insertions, 31 deletions
diff --git a/usr/src/uts/common/exec/elf/elf.c b/usr/src/uts/common/exec/elf/elf.c
index 6508cdae85..53905c1013 100644
--- a/usr/src/uts/common/exec/elf/elf.c
+++ b/usr/src/uts/common/exec/elf/elf.c
@@ -1096,6 +1096,7 @@ mapelfexec(
off_t offset;
int hsize = ehdr->e_phentsize;
caddr_t mintmp = (caddr_t)-1;
+ extern int use_brk_lpg;
if (ehdr->e_type == ET_DYN) {
/*
@@ -1145,47 +1146,41 @@ mapelfexec(
page = 0;
}
+ /*
+ * Set the heap pagesize for OOB when the bss size
+ * is known and use_brk_lpg is not 0.
+ */
+ if (brksize != NULL && use_brk_lpg &&
+ zfodsz != 0 && phdr == dataphdrp &&
+ (prot & PROT_WRITE)) {
+ size_t tlen = P2NPHASE((uintptr_t)addr +
+ phdr->p_filesz, PAGESIZE);
+
+ if (zfodsz > tlen) {
+ curproc->p_brkpageszc =
+ page_szc(map_pgsz(MAPPGSZ_HEAP,
+ curproc, addr + phdr->p_filesz +
+ tlen, zfodsz - tlen, 0));
+ }
+ }
+
if (curproc->p_brkpageszc != 0 && phdr == dataphdrp &&
(prot & PROT_WRITE)) {
- /*
- * segvn only uses large pages for segments
- * that have the requested large page size
- * aligned base and size. To insure the part
- * of bss that starts at heap large page size
- * boundary gets mapped by large pages create
- * 2 bss segvn segments which is accomplished
- * by calling execmap twice. First execmap
- * will create the bss segvn segment that is
- * before the large page boundary and it will
- * be mapped with base pages. If bss start is
- * already large page aligned only 1 bss
- * segment will be created. The second bss
- * segment's size is large page size aligned
- * so that segvn uses large pages for that
- * segment and it also makes the heap that
- * starts right after bss to start at large
- * page boundary.
- */
uint_t szc = curproc->p_brkpageszc;
size_t pgsz = page_get_pagesize(szc);
- caddr_t zaddr = addr + phdr->p_filesz;
- size_t zlen = P2NPHASE((uintptr_t)zaddr, pgsz);
+ caddr_t ebss = addr + phdr->p_memsz;
+ size_t extra_zfodsz;
ASSERT(pgsz > PAGESIZE);
+ extra_zfodsz = P2NPHASE((uintptr_t)ebss, pgsz);
+
if (error = execmap(vp, addr, phdr->p_filesz,
- zlen, phdr->p_offset, prot, page, szc))
+ zfodsz + extra_zfodsz, phdr->p_offset,
+ prot, page, szc))
goto bad;
- if (zfodsz > zlen) {
- zfodsz -= zlen;
- zaddr += zlen;
- zlen = P2ROUNDUP(zfodsz, pgsz);
- if (error = execmap(vp, zaddr, 0, zlen,
- phdr->p_offset, prot, page, szc))
- goto bad;
- }
if (brksize != NULL)
- *brksize = zlen - zfodsz;
+ *brksize = extra_zfodsz;
} else {
if (error = execmap(vp, addr, phdr->p_filesz,
zfodsz, phdr->p_offset, prot, page, 0))