svn commit: r247243 - in projects/virtio: bin/sh cddl/contrib/opensolaris/cmd/dtrace contrib/binutils/opcodes contrib/llvm/lib/Target/X86 contrib/llvm/tools/clang/lib/Driver etc lib/libc/gen lib/li...

Bryan Venteicher bryanv at FreeBSD.org
Sun Feb 24 22:20:44 UTC 2013


Author: bryanv
Date: Sun Feb 24 22:20:40 2013
New Revision: 247243
URL: http://svnweb.freebsd.org/changeset/base/247243

Log:
  IFC @ r247242
  
  Approved by:	grehan (implicit)

Added:
  projects/virtio/sys/x86/include/elf.h
     - copied unchanged from r247242, head/sys/x86/include/elf.h
  projects/virtio/sys/x86/include/frame.h
     - copied unchanged from r247242, head/sys/x86/include/frame.h
  projects/virtio/sys/x86/include/sigframe.h
     - copied unchanged from r247242, head/sys/x86/include/sigframe.h
  projects/virtio/sys/x86/include/signal.h
     - copied unchanged from r247242, head/sys/x86/include/signal.h
  projects/virtio/sys/x86/include/ucontext.h
     - copied unchanged from r247242, head/sys/x86/include/ucontext.h
  projects/virtio/tools/regression/bin/sh/builtins/read6.0
     - copied unchanged from r247242, head/tools/regression/bin/sh/builtins/read6.0
  projects/virtio/tools/regression/bin/sh/builtins/wait4.0
     - copied unchanged from r247242, head/tools/regression/bin/sh/builtins/wait4.0
  projects/virtio/tools/regression/bin/sh/builtins/wait5.0
     - copied unchanged from r247242, head/tools/regression/bin/sh/builtins/wait5.0
Deleted:
  projects/virtio/sys/dev/mxge/mxge_lro.c
Modified:
  projects/virtio/bin/sh/eval.c
  projects/virtio/bin/sh/jobs.c
  projects/virtio/bin/sh/main.c
  projects/virtio/bin/sh/trap.c
  projects/virtio/bin/sh/trap.h
  projects/virtio/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
  projects/virtio/contrib/binutils/opcodes/i386-opc.h
  projects/virtio/contrib/llvm/lib/Target/X86/X86InstrCompiler.td
  projects/virtio/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
  projects/virtio/contrib/llvm/tools/clang/lib/Driver/Tools.h
  projects/virtio/etc/Makefile
  projects/virtio/lib/libc/gen/opendir.c
  projects/virtio/lib/libc/stdlib/bsearch.3
  projects/virtio/lib/libc/stdlib/qsort.3
  projects/virtio/lib/libelf/elf_update.c
  projects/virtio/sbin/devd/devd.conf.5
  projects/virtio/sbin/fsck_ffs/dir.c
  projects/virtio/sbin/fsck_ffs/ea.c
  projects/virtio/sbin/fsck_ffs/fsck.h
  projects/virtio/sbin/fsck_ffs/fsutil.c
  projects/virtio/sbin/fsck_ffs/inode.c
  projects/virtio/sbin/fsck_ffs/main.c
  projects/virtio/sbin/fsck_ffs/setup.c
  projects/virtio/sbin/fsdb/fsdbutil.c
  projects/virtio/share/man/man4/carp.4
  projects/virtio/share/man/man9/VFS_SET.9
  projects/virtio/share/mk/bsd.lib.mk
  projects/virtio/sys/amd64/include/elf.h
  projects/virtio/sys/amd64/include/frame.h
  projects/virtio/sys/amd64/include/sigframe.h
  projects/virtio/sys/amd64/include/signal.h
  projects/virtio/sys/amd64/include/ucontext.h
  projects/virtio/sys/arm/arm/machdep.c
  projects/virtio/sys/arm/arm/pmap-v6.c
  projects/virtio/sys/arm/arm/pmap.c
  projects/virtio/sys/arm/at91/at91_machdep.c
  projects/virtio/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
  projects/virtio/sys/arm/econa/econa_machdep.c
  projects/virtio/sys/arm/include/pmap.h
  projects/virtio/sys/arm/s3c2xx0/s3c24x0_machdep.c
  projects/virtio/sys/arm/sa11x0/assabet_machdep.c
  projects/virtio/sys/arm/xscale/i80321/ep80219_machdep.c
  projects/virtio/sys/arm/xscale/i80321/iq31244_machdep.c
  projects/virtio/sys/arm/xscale/i8134x/crb_machdep.c
  projects/virtio/sys/arm/xscale/ixp425/avila_machdep.c
  projects/virtio/sys/arm/xscale/pxa/pxa_machdep.c
  projects/virtio/sys/boot/fdt/dts/bcm2835-rpi-b.dts
  projects/virtio/sys/boot/fdt/fdt_loader_cmd.c
  projects/virtio/sys/boot/uboot/lib/elf_freebsd.c
  projects/virtio/sys/boot/userboot/userboot/elf32_freebsd.c
  projects/virtio/sys/cam/ata/ata_pmp.c
  projects/virtio/sys/cam/scsi/scsi_da.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lzjb.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_leaf.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_byteswap.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_rlock.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  projects/virtio/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  projects/virtio/sys/conf/files
  projects/virtio/sys/crypto/aesni/aesni_wrap.c
  projects/virtio/sys/dev/ata/ata-all.c
  projects/virtio/sys/dev/ata/ata-all.h
  projects/virtio/sys/dev/ata/ata-dma.c
  projects/virtio/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
  projects/virtio/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c
  projects/virtio/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
  projects/virtio/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
  projects/virtio/sys/dev/ath/if_ath.c
  projects/virtio/sys/dev/ath/if_ath_sysctl.c
  projects/virtio/sys/dev/ath/if_ath_tx.c
  projects/virtio/sys/dev/ath/if_ath_tx.h
  projects/virtio/sys/dev/ath/if_ath_tx_ht.c
  projects/virtio/sys/dev/ath/if_athvar.h
  projects/virtio/sys/dev/cxgbe/common/t4_hw.h
  projects/virtio/sys/dev/cxgbe/t4_main.c
  projects/virtio/sys/dev/cxgbe/t4_sge.c
  projects/virtio/sys/dev/e1000/e1000_82571.c
  projects/virtio/sys/dev/e1000/e1000_82575.c
  projects/virtio/sys/dev/e1000/e1000_82575.h
  projects/virtio/sys/dev/e1000/e1000_api.c
  projects/virtio/sys/dev/e1000/e1000_api.h
  projects/virtio/sys/dev/e1000/e1000_defines.h
  projects/virtio/sys/dev/e1000/e1000_hw.h
  projects/virtio/sys/dev/e1000/e1000_i210.c
  projects/virtio/sys/dev/e1000/e1000_i210.h
  projects/virtio/sys/dev/e1000/e1000_ich8lan.c
  projects/virtio/sys/dev/e1000/e1000_ich8lan.h
  projects/virtio/sys/dev/e1000/e1000_mac.c
  projects/virtio/sys/dev/e1000/e1000_mac.h
  projects/virtio/sys/dev/e1000/e1000_manage.c
  projects/virtio/sys/dev/e1000/e1000_nvm.c
  projects/virtio/sys/dev/e1000/e1000_nvm.h
  projects/virtio/sys/dev/e1000/e1000_osdep.h
  projects/virtio/sys/dev/e1000/e1000_phy.c
  projects/virtio/sys/dev/e1000/e1000_phy.h
  projects/virtio/sys/dev/e1000/e1000_regs.h
  projects/virtio/sys/dev/e1000/if_em.c
  projects/virtio/sys/dev/e1000/if_igb.c
  projects/virtio/sys/dev/e1000/if_lem.c
  projects/virtio/sys/dev/fdt/fdt_common.h
  projects/virtio/sys/dev/firewire/sbp.c
  projects/virtio/sys/dev/mcd/mcd.c
  projects/virtio/sys/dev/mxge/if_mxge.c
  projects/virtio/sys/dev/mxge/if_mxge_var.h
  projects/virtio/sys/dev/ppc/ppc.c
  projects/virtio/sys/dev/ppc/ppc_isa.c
  projects/virtio/sys/dev/si/si.c
  projects/virtio/sys/fs/nfs/nfs_commonkrpc.c
  projects/virtio/sys/fs/nfsclient/nfs_clstate.c
  projects/virtio/sys/fs/nfsclient/nfs_clvfsops.c
  projects/virtio/sys/i386/include/elf.h
  projects/virtio/sys/i386/include/frame.h
  projects/virtio/sys/i386/include/sigframe.h
  projects/virtio/sys/i386/include/signal.h
  projects/virtio/sys/i386/include/ucontext.h
  projects/virtio/sys/i386/isa/pmtimer.c
  projects/virtio/sys/ia64/conf/GENERIC
  projects/virtio/sys/kern/kern_sig.c
  projects/virtio/sys/kern/subr_trap.c
  projects/virtio/sys/kern/vfs_export.c
  projects/virtio/sys/kern/vfs_init.c
  projects/virtio/sys/kern/vfs_lookup.c
  projects/virtio/sys/modules/mxge/mxge/Makefile
  projects/virtio/sys/netinet/ip_input.c
  projects/virtio/sys/netinet/tcp_lro.c
  projects/virtio/sys/nfsclient/nfs_krpc.c
  projects/virtio/sys/nfsclient/nfs_vfsops.c
  projects/virtio/sys/opencrypto/xform.c
  projects/virtio/sys/pci/ncr.c
  projects/virtio/sys/powerpc/include/vmparam.h
  projects/virtio/sys/sys/mount.h
  projects/virtio/sys/sys/signalvar.h
  projects/virtio/sys/sys/systm.h
  projects/virtio/sys/tools/vnode_if.awk
  projects/virtio/sys/x86/isa/atrtc.c
  projects/virtio/sys/x86/isa/clock.c
  projects/virtio/usr.bin/systat/ifcmds.c
  projects/virtio/usr.bin/systat/ifstat.c
  projects/virtio/usr.bin/systat/systat.1
  projects/virtio/usr.sbin/bhyve/mem.c
  projects/virtio/usr.sbin/bhyve/mem.h
  projects/virtio/usr.sbin/bhyve/pci_emul.c
  projects/virtio/usr.sbin/extattr/rmextattr.c
  projects/virtio/usr.sbin/makefs/makefs.8
  projects/virtio/usr.sbin/makefs/makefs.c
  projects/virtio/usr.sbin/makefs/makefs.h
  projects/virtio/usr.sbin/makefs/mtree.c
  projects/virtio/usr.sbin/makefs/walk.c
  projects/virtio/usr.sbin/mountd/mountd.c
  projects/virtio/usr.sbin/pkg/pkg.c
Directory Properties:
  projects/virtio/   (props changed)
  projects/virtio/cddl/contrib/opensolaris/   (props changed)
  projects/virtio/contrib/binutils/   (props changed)
  projects/virtio/contrib/llvm/   (props changed)
  projects/virtio/contrib/llvm/tools/clang/   (props changed)
  projects/virtio/lib/libc/   (props changed)
  projects/virtio/sbin/   (props changed)
  projects/virtio/share/man/man4/   (props changed)
  projects/virtio/sys/   (props changed)
  projects/virtio/sys/boot/   (props changed)
  projects/virtio/sys/cddl/contrib/opensolaris/   (props changed)
  projects/virtio/sys/conf/   (props changed)
  projects/virtio/usr.sbin/bhyve/   (props changed)

Modified: projects/virtio/bin/sh/eval.c
==============================================================================
--- projects/virtio/bin/sh/eval.c	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/bin/sh/eval.c	Sun Feb 24 22:20:40 2013	(r247243)
@@ -301,7 +301,7 @@ evaltree(union node *n, int flags)
 	} while (n != NULL);
 out:
 	popstackmark(&smark);
-	if (pendingsigs)
+	if (pendingsig)
 		dotrap();
 	if (eflag && exitstatus != 0 && do_etest)
 		exitshell(exitstatus);

Modified: projects/virtio/bin/sh/jobs.c
==============================================================================
--- projects/virtio/bin/sh/jobs.c	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/bin/sh/jobs.c	Sun Feb 24 22:20:40 2013	(r247243)
@@ -521,7 +521,7 @@ waitcmd(int argc, char **argv)
 	} while (dowait(DOWAIT_BLOCK | DOWAIT_SIG, (struct job *)NULL) != -1);
 	in_waitcmd--;
 
-	return 0;
+	return pendingsig + 128;
 }
 
 

Modified: projects/virtio/bin/sh/main.c
==============================================================================
--- projects/virtio/bin/sh/main.c	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/bin/sh/main.c	Sun Feb 24 22:20:40 2013	(r247243)
@@ -196,7 +196,7 @@ cmdloop(int top)
 	TRACE(("cmdloop(%d) called\n", top));
 	setstackmark(&smark);
 	for (;;) {
-		if (pendingsigs)
+		if (pendingsig)
 			dotrap();
 		inter = 0;
 		if (iflag && top) {

Modified: projects/virtio/bin/sh/trap.c
==============================================================================
--- projects/virtio/bin/sh/trap.c	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/bin/sh/trap.c	Sun Feb 24 22:20:40 2013	(r247243)
@@ -73,7 +73,7 @@ __FBSDID("$FreeBSD$");
 
 
 MKINIT char sigmode[NSIG];	/* current value of signal */
-int pendingsigs;		/* indicates some signal received */
+volatile sig_atomic_t pendingsig;	/* indicates some signal received */
 int in_dotrap;			/* do we execute in a trap handler? */
 static char *volatile trap[NSIG];	/* trap handler commands */
 static volatile sig_atomic_t gotsig[NSIG];
@@ -388,22 +388,25 @@ onsig(int signo)
 		return;
 	}
 
-	if (signo != SIGCHLD || !ignore_sigchld)
-		gotsig[signo] = 1;
-	pendingsigs++;
-
 	/* If we are currently in a wait builtin, prepare to break it */
-	if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0)
-		breakwaitcmd = 1;
-	/*
-	 * If a trap is set, not ignored and not the null command, we need
-	 * to make sure traps are executed even when a child blocks signals.
-	 */
-	if (Tflag &&
-	    trap[signo] != NULL &&
-	    ! (trap[signo][0] == '\0') &&
-	    ! (trap[signo][0] == ':' && trap[signo][1] == '\0'))
+	if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0) {
 		breakwaitcmd = 1;
+		pendingsig = signo;
+	}
+
+	if (trap[signo] != NULL && trap[signo][0] != '\0' &&
+	    (signo != SIGCHLD || !ignore_sigchld)) {
+		gotsig[signo] = 1;
+		pendingsig = signo;
+
+		/*
+		 * If a trap is set, not ignored and not the null command, we
+		 * need to make sure traps are executed even when a child
+		 * blocks signals.
+		 */
+		if (Tflag && !(trap[signo][0] == ':' && trap[signo][1] == '\0'))
+			breakwaitcmd = 1;
+	}
 
 #ifndef NO_HISTORY
 	if (signo == SIGWINCH)
@@ -424,7 +427,7 @@ dotrap(void)
 
 	in_dotrap++;
 	for (;;) {
-		pendingsigs = 0;
+		pendingsig = 0;
 		for (i = 1; i < NSIG; i++) {
 			if (gotsig[i]) {
 				gotsig[i] = 0;

Modified: projects/virtio/bin/sh/trap.h
==============================================================================
--- projects/virtio/bin/sh/trap.h	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/bin/sh/trap.h	Sun Feb 24 22:20:40 2013	(r247243)
@@ -33,7 +33,7 @@
  * $FreeBSD$
  */
 
-extern int pendingsigs;
+extern volatile sig_atomic_t pendingsig;
 extern int in_dotrap;
 extern volatile sig_atomic_t gotwinch;
 

Modified: projects/virtio/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
==============================================================================
--- projects/virtio/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c	Sun Feb 24 22:20:40 2013	(r247243)
@@ -195,6 +195,13 @@ fatal(const char *fmt, ...)
 	verror(fmt, ap);
 	va_end(ap);
 
+	/*
+	 * Close the DTrace handle to ensure that any controlled processes are
+	 * correctly restored and continued.
+	 */
+	if (g_dtp)
+		dtrace_close(g_dtp);
+
 	exit(E_ERROR);
 }
 

Modified: projects/virtio/contrib/binutils/opcodes/i386-opc.h
==============================================================================
--- projects/virtio/contrib/binutils/opcodes/i386-opc.h	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/contrib/binutils/opcodes/i386-opc.h	Sun Feb 24 22:20:40 2013	(r247243)
@@ -73,15 +73,16 @@ typedef struct template
 #define CpuSSE4_2    0x800000	/* SSE4.2 Instructions required */
 #define CpuXSAVE    0x1000000	/* XSAVE Instructions required */
 #define CpuAES      0x2000000	/* AES Instructions required */
-#define CpuPCLMUL   0x4000000	/* Carry-less Multiplication extensions */
-
-/* SSE4.1/4.2 Instructions required */
-#define CpuSSE4	     (CpuSSE4_1|CpuSSE4_2)
 
   /* These flags are set by gas depending on the flag_code.  */
 #define Cpu64	     0x4000000   /* 64bit support required  */
 #define CpuNo64      0x8000000   /* Not supported in the 64bit mode  */
 
+#define CpuPCLMUL   0x10000000	/* Carry-less Multiplication extensions */
+
+/* SSE4.1/4.2 Instructions required */
+#define CpuSSE4	     (CpuSSE4_1|CpuSSE4_2)
+
   /* The default value for unknown CPUs - enable all features to avoid problems.  */
 #define CpuUnknownFlags (Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 \
 	|CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuVMX \

Modified: projects/virtio/contrib/llvm/lib/Target/X86/X86InstrCompiler.td
==============================================================================
--- projects/virtio/contrib/llvm/lib/Target/X86/X86InstrCompiler.td	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/contrib/llvm/lib/Target/X86/X86InstrCompiler.td	Sun Feb 24 22:20:40 2013	(r247243)
@@ -1076,12 +1076,14 @@ def : Pat<(X86cmp GR64:$src1, 0),
 // inverted.
 multiclass CMOVmr<PatLeaf InvertedCond, Instruction Inst16, Instruction Inst32,
                   Instruction Inst64> {
-  def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, InvertedCond, EFLAGS),
-            (Inst16 GR16:$src2, addr:$src1)>;
-  def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, InvertedCond, EFLAGS),
-            (Inst32 GR32:$src2, addr:$src1)>;
-  def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, InvertedCond, EFLAGS),
-            (Inst64 GR64:$src2, addr:$src1)>;
+  let Predicates = [HasCMov] in {
+    def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, InvertedCond, EFLAGS),
+              (Inst16 GR16:$src2, addr:$src1)>;
+    def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, InvertedCond, EFLAGS),
+              (Inst32 GR32:$src2, addr:$src1)>;
+    def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, InvertedCond, EFLAGS),
+              (Inst64 GR64:$src2, addr:$src1)>;
+  }
 }
 
 defm : CMOVmr<X86_COND_B , CMOVAE16rm, CMOVAE32rm, CMOVAE64rm>;

Modified: projects/virtio/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
==============================================================================
--- projects/virtio/contrib/llvm/tools/clang/lib/Driver/Tools.cpp	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/contrib/llvm/tools/clang/lib/Driver/Tools.cpp	Sun Feb 24 22:20:40 2013	(r247243)
@@ -1114,10 +1114,59 @@ void Clang::AddSparcTargetArgs(const Arg
   }
 }
 
+static const char *getX86TargetCPU(const ArgList &Args,
+                                   const llvm::Triple &Triple) {
+  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+    if (StringRef(A->getValue()) != "native")
+      return A->getValue();
+
+    // FIXME: Reject attempts to use -march=native unless the target matches
+    // the host.
+    //
+    // FIXME: We should also incorporate the detected target features for use
+    // with -native.
+    std::string CPU = llvm::sys::getHostCPUName();
+    if (!CPU.empty() && CPU != "generic")
+      return Args.MakeArgString(CPU);
+  }
+
+  // Select the default CPU if none was given (or detection failed).
+
+  if (Triple.getArch() != llvm::Triple::x86_64 &&
+      Triple.getArch() != llvm::Triple::x86)
+    return 0; // This routine is only handling x86 targets.
+
+  bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
+
+  // FIXME: Need target hooks.
+  if (Triple.isOSDarwin())
+    return Is64Bit ? "core2" : "yonah";
+
+  // Everything else goes to x86-64 in 64-bit mode.
+  if (Is64Bit)
+    return "x86-64";
+
+  if (Triple.getOSName().startswith("haiku"))
+    return "i586";
+  if (Triple.getOSName().startswith("openbsd"))
+    return "i486";
+  if (Triple.getOSName().startswith("bitrig"))
+    return "i686";
+  if (Triple.getOSName().startswith("freebsd"))
+    return "i486";
+  if (Triple.getOSName().startswith("netbsd"))
+    return "i486";
+  // All x86 devices running Android have core2 as their common
+  // denominator. This makes a better choice than pentium4.
+  if (Triple.getEnvironment() == llvm::Triple::Android)
+    return "core2";
+
+  // Fallback to p4.
+  return "pentium4";
+}
+
 void Clang::AddX86TargetArgs(const ArgList &Args,
                              ArgStringList &CmdArgs) const {
-  const bool isAndroid =
-    getToolChain().getTriple().getEnvironment() == llvm::Triple::Android;
   if (!Args.hasFlag(options::OPT_mred_zone,
                     options::OPT_mno_red_zone,
                     true) ||
@@ -1130,65 +1179,7 @@ void Clang::AddX86TargetArgs(const ArgLi
                    false))
     CmdArgs.push_back("-no-implicit-float");
 
-  const char *CPUName = 0;
-  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
-    if (StringRef(A->getValue()) == "native") {
-      // FIXME: Reject attempts to use -march=native unless the target matches
-      // the host.
-      //
-      // FIXME: We should also incorporate the detected target features for use
-      // with -native.
-      std::string CPU = llvm::sys::getHostCPUName();
-      if (!CPU.empty() && CPU != "generic")
-        CPUName = Args.MakeArgString(CPU);
-    } else
-      CPUName = A->getValue();
-  }
-
-  // Select the default CPU if none was given (or detection failed).
-  if (!CPUName) {
-    // FIXME: Need target hooks.
-    if (getToolChain().getTriple().isOSDarwin()) {
-      if (getToolChain().getArch() == llvm::Triple::x86_64)
-        CPUName = "core2";
-      else if (getToolChain().getArch() == llvm::Triple::x86)
-        CPUName = "yonah";
-    } else if (getToolChain().getOS().startswith("haiku"))  {
-      if (getToolChain().getArch() == llvm::Triple::x86_64)
-        CPUName = "x86-64";
-      else if (getToolChain().getArch() == llvm::Triple::x86)
-        CPUName = "i586";
-    } else if (getToolChain().getOS().startswith("openbsd"))  {
-      if (getToolChain().getArch() == llvm::Triple::x86_64)
-        CPUName = "x86-64";
-      else if (getToolChain().getArch() == llvm::Triple::x86)
-        CPUName = "i486";
-    } else if (getToolChain().getOS().startswith("bitrig"))  {
-      if (getToolChain().getArch() == llvm::Triple::x86_64)
-        CPUName = "x86-64";
-      else if (getToolChain().getArch() == llvm::Triple::x86)
-        CPUName = "i686";
-    } else if (getToolChain().getOS().startswith("freebsd"))  {
-      if (getToolChain().getArch() == llvm::Triple::x86_64)
-        CPUName = "x86-64";
-      else if (getToolChain().getArch() == llvm::Triple::x86)
-        CPUName = "i486";
-    } else if (getToolChain().getOS().startswith("netbsd"))  {
-      if (getToolChain().getArch() == llvm::Triple::x86_64)
-        CPUName = "x86-64";
-      else if (getToolChain().getArch() == llvm::Triple::x86)
-        CPUName = "i486";
-    } else {
-      if (getToolChain().getArch() == llvm::Triple::x86_64)
-        CPUName = "x86-64";
-      else if (getToolChain().getArch() == llvm::Triple::x86)
-        // All x86 devices running Android have core2 as their common
-        // denominator. This makes a better choice than pentium4.
-        CPUName = isAndroid ? "core2" : "pentium4";
-    }
-  }
-
-  if (CPUName) {
+  if (const char *CPUName = getX86TargetCPU(Args, getToolChain().getTriple())) {
     CmdArgs.push_back("-target-cpu");
     CmdArgs.push_back(CPUName);
   }
@@ -3091,6 +3082,15 @@ void ClangAs::AddARMTargetArgs(const Arg
     addFPMathArgs(D, A, Args, CmdArgs, getARMTargetCPU(Args, Triple));
 }
 
+void ClangAs::AddX86TargetArgs(const ArgList &Args,
+                               ArgStringList &CmdArgs) const {
+  // Set the CPU based on -march=.
+  if (const char *CPUName = getX86TargetCPU(Args, getToolChain().getTriple())) {
+    CmdArgs.push_back("-target-cpu");
+    CmdArgs.push_back(CPUName);
+  }
+}
+
 /// Add options related to the Objective-C runtime/ABI.
 ///
 /// Returns true if the runtime is non-fragile.
@@ -3261,6 +3261,11 @@ void ClangAs::ConstructJob(Compilation &
   case llvm::Triple::thumb:
     AddARMTargetArgs(Args, CmdArgs);
     break;
+
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    AddX86TargetArgs(Args, CmdArgs);
+    break;
   }
 
   // Ignore explicit -force_cpusubtype_ALL option.
@@ -6068,8 +6073,27 @@ void linuxtools::Link::ConstructJob(Comp
     CmdArgs.push_back("-plugin");
     std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
     CmdArgs.push_back(Args.MakeArgString(Plugin));
+
+    // Try to pass driver level flags relevant to LTO code generation down to
+    // the plugin.
+
+    // Handle architecture-specific flags for selecting CPU variants.
+    if (ToolChain.getArch() == llvm::Triple::x86 ||
+        ToolChain.getArch() == llvm::Triple::x86_64)
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-plugin-opt=mcpu=") +
+                             getX86TargetCPU(Args, ToolChain.getTriple())));
+    else if (ToolChain.getArch() == llvm::Triple::arm ||
+             ToolChain.getArch() == llvm::Triple::thumb)
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-plugin-opt=mcpu=") +
+                             getARMTargetCPU(Args, ToolChain.getTriple())));
+
+    // FIXME: Factor out logic for MIPS, PPC, and other targets to support this
+    // as well.
   }
 
+
   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
     CmdArgs.push_back("--no-demangle");
 

Modified: projects/virtio/contrib/llvm/tools/clang/lib/Driver/Tools.h
==============================================================================
--- projects/virtio/contrib/llvm/tools/clang/lib/Driver/Tools.h	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/contrib/llvm/tools/clang/lib/Driver/Tools.h	Sun Feb 24 22:20:40 2013	(r247243)
@@ -68,6 +68,7 @@ namespace tools {
   /// \brief Clang integrated assembler tool.
   class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
     void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+    void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
   public:
     ClangAs(const ToolChain &TC) : Tool("clang::as",
                                         "clang integrated assembler", TC) {}

Modified: projects/virtio/etc/Makefile
==============================================================================
--- projects/virtio/etc/Makefile	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/etc/Makefile	Sun Feb 24 22:20:40 2013	(r247243)
@@ -354,7 +354,7 @@ distrib-dirs:
 		    ${METALOG.add} ; \
 	done; true
 .endif
-	${INSTALL_SYMLINK} usr/src/sys ${DESTDIR}/
+	${INSTALL_SYMLINK} usr/src/sys ${DESTDIR}/sys
 	cd ${DESTDIR}/usr/share/man; \
 	for mandir in man*; do \
 		${INSTALL_SYMLINK} ../$$mandir \

Modified: projects/virtio/lib/libc/gen/opendir.c
==============================================================================
--- projects/virtio/lib/libc/gen/opendir.c	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/lib/libc/gen/opendir.c	Sun Feb 24 22:20:40 2013	(r247243)
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
 #include "gen-private.h"
 #include "telldir.h"
 
-static DIR * __opendir_common(int, const char *, int);
+static DIR * __opendir_common(int, int);
 
 /*
  * Open a directory.
@@ -78,7 +78,7 @@ fdopendir(int fd)
 	}
 	if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
 		return (NULL);
-	return (__opendir_common(fd, NULL, DTF_HIDEW|DTF_NODUP));
+	return (__opendir_common(fd, DTF_HIDEW|DTF_NODUP));
 }
 
 DIR *
@@ -92,7 +92,7 @@ __opendir2(const char *name, int flags)
 	    O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC)) == -1)
 		return (NULL);
 
-	dir = __opendir_common(fd, name, flags);
+	dir = __opendir_common(fd, flags);
 	if (dir == NULL) {
 		saved_errno = errno;
 		_close(fd);
@@ -113,7 +113,7 @@ opendir_compar(const void *p1, const voi
  * Common routine for opendir(3), __opendir2(3) and fdopendir(3).
  */
 static DIR *
-__opendir_common(int fd, const char *name, int flags)
+__opendir_common(int fd, int flags)
 {
 	DIR *dirp;
 	int incr;
@@ -121,6 +121,8 @@ __opendir_common(int fd, const char *nam
 	int unionstack;
 	int fd2;
 
+	fd2 = -1;
+
 	if ((dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL)
 		return (NULL);
 
@@ -165,7 +167,22 @@ __opendir_common(int fd, const char *nam
 		 * entries into a buffer, sort the buffer, and
 		 * remove duplicate entries by setting the inode
 		 * number to zero.
+		 *
+		 * We reopen the directory because _getdirentries()
+		 * on a MNT_UNION mount modifies the open directory,
+		 * making it refer to the lower directory after the
+		 * upper directory's entries are exhausted.
+		 * This would otherwise break software that uses
+		 * the directory descriptor for fchdir or *at
+		 * functions, such as fts.c.
 		 */
+		if ((fd2 = _openat(fd, ".", O_RDONLY | O_CLOEXEC)) == -1) {
+			saved_errno = errno;
+			free(buf);
+			free(dirp);
+			errno = saved_errno;
+			return (NULL);
+		}
 
 		do {
 			/*
@@ -181,7 +198,7 @@ __opendir_common(int fd, const char *nam
 				ddptr = buf + (len - space);
 			}
 
-			n = _getdirentries(fd, ddptr, space, &dirp->dd_seek);
+			n = _getdirentries(fd2, ddptr, space, &dirp->dd_seek);
 			if (n > 0) {
 				ddptr += n;
 				space -= n;
@@ -191,25 +208,8 @@ __opendir_common(int fd, const char *nam
 		ddeptr = ddptr;
 		flags |= __DTF_READALL;
 
-		/*
-		 * Re-open the directory.
-		 * This has the effect of rewinding back to the
-		 * top of the union stack and is needed by
-		 * programs which plan to fchdir to a descriptor
-		 * which has also been read -- see fts.c.
-		 */
-		if (flags & DTF_REWIND) {
-			if ((fd2 = _open(name, O_RDONLY | O_DIRECTORY |
-			    O_CLOEXEC)) == -1) {
-				saved_errno = errno;
-				free(buf);
-				free(dirp);
-				errno = saved_errno;
-				return (NULL);
-			}
-			(void)_dup2(fd2, fd);
-			_close(fd2);
-		}
+		_close(fd2);
+		fd2 = -1;
 
 		/*
 		 * There is now a buffer full of (possibly) duplicate
@@ -293,7 +293,6 @@ __opendir_common(int fd, const char *nam
 		if (dirp->dd_buf == NULL)
 			goto fail;
 		dirp->dd_seek = 0;
-		flags &= ~DTF_REWIND;
 	}
 
 	dirp->dd_loc = 0;
@@ -310,6 +309,8 @@ __opendir_common(int fd, const char *nam
 
 fail:
 	saved_errno = errno;
+	if (fd2 != -1)
+		_close(fd2);
 	free(dirp);
 	errno = saved_errno;
 	return (NULL);

Modified: projects/virtio/lib/libc/stdlib/bsearch.3
==============================================================================
--- projects/virtio/lib/libc/stdlib/bsearch.3	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/lib/libc/stdlib/bsearch.3	Sun Feb 24 22:20:40 2013	(r247243)
@@ -32,7 +32,7 @@
 .\"     @(#)bsearch.3	8.3 (Berkeley) 4/19/94
 .\" $FreeBSD$
 .\"
-.Dd April 19, 1994
+.Dd February 22, 2013
 .Dt BSEARCH 3
 .Os
 .Sh NAME
@@ -71,6 +71,12 @@ less than, equal to, or greater than zer
 .Fa key
 object is found, respectively, to be less than, to match, or be
 greater than the array member.
+See the
+.Fa int_compare
+sample function in
+.Xr qsort 3
+for a comparison function that is also compatible with
+.Fn bsearch .
 .Sh RETURN VALUES
 The
 .Fn bsearch

Modified: projects/virtio/lib/libc/stdlib/qsort.3
==============================================================================
--- projects/virtio/lib/libc/stdlib/qsort.3	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/lib/libc/stdlib/qsort.3	Sun Feb 24 22:20:40 2013	(r247243)
@@ -205,12 +205,6 @@ functions
 return no value.
 .Pp
 .Rv -std heapsort mergesort
-.Sh COMPATIBILITY
-Previous versions of
-.Fn qsort
-did not permit the comparison routine itself to call
-.Fn qsort 3 .
-This is no longer true.
 .Sh EXAMPLES
 A sample program that sorts an array of
 .Vt int
@@ -220,7 +214,6 @@ and then prints the sorted array to stan
 .Bd -literal
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 
 /*
  * Custom comparison function that can compare 'int' values through pointers
@@ -229,15 +222,10 @@ and then prints the sorted array to stan
 static int
 int_compare(const void *p1, const void *p2)
 {
-        int *left = (int *)p1;
-        int *right = (int *)p2;
+        int left = *(const int *)p1;
+        int right = *(const int *)p2;
 
-        if (*left < *right)
-                return (-1);
-        else if (*left > *right)
-                return (1);
-        else
-                return (0);
+        return ((left > right) - (left < right));
 }
 
 /*
@@ -247,16 +235,22 @@ int
 main(void)
 {
        int int_array[] = { 4, 5, 9, 3, 0, 1, 7, 2, 8, 6 };
-       const int array_size = sizeof(int_array) / sizeof(int_array[0]);
-       int k;
+       const size_t array_size = sizeof(int_array) / sizeof(int_array[0]);
+       size_t k;
 
-       qsort(&int_array, array_size, sizeof(int), int_compare);
+       qsort(&int_array, array_size, sizeof(int_array[0]), int_compare);
        for (k = 0; k < array_size; k++)
                 printf(" %d", int_array[k]);
-        printf("\\n");
-        exit(EXIT_SUCCESS);
+        puts("");
+        return (EXIT_SUCCESS);
 }
 .Ed
+.Sh COMPATIBILITY
+Previous versions of
+.Fn qsort
+did not permit the comparison routine itself to call
+.Fn qsort 3 .
+This is no longer true.
 .Sh ERRORS
 The
 .Fn heapsort

Modified: projects/virtio/lib/libelf/elf_update.c
==============================================================================
--- projects/virtio/lib/libelf/elf_update.c	Sun Feb 24 21:42:39 2013	(r247242)
+++ projects/virtio/lib/libelf/elf_update.c	Sun Feb 24 22:20:40 2013	(r247243)
@@ -41,89 +41,79 @@ __FBSDID("$FreeBSD$");
 #include "_libelf.h"
 
 /*
- * Update the internal data structures associated with an ELF object.
- * Returns the size in bytes the ELF object would occupy in its file
- * representation.
+ * Layout strategy:
  *
- * After a successful call to this function, the following structures
- * are updated:
+ * - Case 1: ELF_F_LAYOUT is asserted
+ *     In this case the application has full control over where the
+ *     section header table, program header table, and section data
+ *     will reside.   The library only perform error checks.
  *
- * - The ELF header is updated.
- * - All sections are sorted in order of ascending addresses and their
- *   section header table entries updated.   An error is signalled
- *   if an overlap was detected among sections.
- * - All data descriptors associated with a section are sorted in order
- *   of ascending addresses.  Overlaps, if detected, are signalled as
- *   errors.  Other sanity checks for alignments, section types etc. are
- *   made.
+ * - Case 2: ELF_F_LAYOUT is not asserted
  *
- * After a resync_elf() successfully returns, the ELF descriptor is
- * ready for being handed over to _libelf_write_elf().
+ *     The library will do the object layout using the following
+ *     ordering:
+ *     - The executable header is placed first, are required by the
+ *     	 ELF specification.
+ *     - The program header table is placed immediately following the
+ *       executable header.
+ *     - Section data, if any, is placed after the program header
+ *       table, aligned appropriately.
+ *     - The section header table, if needed, is placed last.
  *
- * File alignments:
- * PHDR - Addr
- * SHDR - Addr
+ *     There are two sub-cases to be taken care of:
  *
- * XXX: how do we handle 'flags'.
+ *     - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR
+ *
+ *       In this sub-case, the underlying ELF object may already have
+ *       content in it, which the application may have modified.  The
+ *       library will retrieve content from the existing object as
+ *       needed.
+ *
+ *     - Case 2b: e->e_cmd == ELF_C_WRITE
+ *
+ *       The ELF object is being created afresh in this sub-case;
+ *       there is no pre-existing content in the underlying ELF
+ *       object.
  */
 
 /*
  * Compute the extents of a section, by looking at the data
- * descriptors associated with it.  The function returns zero if an
- * error was detected.  `*rc' holds the maximum file extent seen so
- * far.
+ * descriptors associated with it.  The function returns 1 if
+ * successful, or zero if an error was detected.
  */
 static int
-_libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t *rc)
+_libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc)
 {
 	int ec;
-	Elf_Data *d, *td;
+	size_t fsz, msz;
+	Elf_Data *d;
+	Elf32_Shdr *shdr32;
+	Elf64_Shdr *shdr64;
 	unsigned int elftype;
 	uint32_t sh_type;
 	uint64_t d_align;
 	uint64_t sh_align, sh_entsize, sh_offset, sh_size;
 	uint64_t scn_size, scn_alignment;
 
-	/*
-	 * We need to recompute library private data structures if one
-	 * or more of the following is true:
-	 * - The underlying Shdr structure has been marked `dirty'.  Significant
-	 *   fields include: `sh_offset', `sh_type', `sh_size', `sh_addralign'.
-	 * - The Elf_Data structures part of this section have been marked
-	 *   `dirty'.  Affected members include `d_align', `d_offset', `d_type',
-	 *   and `d_size'.
-	 * - The section as a whole is `dirty', e.g., it has been allocated
-	 *   using elf_newscn(), or if a new Elf_Data structure was added using
-	 *   elf_newdata().
-	 *
-	 * Each of these conditions would result in the ELF_F_DIRTY bit being
-	 * set on the section descriptor's `s_flags' field.
-	 */
-
 	ec = e->e_class;
 
+	shdr32 = &s->s_shdr.s_shdr32;
+	shdr64 = &s->s_shdr.s_shdr64;
 	if (ec == ELFCLASS32) {
-		sh_type    = s->s_shdr.s_shdr32.sh_type;
-		sh_align   = (uint64_t) s->s_shdr.s_shdr32.sh_addralign;
-		sh_entsize = (uint64_t) s->s_shdr.s_shdr32.sh_entsize;
-		sh_offset  = (uint64_t) s->s_shdr.s_shdr32.sh_offset;
-		sh_size    = (uint64_t) s->s_shdr.s_shdr32.sh_size;
+		sh_type    = shdr32->sh_type;
+		sh_align   = (uint64_t) shdr32->sh_addralign;
+		sh_entsize = (uint64_t) shdr32->sh_entsize;
+		sh_offset  = (uint64_t) shdr32->sh_offset;
+		sh_size    = (uint64_t) shdr32->sh_size;
 	} else {
-		sh_type    = s->s_shdr.s_shdr64.sh_type;
-		sh_align   = s->s_shdr.s_shdr64.sh_addralign;
-		sh_entsize = s->s_shdr.s_shdr64.sh_entsize;
-		sh_offset  = s->s_shdr.s_shdr64.sh_offset;
-		sh_size    = s->s_shdr.s_shdr64.sh_size;
+		sh_type    = shdr64->sh_type;
+		sh_align   = shdr64->sh_addralign;
+		sh_entsize = shdr64->sh_entsize;
+		sh_offset  = shdr64->sh_offset;
+		sh_size    = shdr64->sh_size;
 	}
 
-	if (sh_type == SHT_NULL || sh_type == SHT_NOBITS)
-		return (1);
-
-	if ((s->s_flags & ELF_F_DIRTY) == 0) {
-		if ((size_t) *rc < sh_offset + sh_size)
-			*rc = sh_offset + sh_size;
-		return (1);
-	}
+	assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS);
 
 	elftype = _libelf_xlate_shtype(sh_type);
 	if (elftype > ELF_T_LAST) {
@@ -131,15 +121,52 @@ _libelf_compute_section_extents(Elf *e, 
 		return (0);
 	}
 
-	/*
-	 * Compute the extent of the data descriptors associated with
-	 * this section.
-	 */
-	scn_alignment = 0;
 	if (sh_align == 0)
 		sh_align = _libelf_falign(elftype, ec);
 
-	/* Compute the section alignment. */
+	/*
+	 * Check the section's data buffers for sanity and compute the
+	 * section's alignment.
+	 * Compute the section's size and alignment using the data
+	 * descriptors associated with the section.
+	 */
+	if (STAILQ_EMPTY(&s->s_data)) {
+		/*
+		 * The section's content (if any) has not been read in
+		 * yet.  If section is not dirty marked dirty, we can
+		 * reuse the values in the 'sh_size' and 'sh_offset'
+		 * fields of the section header.
+		 */
+		if ((s->s_flags & ELF_F_DIRTY) == 0) {
+			/*
+			 * If the library is doing the layout, then we
+			 * compute the new start offset for the
+			 * section based on the current offset and the
+			 * section's alignment needs.
+			 *
+			 * If the application is doing the layout, we
+			 * can use the value in the 'sh_offset' field
+			 * in the section header directly.
+			 */
+			if (e->e_flags & ELF_F_LAYOUT)
+				goto updatedescriptor;
+			else
+				goto computeoffset;
+		}
+
+		/*
+		 * Otherwise, we need to bring in the section's data
+		 * from the underlying ELF object.
+		 */
+		if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL)
+			return (0);
+	}
+
+	/*
+	 * Loop through the section's data descriptors.
+	 */
+	scn_size = 0L;
+	scn_alignment = 0L;
 	STAILQ_FOREACH(d, &s->s_data, d_next)  {
 		if (d->d_type > ELF_T_LAST) {
 			LIBELF_SET_ERROR(DATA, 0);
@@ -153,23 +180,40 @@ _libelf_compute_section_extents(Elf *e, 
 			LIBELF_SET_ERROR(DATA, 0);
 			return (0);
 		}
-		if (d_align > scn_alignment)
-			scn_alignment = d_align;
-	}
 
-	scn_size = 0L;
+		/*
+		 * The buffer's size should be a multiple of the
+		 * memory size of the underlying type.
+		 */
+		msz = _libelf_msize(d->d_type, ec, e->e_version);
+		if (d->d_size % msz) {
+			LIBELF_SET_ERROR(DATA, 0);
+			return (0);
+		}
 
-	STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) {
+		/*
+		 * Compute the section's size.
+		 */
 		if (e->e_flags & ELF_F_LAYOUT) {
 			if ((uint64_t) d->d_off + d->d_size > scn_size)
 				scn_size = d->d_off + d->d_size;
 		} else {
 			scn_size = roundup2(scn_size, d->d_align);
 			d->d_off = scn_size;
-			scn_size += d->d_size;
+			fsz = _libelf_fsize(d->d_type, ec, d->d_version,
+			    d->d_size / msz);
+			scn_size += fsz;
 		}
+
+		/*
+		 * The section's alignment is the maximum alignment
+		 * needed for its data buffers.
+		 */
+		if (d_align > scn_alignment)
+			scn_alignment = d_align;
 	}
 
+
 	/*
 	 * If the application is requesting full control over the layout
 	 * of the section, check its values for sanity.
@@ -180,46 +224,60 @@ _libelf_compute_section_extents(Elf *e, 
 			LIBELF_SET_ERROR(LAYOUT, 0);
 			return (0);
 		}
-	} else {
-		/*
-		 * Otherwise compute the values in the section header.
-		 */
+		goto updatedescriptor;
+	}
 
-		if (scn_alignment > sh_align)
-			sh_align = scn_alignment;
+	/*
+	 * Otherwise compute the values in the section header.
+	 *
+	 * The section alignment is the maximum alignment for any of
+	 * its contained data descriptors.
+	 */
+	if (scn_alignment > sh_align)
+		sh_align = scn_alignment;
 
-		/*
-		 * If the section entry size is zero, try and fill in an
-		 * appropriate entry size.  Per the elf(5) manual page
-		 * sections without fixed-size entries should have their
-		 * 'sh_entsize' field set to zero.
-		 */
-		if (sh_entsize == 0 &&
-		    (sh_entsize = _libelf_fsize(elftype, ec, e->e_version,
-		    (size_t) 1)) == 1)
-			sh_entsize = 0;
+	/*
+	 * If the section entry size is zero, try and fill in an
+	 * appropriate entry size.  Per the elf(5) manual page
+	 * sections without fixed-size entries should have their
+	 * 'sh_entsize' field set to zero.
+	 */
+	if (sh_entsize == 0 &&
+	    (sh_entsize = _libelf_fsize(elftype, ec, e->e_version,
+	    (size_t) 1)) == 1)
+		sh_entsize = 0;
 
-		sh_size = scn_size;
-		sh_offset = roundup(*rc, sh_align);
+	sh_size = scn_size;
 
-		if (ec == ELFCLASS32) {
-			s->s_shdr.s_shdr32.sh_addralign = (uint32_t) sh_align;
-			s->s_shdr.s_shdr32.sh_entsize   = (uint32_t) sh_entsize;
-			s->s_shdr.s_shdr32.sh_offset    = (uint32_t) sh_offset;
-			s->s_shdr.s_shdr32.sh_size      = (uint32_t) sh_size;
-		} else {
-			s->s_shdr.s_shdr64.sh_addralign = sh_align;
-			s->s_shdr.s_shdr64.sh_entsize   = sh_entsize;
-			s->s_shdr.s_shdr64.sh_offset    = sh_offset;
-			s->s_shdr.s_shdr64.sh_size      = sh_size;
-		}
-	}
+computeoffset:
+	/*
+	 * Compute the new offset for the section based on
+	 * the section's alignment needs.
+	 */
+	sh_offset = roundup(rc, sh_align);
 
-	if ((size_t) *rc < sh_offset + sh_size)
-		*rc = sh_offset + sh_size;
+	/*
+	 * Update the section header.
+	 */
+	if (ec == ELFCLASS32) {
+		shdr32->sh_addralign = (uint32_t) sh_align;
+		shdr32->sh_entsize   = (uint32_t) sh_entsize;
+		shdr32->sh_offset    = (uint32_t) sh_offset;
+		shdr32->sh_size      = (uint32_t) sh_size;
+	} else {
+		shdr64->sh_addralign = sh_align;
+		shdr64->sh_entsize   = sh_entsize;
+		shdr64->sh_offset    = sh_offset;
+		shdr64->sh_size      = sh_size;
+	}
 
+updatedescriptor:
+	/*
+	 * Update the section descriptor.
+	 */
 	s->s_size = sh_size;
 	s->s_offset = sh_offset;
+
 	return (1);
 }
 
@@ -267,13 +325,16 @@ _libelf_insert_section(Elf *e, Elf_Scn *
 	return (1);
 }
 
+/*
+ * Recompute section layout.
+ */
+
 static off_t
 _libelf_resync_sections(Elf *e, off_t rc)
 {
 	int ec;
-	off_t nrc;
+	Elf_Scn *s;
 	size_t sh_type, shdr_start, shdr_end;
-	Elf_Scn *s, *ts;
 
 	ec = e->e_class;
 
@@ -281,13 +342,7 @@ _libelf_resync_sections(Elf *e, off_t rc
 	 * Make a pass through sections, computing the extent of each
 	 * section. Order in increasing order of addresses.
 	 */
-
-	nrc = rc;
-	STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next)
-		if (_libelf_compute_section_extents(e, s, &nrc) == 0)
-			return ((off_t) -1);
-
-	STAILQ_FOREACH_SAFE(s, &e->e_u.e_elf.e_scn, s_next, ts) {
+	STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) {
 		if (ec == ELFCLASS32)
 			sh_type = s->s_shdr.s_shdr32.sh_type;
 		else
@@ -296,21 +351,22 @@ _libelf_resync_sections(Elf *e, off_t rc
 		if (sh_type == SHT_NOBITS || sh_type == SHT_NULL)
 			continue;
 
-		if (s->s_offset < (uint64_t) rc) {
-			if (s->s_offset + s->s_size < (uint64_t) rc) {
-				/*
-				 * Try insert this section in the
-				 * correct place in the list,
-				 * detecting overlaps if any.
-				 */
-				STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn,
-				    s_next);
-				if (_libelf_insert_section(e, s) == 0)
-					return ((off_t) -1);
-			} else {
-				LIBELF_SET_ERROR(LAYOUT, 0);
+		if (_libelf_compute_section_extents(e, s, rc) == 0)
+			return ((off_t) -1);
+
+		if (s->s_size == 0)
+			continue;
+
+		if (s->s_offset + s->s_size < (size_t) rc) {
+			/*
+			 * Try insert this section in the
+			 * correct place in the list,
+			 * detecting overlaps if any.
+			 */
+			STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn,
+			    s_next);
+			if (_libelf_insert_section(e, s) == 0)
 				return ((off_t) -1);
-			}
 		} else

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list