Mercurial > illumos > illumos-gate
changeset 4730:cf546095c072
6308191 mapelfexec() may fail with ENOMEM if a non-zero p_vaddr is specified for an ET_DYN binary
6576832 lx_elfexec sets brkbase to 0 for statically linked linux binaries
6577878 IPv6 sockets in lx brand not supported but creation allowed
6581316 lx_branded processes missing AT_CLKTCK entry from auxhilary vector
author | eh208807 |
---|---|
date | Wed, 25 Jul 2007 16:32:57 -0700 |
parents | 5261ba77b352 |
children | e202adc835b4 |
files | usr/src/lib/brand/lx/lx_brand/common/socket.c usr/src/uts/common/brand/lx/os/lx_brand.c usr/src/uts/common/brand/lx/sys/lx_brand.h usr/src/uts/common/exec/elf/elf.c usr/src/uts/common/sys/auxv.h |
diffstat | 5 files changed, 110 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/brand/lx/lx_brand/common/socket.c Wed Jul 25 16:08:46 2007 -0700 +++ b/usr/src/lib/brand/lx/lx_brand/common/socket.c Wed Jul 25 16:32:57 2007 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -449,6 +449,10 @@ return (err); lx_debug("\tsocket(%d, %d, %d)", domain, type, protocol); + + /* Right now IPv6 sockets don't work */ + if (domain == AF_INET6) + return (-EAFNOSUPPORT); fd = socket(domain, type, protocol); if (fd >= 0) return (fd); @@ -727,14 +731,14 @@ * call, and resetting the action back to its previous value. */ if (nosigpipe) { - newact.sa_handler = SIG_IGN; - newact.sa_flags = 0; - (void) sigemptyset(&newact.sa_mask); + newact.sa_handler = SIG_IGN; + newact.sa_flags = 0; + (void) sigemptyset(&newact.sa_mask); - if (sigaction(SIGPIPE, &newact, &oact) < 0) - lx_err_fatal(gettext( - "%s: could not ignore SIGPIPE to emulate " - "LX_MSG_NOSIGNAL"), "send()"); + if (sigaction(SIGPIPE, &newact, &oact) < 0) + lx_err_fatal(gettext( + "%s: could not ignore SIGPIPE to emulate " + "LX_MSG_NOSIGNAL"), "send()"); } r = send(sockfd, buf, len, flags); @@ -774,14 +778,14 @@ * call, and resetting the action back to its previous value. */ if (nosigpipe) { - newact.sa_handler = SIG_IGN; - newact.sa_flags = 0; - (void) sigemptyset(&newact.sa_mask); + newact.sa_handler = SIG_IGN; + newact.sa_flags = 0; + (void) sigemptyset(&newact.sa_mask); - if (sigaction(SIGPIPE, &newact, &oact) < 0) - lx_err_fatal(gettext( - "%s: could not ignore SIGPIPE to emulate " - "LX_MSG_NOSIGNAL"), "recv()"); + if (sigaction(SIGPIPE, &newact, &oact) < 0) + lx_err_fatal(gettext( + "%s: could not ignore SIGPIPE to emulate " + "LX_MSG_NOSIGNAL"), "recv()"); } r = recv(sockfd, buf, len, flags); @@ -831,14 +835,14 @@ * call, and resetting the action back to its previous value. */ if (nosigpipe) { - newact.sa_handler = SIG_IGN; - newact.sa_flags = 0; - (void) sigemptyset(&newact.sa_mask); + newact.sa_handler = SIG_IGN; + newact.sa_flags = 0; + (void) sigemptyset(&newact.sa_mask); - if (sigaction(SIGPIPE, &newact, &oact) < 0) - lx_err_fatal(gettext( - "%s: could not ignore SIGPIPE to emulate " - "LX_MSG_NOSIGNAL"), "sendto()"); + if (sigaction(SIGPIPE, &newact, &oact) < 0) + lx_err_fatal(gettext( + "%s: could not ignore SIGPIPE to emulate " + "LX_MSG_NOSIGNAL"), "sendto()"); } r = sendto(sockfd, buf, len, flags, to, tolen); @@ -891,14 +895,14 @@ * call, and resetting the action back to its previous value. */ if (nosigpipe) { - newact.sa_handler = SIG_IGN; - newact.sa_flags = 0; - (void) sigemptyset(&newact.sa_mask); + newact.sa_handler = SIG_IGN; + newact.sa_flags = 0; + (void) sigemptyset(&newact.sa_mask); - if (sigaction(SIGPIPE, &newact, &oact) < 0) - lx_err_fatal(gettext( - "%s: could not ignore SIGPIPE to emulate " - "LX_MSG_NOSIGNAL"), "recvfrom()"); + if (sigaction(SIGPIPE, &newact, &oact) < 0) + lx_err_fatal(gettext( + "%s: could not ignore SIGPIPE to emulate " + "LX_MSG_NOSIGNAL"), "recvfrom()"); } r = recvfrom(sockfd, buf, len, flags, from, from_lenp); @@ -1147,14 +1151,14 @@ * call, and resetting the action back to its previous value. */ if (nosigpipe) { - newact.sa_handler = SIG_IGN; - newact.sa_flags = 0; - (void) sigemptyset(&newact.sa_mask); + newact.sa_handler = SIG_IGN; + newact.sa_flags = 0; + (void) sigemptyset(&newact.sa_mask); - if (sigaction(SIGPIPE, &newact, &oact) < 0) - lx_err_fatal(gettext( - "%s: could not ignore SIGPIPE to emulate " - "LX_MSG_NOSIGNAL"), "sendmsg()"); + if (sigaction(SIGPIPE, &newact, &oact) < 0) + lx_err_fatal(gettext( + "%s: could not ignore SIGPIPE to emulate " + "LX_MSG_NOSIGNAL"), "sendmsg()"); } r = _so_sendmsg(sockfd, (struct msghdr *)&msg, flags | MSG_XPG4_2); @@ -1225,14 +1229,14 @@ * call, and resetting the action back to its previous value. */ if (nosigpipe) { - newact.sa_handler = SIG_IGN; - newact.sa_flags = 0; - (void) sigemptyset(&newact.sa_mask); + newact.sa_handler = SIG_IGN; + newact.sa_flags = 0; + (void) sigemptyset(&newact.sa_mask); - if (sigaction(SIGPIPE, &newact, &oact) < 0) - lx_err_fatal(gettext( - "%s: could not ignore SIGPIPE to emulate " - "LX_MSG_NOSIGNAL"), "recvmsg()"); + if (sigaction(SIGPIPE, &newact, &oact) < 0) + lx_err_fatal(gettext( + "%s: could not ignore SIGPIPE to emulate " + "LX_MSG_NOSIGNAL"), "recvmsg()"); } r = _so_recvmsg(sockfd, (struct msghdr *)&msg, flags | MSG_XPG4_2);
--- a/usr/src/uts/common/brand/lx/os/lx_brand.c Wed Jul 25 16:08:46 2007 -0700 +++ b/usr/src/uts/common/brand/lx/os/lx_brand.c Wed Jul 25 16:32:57 2007 -0700 @@ -711,15 +711,41 @@ * calculated address from above. */ edp->ed_ldentry = edp->ed_entry; + + /* + * In all situations except an ET_DYN elf object with no + * interpreter, we want to leave the brk and base + * values set by mapexec_brand alone. Normally when + * running ET_DYN objects on Solaris (most likely + * /lib/ld.so.1) the kernel sets brk and base to 0 since + * it doesn't know where to put the heap, and later the + * linker will call brk() to initialize the heap in: + * usr/src/cmd/sgs/rtld/common/setup.c:setup() + * after it has determined where to put it. (This + * decision is made after the linker loads and inspects + * elf properties of the target executable being run.) + * + * So for ET_DYN Linux executables, we also don't know + * where the heap should go, so we'll set the brk and + * base to 0. But in this case the Solaris linker will + * not initialize the heap, so when the Linux linker + * starts running there is no heap allocated. This + * seems to be ok on Linux 2.4 based systems because the + * Linux linker/libc fall back to using mmap() to + * allocate memory. But on 2.6 systems, running + * applications by specifying them as command line + * arguments to the linker results in segfaults for an + * as yet undetermined reason (which seems to indicatej + * that a more permanent fix for heap initalization in + * these cases may be necessary). + */ + if (ehdr.e_type == ET_DYN) { + env.ex_bssbase = (caddr_t)0; + env.ex_brkbase = (caddr_t)0; + env.ex_brksize = 0; + } } - /* - * Delay setting the brkbase until the first call to brk(); - * see elfexec() for details. - */ - env.ex_bssbase = (caddr_t)0; - env.ex_brkbase = (caddr_t)0; - env.ex_brksize = 0; } env.ex_vp = vp; @@ -732,6 +758,14 @@ * what's on the process stack. */ phdr_auxv32[0].a_un.a_val = edp->ed_phdr; + + /* + * Linux 2.6 programs such as ps will print an error message if the + * following aux entry is missing + */ + phdr_auxv32[1].a_type = AT_CLKTCK; + phdr_auxv32[1].a_un.a_val = hz; + if (copyout(&phdr_auxv32, args->auxp_brand, sizeof (phdr_auxv32)) == -1) return (EFAULT);
--- a/usr/src/uts/common/brand/lx/sys/lx_brand.h Wed Jul 25 16:08:46 2007 -0700 +++ b/usr/src/uts/common/brand/lx/sys/lx_brand.h Wed Jul 25 16:32:57 2007 -0700 @@ -80,6 +80,9 @@ /* Aux vector containing phdr of linux executable, used by lx_librtld_db */ #define AT_SUN_BRAND_LX_PHDR AT_SUN_BRAND_AUX1 +/* Aux vector containing hz value */ +#define AT_CLKTCK 17 + #ifndef _ASM typedef struct lx_brand_registration {
--- a/usr/src/uts/common/exec/elf/elf.c Wed Jul 25 16:08:46 2007 -0700 +++ b/usr/src/uts/common/exec/elf/elf.c Wed Jul 25 16:32:57 2007 -0700 @@ -1124,6 +1124,22 @@ if (addr == NULL) return (ENOMEM); *voffset = (intptr_t)addr; + + /* + * Calculate the minimum vaddr so it can be subtracted out. + * According to the ELF specification, since PT_LOAD sections + * must be sorted by increasing p_vaddr values, this is + * guaranteed to be the first PT_LOAD section. + */ + phdr = (Phdr *)phdrbase; + for (i = nphdrs; i > 0; i--) { + if (phdr->p_type == PT_LOAD) { + *voffset -= (uintptr_t)phdr->p_vaddr; + break; + } + phdr = (Phdr *)((caddr_t)phdr + hsize); + } + } else { *voffset = 0; }
--- a/usr/src/uts/common/sys/auxv.h Wed Jul 25 16:08:46 2007 -0700 +++ b/usr/src/uts/common/sys/auxv.h Wed Jul 25 16:32:57 2007 -0700 @@ -92,7 +92,8 @@ * in the draft amd64 ABI. * * At the time of writing, Solaris doesn't place any of these values into - * the aux vector; we do similar things via AT_SUN_ values. + * the aux vector, except AT_CLKTCK which is placed on the aux vector for + * lx branded processes; also, we do similar things via AT_SUN_ values. * * AT_NOTELF 10 program is not ELF? * AT_UID 11 real user id @@ -139,7 +140,7 @@ * These attributes communicate performance -hints- about processor * hardware capabilities that might be useful to library implementations. */ -#define AT_SUN_HWCAP 2009 +#define AT_SUN_HWCAP 2009 #if defined(_KERNEL) /*