svn commit: r247227 - in user/attilio/vmobj-rwlock: bin/sh contrib/llvm/lib/Target/X86 lib/libelf sbin/fsck_ffs sys/arm/arm sys/arm/broadcom/bcm2835 sys/boot/fdt sys/boot/fdt/dts sys/boot/uboot/lib...

Attilio Rao attilio at FreeBSD.org
Sun Feb 24 17:20:56 UTC 2013


Author: attilio
Date: Sun Feb 24 17:20:53 2013
New Revision: 247227
URL: http://svnweb.freebsd.org/changeset/base/247227

Log:
  MFC

Added:
  user/attilio/vmobj-rwlock/tools/regression/bin/sh/builtins/wait4.0
     - copied unchanged from r247226, head/tools/regression/bin/sh/builtins/wait4.0
  user/attilio/vmobj-rwlock/tools/regression/bin/sh/builtins/wait5.0
     - copied unchanged from r247226, head/tools/regression/bin/sh/builtins/wait5.0
Modified:
  user/attilio/vmobj-rwlock/bin/sh/eval.c
  user/attilio/vmobj-rwlock/bin/sh/jobs.c
  user/attilio/vmobj-rwlock/bin/sh/main.c
  user/attilio/vmobj-rwlock/bin/sh/trap.c
  user/attilio/vmobj-rwlock/bin/sh/trap.h
  user/attilio/vmobj-rwlock/contrib/llvm/lib/Target/X86/X86InstrCompiler.td
  user/attilio/vmobj-rwlock/lib/libelf/elf_update.c
  user/attilio/vmobj-rwlock/sbin/fsck_ffs/dir.c
  user/attilio/vmobj-rwlock/sbin/fsck_ffs/ea.c
  user/attilio/vmobj-rwlock/sbin/fsck_ffs/fsck.h
  user/attilio/vmobj-rwlock/sbin/fsck_ffs/fsutil.c
  user/attilio/vmobj-rwlock/sbin/fsck_ffs/inode.c
  user/attilio/vmobj-rwlock/sbin/fsck_ffs/main.c
  user/attilio/vmobj-rwlock/sbin/fsck_ffs/setup.c
  user/attilio/vmobj-rwlock/sys/arm/arm/machdep.c
  user/attilio/vmobj-rwlock/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
  user/attilio/vmobj-rwlock/sys/boot/fdt/dts/bcm2835-rpi-b.dts
  user/attilio/vmobj-rwlock/sys/boot/fdt/fdt_loader_cmd.c
  user/attilio/vmobj-rwlock/sys/boot/uboot/lib/elf_freebsd.c
  user/attilio/vmobj-rwlock/sys/dev/fdt/fdt_common.h
  user/attilio/vmobj-rwlock/sys/ia64/conf/GENERIC
Directory Properties:
  user/attilio/vmobj-rwlock/   (props changed)
  user/attilio/vmobj-rwlock/contrib/llvm/   (props changed)
  user/attilio/vmobj-rwlock/sbin/   (props changed)
  user/attilio/vmobj-rwlock/sys/   (props changed)
  user/attilio/vmobj-rwlock/sys/boot/   (props changed)

Modified: user/attilio/vmobj-rwlock/bin/sh/eval.c
==============================================================================
--- user/attilio/vmobj-rwlock/bin/sh/eval.c	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/bin/sh/eval.c	Sun Feb 24 17:20:53 2013	(r247227)
@@ -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: user/attilio/vmobj-rwlock/bin/sh/jobs.c
==============================================================================
--- user/attilio/vmobj-rwlock/bin/sh/jobs.c	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/bin/sh/jobs.c	Sun Feb 24 17:20:53 2013	(r247227)
@@ -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: user/attilio/vmobj-rwlock/bin/sh/main.c
==============================================================================
--- user/attilio/vmobj-rwlock/bin/sh/main.c	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/bin/sh/main.c	Sun Feb 24 17:20:53 2013	(r247227)
@@ -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: user/attilio/vmobj-rwlock/bin/sh/trap.c
==============================================================================
--- user/attilio/vmobj-rwlock/bin/sh/trap.c	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/bin/sh/trap.c	Sun Feb 24 17:20:53 2013	(r247227)
@@ -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: user/attilio/vmobj-rwlock/bin/sh/trap.h
==============================================================================
--- user/attilio/vmobj-rwlock/bin/sh/trap.h	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/bin/sh/trap.h	Sun Feb 24 17:20:53 2013	(r247227)
@@ -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: user/attilio/vmobj-rwlock/contrib/llvm/lib/Target/X86/X86InstrCompiler.td
==============================================================================
--- user/attilio/vmobj-rwlock/contrib/llvm/lib/Target/X86/X86InstrCompiler.td	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/contrib/llvm/lib/Target/X86/X86InstrCompiler.td	Sun Feb 24 17:20:53 2013	(r247227)
@@ -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: user/attilio/vmobj-rwlock/lib/libelf/elf_update.c
==============================================================================
--- user/attilio/vmobj-rwlock/lib/libelf/elf_update.c	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/lib/libelf/elf_update.c	Sun Feb 24 17:20:53 2013	(r247227)
@@ -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
 			rc = s->s_offset + s->s_size;
 	}
@@ -338,8 +394,6 @@ _libelf_resync_sections(Elf *e, off_t rc
 		}
 	}
 
-	assert(nrc == rc);
-
 	return (rc);
 }
 

Modified: user/attilio/vmobj-rwlock/sbin/fsck_ffs/dir.c
==============================================================================
--- user/attilio/vmobj-rwlock/sbin/fsck_ffs/dir.c	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/sbin/fsck_ffs/dir.c	Sun Feb 24 17:20:53 2013	(r247227)
@@ -708,6 +708,6 @@ getdirblk(ufs2_daddr_t blkno, long size)
 
 	if (pdirbp != 0)
 		pdirbp->b_flags &= ~B_INUSE;
-	pdirbp = getdatablk(blkno, size);
+	pdirbp = getdatablk(blkno, size, BT_DIRDATA);
 	return (pdirbp);
 }

Modified: user/attilio/vmobj-rwlock/sbin/fsck_ffs/ea.c
==============================================================================
--- user/attilio/vmobj-rwlock/sbin/fsck_ffs/ea.c	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/sbin/fsck_ffs/ea.c	Sun Feb 24 17:20:53 2013	(r247227)
@@ -73,7 +73,7 @@ eascan(struct inodesc *idesc, struct ufs
 	else
 		blksiz = sblock.fs_bsize;
 	printf("blksiz = %ju\n", (intmax_t)blksiz);
-	bp = getdatablk(dp->di_extb[0], blksiz);
+	bp = getdatablk(dp->di_extb[0], blksiz, BT_EXTATTR);
 	cp = (u_char *)bp->b_un.b_buf;
 	for (n = 0; n < blksiz; n++) {
 		printf("%02x", cp[n]);

Modified: user/attilio/vmobj-rwlock/sbin/fsck_ffs/fsck.h
==============================================================================
--- user/attilio/vmobj-rwlock/sbin/fsck_ffs/fsck.h	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/sbin/fsck_ffs/fsck.h	Sun Feb 24 17:20:53 2013	(r247227)
@@ -138,6 +138,7 @@ struct bufarea {
 	int b_size;
 	int b_errs;
 	int b_flags;
+	int b_type;
 	union {
 		char *b_buf;			/* buffer space */
 		ufs1_daddr_t *b_indir1;		/* UFS1 indirect block */
@@ -165,6 +166,36 @@ struct bufarea {
  * Buffer flags
  */
 #define	B_INUSE 	0x00000001	/* Buffer is in use */
+/*
+ * Type of data in buffer
+ */
+#define	BT_UNKNOWN 	 0	/* Buffer holds a superblock */
+#define	BT_SUPERBLK 	 1	/* Buffer holds a superblock */
+#define	BT_CYLGRP 	 2	/* Buffer holds a cylinder group map */
+#define	BT_LEVEL1 	 3	/* Buffer holds single level indirect */
+#define	BT_LEVEL2 	 4	/* Buffer holds double level indirect */
+#define	BT_LEVEL3 	 5	/* Buffer holds triple level indirect */
+#define	BT_EXTATTR 	 6	/* Buffer holds external attribute data */
+#define	BT_INODES 	 7	/* Buffer holds external attribute data */
+#define	BT_DIRDATA 	 8	/* Buffer holds directory data */
+#define	BT_DATA	 	 9	/* Buffer holds user data */
+#define BT_NUMBUFTYPES	10
+#define BT_NAMES {			\
+	"unknown",			\
+	"Superblock",			\
+	"Cylinder Group",		\
+	"Single Level Indirect",	\
+	"Double Level Indirect",	\
+	"Triple Level Indirect",	\
+	"External Attribute",		\
+	"Inode Block",			\
+	"Directory Contents",		\
+	"User Data" }
+long readcnt[BT_NUMBUFTYPES];
+long totalreadcnt[BT_NUMBUFTYPES];
+struct timespec readtime[BT_NUMBUFTYPES];
+struct timespec totalreadtime[BT_NUMBUFTYPES];
+struct timespec startprog;
 
 struct bufarea sblk;		/* file system superblock */
 struct bufarea cgblk;		/* cylinder group blocks */
@@ -177,10 +208,11 @@ struct bufarea *pbp;		/* current inode b
 	else \
 		(bp)->b_dirty = 1; \
 } while (0)
-#define	initbarea(bp) do { \
+#define	initbarea(bp, type) do { \
 	(bp)->b_dirty = 0; \
 	(bp)->b_bno = (ufs2_daddr_t)-1; \
 	(bp)->b_flags = 0; \
+	(bp)->b_type = type; \
 } while (0)
 
 #define	sbdirty()	dirty(&sblk)
@@ -357,6 +389,7 @@ int		dirscan(struct inodesc *);
 int		dofix(struct inodesc *, const char *msg);
 int		eascan(struct inodesc *, struct ufs2_dinode *dp);
 void		fileerror(ino_t cwd, ino_t ino, const char *errmesg);
+void		finalIOstats(void);
 int		findino(struct inodesc *);
 int		findname(struct inodesc *);
 void		flush(int fd, struct bufarea *bp);
@@ -365,7 +398,7 @@ void		freeino(ino_t ino);
 void		freeinodebuf(void);
 int		ftypeok(union dinode *dp);
 void		getblk(struct bufarea *bp, ufs2_daddr_t blk, long size);
-struct bufarea *getdatablk(ufs2_daddr_t blkno, long size);
+struct bufarea *getdatablk(ufs2_daddr_t blkno, long size, int type);
 struct inoinfo *getinoinfo(ino_t inumber);
 union dinode   *getnextinode(ino_t inumber, int rebuildcg);
 void		getpathname(char *namebuf, ino_t curdir, ino_t ino);
@@ -375,6 +408,7 @@ void		alarmhandler(int sig);
 void		inocleanup(void);
 void		inodirty(void);
 struct inostat *inoinfo(ino_t inum);
+void		IOstats(char *what);
 int		linkup(ino_t orphan, ino_t parentdir, char *name);
 int		makeentry(ino_t parent, ino_t ino, const char *name);
 void		panic(const char *fmt, ...) __printflike(1, 2);

Modified: user/attilio/vmobj-rwlock/sbin/fsck_ffs/fsutil.c
==============================================================================
--- user/attilio/vmobj-rwlock/sbin/fsck_ffs/fsutil.c	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/sbin/fsck_ffs/fsutil.c	Sun Feb 24 17:20:53 2013	(r247227)
@@ -56,19 +56,23 @@ __FBSDID("$FreeBSD$");
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "fsck.h"
 
 static void slowio_start(void);
 static void slowio_end(void);
+static void printIOstats(void);
 
-long	diskreads, totalreads;	/* Disk cache statistics */
+static long diskreads, totaldiskreads, totalreads; /* Disk cache statistics */
+static struct timespec startpass, finishpass;
 struct timeval slowio_starttime;
 int slowio_delay_usec = 10000;	/* Initial IO delay for background fsck */
 int slowio_pollcnt;
 static TAILQ_HEAD(buflist, bufarea) bufhead;	/* head of buffer cache list */
 static int numbufs;				/* size of buffer cache */
+static char *buftype[BT_NUMBUFTYPES] = BT_NAMES;
 
 int
 ftypeok(union dinode *dp)
@@ -163,7 +167,7 @@ bufinit(void)
 	if (bufp == 0)
 		errx(EEXIT, "cannot allocate buffer pool");
 	cgblk.b_un.b_buf = bufp;
-	initbarea(&cgblk);
+	initbarea(&cgblk, BT_CYLGRP);
 	TAILQ_INIT(&bufhead);
 	bufcnt = MAXBUFS;
 	if (bufcnt < MINBUFS)
@@ -178,16 +182,21 @@ bufinit(void)
 		}
 		bp->b_un.b_buf = bufp;
 		TAILQ_INSERT_HEAD(&bufhead, bp, b_list);
-		initbarea(bp);
+		initbarea(bp, BT_UNKNOWN);
 	}
 	numbufs = i;	/* save number of buffers */
+	for (i = 0; i < BT_NUMBUFTYPES; i++) {
+		readtime[i].tv_sec = totalreadtime[i].tv_sec = 0;
+		readtime[i].tv_nsec = totalreadtime[i].tv_nsec = 0;
+		readcnt[i] = totalreadcnt[i] = 0;
+	}
 }
 
 /*
  * Manage a cache of directory blocks.
  */
 struct bufarea *
-getdatablk(ufs2_daddr_t blkno, long size)
+getdatablk(ufs2_daddr_t blkno, long size, int type)
 {
 	struct bufarea *bp;
 
@@ -199,26 +208,62 @@ getdatablk(ufs2_daddr_t blkno, long size
 			break;
 	if (bp == NULL)
 		errx(EEXIT, "deadlocked buffer pool");
+	bp->b_type = type;
 	getblk(bp, blkno, size);
 	/* fall through */
 foundit:
+	if (debug && bp->b_type != type)
+		printf("Buffer type changed from %s to %s\n",
+		    buftype[bp->b_type], buftype[type]);
 	TAILQ_REMOVE(&bufhead, bp, b_list);
 	TAILQ_INSERT_HEAD(&bufhead, bp, b_list);
 	bp->b_flags |= B_INUSE;
 	return (bp);
 }
 
+/*
+ * Timespec operations (from <sys/time.h>).
+ */
+#define	timespecsub(vvp, uvp)						\
+	do {								\
+		(vvp)->tv_sec -= (uvp)->tv_sec;				\
+		(vvp)->tv_nsec -= (uvp)->tv_nsec;			\
+		if ((vvp)->tv_nsec < 0) {				\
+			(vvp)->tv_sec--;				\
+			(vvp)->tv_nsec += 1000000000;			\
+		}							\
+	} while (0)
+#define	timespecadd(vvp, uvp)						\
+	do {								\
+		(vvp)->tv_sec += (uvp)->tv_sec;				\
+		(vvp)->tv_nsec += (uvp)->tv_nsec;			\
+		if ((vvp)->tv_nsec >= 1000000000) {			\
+			(vvp)->tv_sec++;				\
+			(vvp)->tv_nsec -= 1000000000;			\
+		}							\
+	} while (0)
+
 void
 getblk(struct bufarea *bp, ufs2_daddr_t blk, long size)
 {
 	ufs2_daddr_t dblk;
+	struct timespec start, finish;
 
-	totalreads++;
 	dblk = fsbtodb(&sblock, blk);
-	if (bp->b_bno != dblk) {
+	if (bp->b_bno == dblk) {
+		totalreads++;
+	} else {
 		flush(fswritefd, bp);
-		diskreads++;
+		if (debug) {
+			readcnt[bp->b_type]++;
+			clock_gettime(CLOCK_REALTIME_PRECISE, &start);
+		}
 		bp->b_errs = blread(fsreadfd, bp->b_un.b_buf, dblk, size);
+		if (debug) {
+			clock_gettime(CLOCK_REALTIME_PRECISE, &finish);
+			timespecsub(&finish, &start);
+			timespecadd(&readtime[bp->b_type], &finish);
+		}
 		bp->b_bno = dblk;
 		bp->b_size = size;
 	}
@@ -292,8 +337,8 @@ ckfini(int markclean)
 	}
 	if (debug && totalreads > 0)
 		printf("cache with %d buffers missed %ld of %ld (%d%%)\n",
-		    numbufs, diskreads, totalreads,
-		    (int)(diskreads * 100 / totalreads));
+		    numbufs, totaldiskreads, totalreads,
+		    (int)(totaldiskreads * 100 / totalreads));
 	if (fswritefd < 0) {
 		(void)close(fsreadfd);
 		return;
@@ -347,6 +392,82 @@ ckfini(int markclean)
 	(void)close(fswritefd);
 }
 
+/*
+ * Print out I/O statistics.
+ */
+void
+IOstats(char *what)
+{
+	int i;
+
+	if (debug == 0)
+		return;
+	if (diskreads == 0) {
+		printf("%s: no I/O\n\n", what);
+		return;
+	}
+	if (startpass.tv_sec == 0)
+		startpass = startprog;
+	printf("%s: I/O statistics\n", what);
+	printIOstats();
+	totaldiskreads += diskreads;
+	diskreads = 0;
+	for (i = 0; i < BT_NUMBUFTYPES; i++) {
+		timespecadd(&totalreadtime[i], &readtime[i]);
+		totalreadcnt[i] += readcnt[i];
+		readtime[i].tv_sec = readtime[i].tv_nsec = 0;
+		readcnt[i] = 0;
+	}
+	clock_gettime(CLOCK_REALTIME_PRECISE, &startpass);
+}
+
+void
+finalIOstats(void)
+{
+	int i;
+
+	if (debug == 0)
+		return;
+	printf("Final I/O statistics\n");
+	totaldiskreads += diskreads;
+	diskreads = totaldiskreads;
+	startpass = startprog;
+	for (i = 0; i < BT_NUMBUFTYPES; i++) {
+		timespecadd(&totalreadtime[i], &readtime[i]);
+		totalreadcnt[i] += readcnt[i];
+		readtime[i] = totalreadtime[i];
+		readcnt[i] = totalreadcnt[i];
+	}
+	printIOstats();
+}
+
+static void printIOstats(void)
+{
+	long long msec, totalmsec;
+	int i;
+
+	clock_gettime(CLOCK_REALTIME_PRECISE, &finishpass);
+	timespecsub(&finishpass, &startpass);
+	printf("Running time: %ld msec\n",
+		finishpass.tv_sec * 1000 + finishpass.tv_nsec / 1000000);
+	printf("buffer reads by type:\n");
+	for (totalmsec = 0, i = 0; i < BT_NUMBUFTYPES; i++)
+		totalmsec += readtime[i].tv_sec * 1000 +
+		    readtime[i].tv_nsec / 1000000;
+	if (totalmsec == 0)
+		totalmsec = 1;
+	for (i = 0; i < BT_NUMBUFTYPES; i++) {
+		if (readcnt[i] == 0)
+			continue;
+		msec = readtime[i].tv_sec * 1000 + readtime[i].tv_nsec / 1000000;
+		printf("%21s:%8ld %2ld.%ld%% %8lld msec %2lld.%lld%%\n",
+		    buftype[i], readcnt[i], readcnt[i] * 100 / diskreads,
+		    (readcnt[i] * 1000 / diskreads) % 10, msec,
+		    msec * 100 / totalmsec, (msec * 1000 / totalmsec) % 10);
+	}
+	printf("\n");
+}
+
 int
 blread(int fd, char *buf, ufs2_daddr_t blk, long size)
 {
@@ -358,6 +479,8 @@ blread(int fd, char *buf, ufs2_daddr_t b
 	offset *= dev_bsize;
 	if (bkgrdflag)
 		slowio_start();
+	totalreads++;
+	diskreads++;
 	if (lseek(fd, offset, 0) < 0)
 		rwerror("SEEK BLK", blk);
 	else if (read(fd, buf, (int)size) == size) {

Modified: user/attilio/vmobj-rwlock/sbin/fsck_ffs/inode.c
==============================================================================
--- user/attilio/vmobj-rwlock/sbin/fsck_ffs/inode.c	Sun Feb 24 17:11:10 2013	(r247226)
+++ user/attilio/vmobj-rwlock/sbin/fsck_ffs/inode.c	Sun Feb 24 17:20:53 2013	(r247227)
@@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$");
 
 static ino_t startinum;
 
-static int iblock(struct inodesc *, long ilevel, off_t isize);
+static int iblock(struct inodesc *, long ilevel, off_t isize, int type);
 
 int
 ckinode(union dinode *dp, struct inodesc *idesc)
@@ -121,7 +121,7 @@ ckinode(union dinode *dp, struct inodesc
 		sizepb *= NINDIR(&sblock);
 		if (DIP(&dino, di_ib[i])) {
 			idesc->id_blkno = DIP(&dino, di_ib[i]);
-			ret = iblock(idesc, i + 1, remsize);
+			ret = iblock(idesc, i + 1, remsize, BT_LEVEL1 + i);
 			if (ret & STOP)
 				return (ret);
 		} else {
@@ -151,7 +151,7 @@ ckinode(union dinode *dp, struct inodesc
 }
 
 static int
-iblock(struct inodesc *idesc, long ilevel, off_t isize)
+iblock(struct inodesc *idesc, long ilevel, off_t isize, int type)
 {
 	struct bufarea *bp;
 	int i, n, (*func)(struct inodesc *), nif;
@@ -168,7 +168,7 @@ iblock(struct inodesc *idesc, long ileve
 		func = dirscan;
 	if (chkrange(idesc->id_blkno, idesc->id_numfrags))
 		return (SKIP);
-	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize);
+	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize, type);
 	ilevel--;
 	for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
 		sizepb *= NINDIR(&sblock);
@@ -199,7 +199,7 @@ iblock(struct inodesc *idesc, long ileve
 			if (ilevel == 0)
 				n = (*func)(idesc);
 			else
-				n = iblock(idesc, ilevel, isize);
+				n = iblock(idesc, ilevel, isize, type);
 			if (n & STOP) {
 				bp->b_flags &= ~B_INUSE;
 				return (n);
@@ -292,7 +292,7 @@ ginode(ino_t inumber)
 		iblk = ino_to_fsba(&sblock, inumber);
 		if (pbp != 0)
 			pbp->b_flags &= ~B_INUSE;
-		pbp = getdatablk(iblk, sblock.fs_bsize);
+		pbp = getdatablk(iblk, sblock.fs_bsize, BT_INODES);
 		startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
 	}
 	if (sblock.fs_magic == FS_UFS1_MAGIC)
@@ -306,8 +306,8 @@ ginode(ino_t inumber)
  * over all the inodes in numerical order.
  */
 static ino_t nextino, lastinum, lastvalidinum;
-static long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
-static caddr_t inodebuf;
+static long readcount, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
+static struct bufarea inobuf;
 
 union dinode *
 getnextinode(ino_t inumber, int rebuildcg)
@@ -315,7 +315,7 @@ getnextinode(ino_t inumber, int rebuildc
 	int j;
 	long size;
 	mode_t mode;
-	ufs2_daddr_t ndb, dblk;
+	ufs2_daddr_t ndb, blk;
 	union dinode *dp;
 	static caddr_t nextinop;
 
@@ -323,9 +323,9 @@ getnextinode(ino_t inumber, int rebuildc
 		errx(EEXIT, "bad inode number %ju to nextinode",
 		    (uintmax_t)inumber);
 	if (inumber >= lastinum) {
-		readcnt++;
-		dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
-		if (readcnt % readpercg == 0) {
+		readcount++;
+		blk = ino_to_fsba(&sblock, lastinum);
+		if (readcount % readpercg == 0) {
 			size = partialsize;
 			lastinum += partialcnt;
 		} else {
@@ -333,14 +333,14 @@ getnextinode(ino_t inumber, int rebuildc
 			lastinum += fullcnt;
 		}
 		/*
-		 * If blread returns an error, it will already have zeroed
+		 * If getblk encounters an error, it will already have zeroed
 		 * out the buffer, so we do not need to do so here.
 		 */
-		(void)blread(fsreadfd, inodebuf, dblk, size);
-		nextinop = inodebuf;
+		getblk(&inobuf, blk, size);
+		nextinop = inobuf.b_un.b_buf;
 	}
 	dp = (union dinode *)nextinop;
-	if (rebuildcg && nextinop == inodebuf) {
+	if (rebuildcg && nextinop == inobuf.b_un.b_buf) {
 		/*
 		 * Try to determine if we have reached the end of the
 		 * allocated inodes.
@@ -406,8 +406,8 @@ setinodebuf(ino_t inum)
 	startinum = 0;
 	nextino = inum;
 	lastinum = inum;
-	readcnt = 0;
-	if (inodebuf != NULL)
+	readcount = 0;
+	if (inobuf.b_un.b_buf != NULL)
 		return;
 	inobufsize = blkroundup(&sblock, INOBUFSIZE);
 	fullcnt = inobufsize / ((sblock.fs_magic == FS_UFS1_MAGIC) ?

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


More information about the svn-src-user mailing list