public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org,
	"Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
Subject: [PATCH 3.2 18/70] ftrace/scripts: Have recordmcount copy the object file
Date: Mon, 18 Jan 2016 03:18:35 +0000	[thread overview]
Message-ID: <lsq.1453087115.475982168@decadent.org.uk> (raw)
In-Reply-To: <lsq.1453087114.713093519@decadent.org.uk>

3.2.76-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

commit a50bd43935586420fb75f4558369eb08566fac5e upstream.

Russell King found that he had weird side effects when compiling the kernel
with hard linked ccache. The reason was that recordmcount modified the
kernel in place via mmap, and when a file gets modified twice by
recordmcount, it will complain about it. To fix this issue, Russell wrote a
patch that checked if the file was hard linked more than once and would
unlink it if it was.

Linus Torvalds was not happy with the fact that recordmcount does this in
place modification. Instead of doing the unlink only if the file has two or
more hard links, it does the unlink all the time. In otherwords, it always
does a copy if it changed something. That is, it does the write out if a
change was made.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 scripts/recordmcount.c | 145 +++++++++++++++++++++++++++++++++++++------------
 1 file changed, 110 insertions(+), 35 deletions(-)

--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -35,12 +35,17 @@
 
 static int fd_map;	/* File descriptor for file being modified. */
 static int mmap_failed; /* Boolean flag. */
-static void *ehdr_curr; /* current ElfXX_Ehdr *  for resource cleanup */
 static char gpfx;	/* prefix for global symbol name (sometimes '_') */
 static struct stat sb;	/* Remember .st_size, etc. */
 static jmp_buf jmpenv;	/* setjmp/longjmp per-file error escape */
 static const char *altmcount;	/* alternate mcount symbol name */
 static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */
+static void *file_map;	/* pointer of the mapped file */
+static void *file_end;	/* pointer to the end of the mapped file */
+static int file_updated; /* flag to state file was changed */
+static void *file_ptr;	/* current file pointer location */
+static void *file_append; /* added to the end of the file */
+static size_t file_append_size; /* how much is added to end of file */
 
 /* setjmp() return values */
 enum {
@@ -54,10 +59,14 @@ static void
 cleanup(void)
 {
 	if (!mmap_failed)
-		munmap(ehdr_curr, sb.st_size);
+		munmap(file_map, sb.st_size);
 	else
-		free(ehdr_curr);
-	close(fd_map);
+		free(file_map);
+	file_map = NULL;
+	free(file_append);
+	file_append = NULL;
+	file_append_size = 0;
+	file_updated = 0;
 }
 
 static void __attribute__((noreturn))
@@ -79,12 +88,22 @@ succeed_file(void)
 static off_t
 ulseek(int const fd, off_t const offset, int const whence)
 {
-	off_t const w = lseek(fd, offset, whence);
-	if (w == (off_t)-1) {
-		perror("lseek");
+	switch (whence) {
+	case SEEK_SET:
+		file_ptr = file_map + offset;
+		break;
+	case SEEK_CUR:
+		file_ptr += offset;
+		break;
+	case SEEK_END:
+		file_ptr = file_map + (sb.st_size - offset);
+		break;
+	}
+	if (file_ptr < file_map) {
+		fprintf(stderr, "lseek: seek before file\n");
 		fail_file();
 	}
-	return w;
+	return file_ptr - file_map;
 }
 
 static size_t
@@ -101,12 +120,38 @@ uread(int const fd, void *const buf, siz
 static size_t
 uwrite(int const fd, void const *const buf, size_t const count)
 {
-	size_t const n = write(fd, buf, count);
-	if (n != count) {
-		perror("write");
-		fail_file();
+	size_t cnt = count;
+	off_t idx = 0;
+
+	file_updated = 1;
+
+	if (file_ptr + count >= file_end) {
+		off_t aoffset = (file_ptr + count) - file_end;
+
+		if (aoffset > file_append_size) {
+			file_append = realloc(file_append, aoffset);
+			file_append_size = aoffset;
+		}
+		if (!file_append) {
+			perror("write");
+			fail_file();
+		}
+		if (file_ptr < file_end) {
+			cnt = file_end - file_ptr;
+		} else {
+			cnt = 0;
+			idx = aoffset - count;
+		}
 	}
-	return n;
+
+	if (cnt)
+		memcpy(file_ptr, buf, cnt);
+
+	if (cnt < count)
+		memcpy(file_append + idx, buf + cnt, count - cnt);
+
+	file_ptr += count;
+	return count;
 }
 
 static void *
@@ -163,9 +208,7 @@ static int make_nop_x86(void *map, size_
  */
 static void *mmap_file(char const *fname)
 {
-	void *addr;
-
-	fd_map = open(fname, O_RDWR);
+	fd_map = open(fname, O_RDONLY);
 	if (fd_map < 0 || fstat(fd_map, &sb) < 0) {
 		perror(fname);
 		fail_file();
@@ -174,29 +217,58 @@ static void *mmap_file(char const *fname
 		fprintf(stderr, "not a regular file: %s\n", fname);
 		fail_file();
 	}
-	addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
-		    fd_map, 0);
+	file_map = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
+			fd_map, 0);
 	mmap_failed = 0;
-	if (addr == MAP_FAILED) {
+	if (file_map == MAP_FAILED) {
 		mmap_failed = 1;
-		addr = umalloc(sb.st_size);
-		uread(fd_map, addr, sb.st_size);
+		file_map = umalloc(sb.st_size);
+		uread(fd_map, file_map, sb.st_size);
 	}
-	if (sb.st_nlink != 1) {
-		/* file is hard-linked, break the hard link */
-		close(fd_map);
-		if (unlink(fname) < 0) {
-			perror(fname);
-			fail_file();
-		}
-		fd_map = open(fname, O_RDWR | O_CREAT, sb.st_mode);
-		if (fd_map < 0) {
-			perror(fname);
+	close(fd_map);
+
+	file_end = file_map + sb.st_size;
+
+	return file_map;
+}
+
+static void write_file(const char *fname)
+{
+	char tmp_file[strlen(fname) + 4];
+	size_t n;
+
+	if (!file_updated)
+		return;
+
+	sprintf(tmp_file, "%s.rc", fname);
+
+	/*
+	 * After reading the entire file into memory, delete it
+	 * and write it back, to prevent weird side effects of modifying
+	 * an object file in place.
+	 */
+	fd_map = open(tmp_file, O_WRONLY | O_TRUNC | O_CREAT, sb.st_mode);
+	if (fd_map < 0) {
+		perror(fname);
+		fail_file();
+	}
+	n = write(fd_map, file_map, sb.st_size);
+	if (n != sb.st_size) {
+		perror("write");
+		fail_file();
+	}
+	if (file_append_size) {
+		n = write(fd_map, file_append, file_append_size);
+		if (n != file_append_size) {
+			perror("write");
 			fail_file();
 		}
-		uwrite(fd_map, addr, sb.st_size);
 	}
-	return addr;
+	close(fd_map);
+	if (rename(tmp_file, fname) < 0) {
+		perror(fname);
+		fail_file();
+	}
 }
 
 /* w8rev, w8nat, ...: Handle endianness. */
@@ -303,7 +375,6 @@ do_file(char const *const fname)
 	Elf32_Ehdr *const ehdr = mmap_file(fname);
 	unsigned int reltype = 0;
 
-	ehdr_curr = ehdr;
 	w = w4nat;
 	w2 = w2nat;
 	w8 = w8nat;
@@ -415,6 +486,7 @@ do_file(char const *const fname)
 	}
 	}  /* end switch */
 
+	write_file(fname);
 	cleanup();
 }
 
@@ -467,11 +539,14 @@ main(int argc, char *argv[])
 		case SJ_SETJMP:    /* normal sequence */
 			/* Avoid problems if early cleanup() */
 			fd_map = -1;
-			ehdr_curr = NULL;
 			mmap_failed = 1;
+			file_map = NULL;
+			file_ptr = NULL;
+			file_updated = 0;
 			do_file(file);
 			break;
 		case SJ_FAIL:    /* error in do_file or below */
+			sprintf("%s: failed\n", file);
 			++n_error;
 			break;
 		case SJ_SUCCEED:    /* premature success */

  parent reply	other threads:[~2016-01-18  3:35 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-18  3:18 [PATCH 3.2 00/70] 3.2.76-rc1 review Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 57/70] i2c: i801: SMBus patch for Intel Coleto Creek DeviceIDs Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 67/70] i2c: i801: Document Intel DNV and Broxton Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 13/70] mISDN: fix a loop count Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 65/70] i2c: i801: Add support for Intel DNV Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 25/70] xen/pciback: Return error on XEN_PCI_OP_enable_msi when device has MSI or MSI-X enabled Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 56/70] i2c: i801: Add Device IDs for Intel Wellsburg PCH Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 62/70] i2c: i801: Add PCI ID for Intel Braswell Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 20/70] xen: Add RING_COPY_REQUEST() Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 21/70] xen-netback: don't use last request to determine minimum Tx credit Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 41/70] ftrace/scripts: Fix incorrect use of sprintf in recordmcount Ben Hutchings
2016-01-18  3:18 ` Ben Hutchings [this message]
2016-01-18  3:18 ` [PATCH 3.2 53/70] ahci: Add Device ID for Intel Sunrise Point PCH Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 11/70] ALSA: usb-audio: Add a more accurate volume quirk for AudioQuest DragonFly Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 01/70] sctp: start t5 timer only when peer rwnd is 0 and local state is SHUTDOWN_PENDING Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 37/70] MIPS: Fix restart of indirect syscalls Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 55/70] i2c: i801: SMBus patch for Intel Avoton DeviceIDs Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 06/70] ses: Fix problems with simple enclosures Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 58/70] i2c: i801: Add Device IDs for Intel Wildcat Point-LP PCH Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 59/70] i2c: i801: enable Intel BayTrail SMBUS Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 60/70] i2c: i801: Fix the alignment of the device table Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 10/70] ALSA: tlv: add DECLARE_TLV_DB_RANGE() Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 03/70] video: fbdev: fsl: Fix kernel crash when diu_ops is not implemented Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 14/70] ser_gigaset: fix deallocation of platform device structure Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 46/70] udp: properly support MSG_PEEK with truncated buffers Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 38/70] drm/radeon: fix hotplug race at startup Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 36/70] mm/memory_hotplug.c: check for missing sections in test_pages_in_a_zone() Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 39/70] net/core: revert "net: fix __netdev_update_features return.." and add comment Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 66/70] i2c: i801: Add support for Intel Broxton Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 44/70] kvm: x86: only channel 0 of the i8254 is linked to the HPET Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 48/70] ahci: Add Device IDs for Intel Wellsburg PCH Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 15/70] spi: fix parent-device reference leak Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 49/70] ahci: Add JMicron 362 device IDs Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 07/70] ses: fix additional element traversal bug Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 27/70] xen/pciback: Do not install an IRQ handler for MSI interrupts Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 45/70] Revert "net: add length argument to skb_copy_and_csum_datagram_iovec" Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 68/70] i2c: i801: add Intel Lewisburg device IDs Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 35/70] ocfs2: fix BUG when calculate new backup super Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 42/70] net: possible use after free in dst_release Ben Hutchings
2016-01-18  3:49   ` Francesco Ruggeri
2016-01-18 11:50     ` Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 61/70] i2c: i801: Add device ID for Intel Wildcat Point PCH Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 69/70] cdrom: Random writing support for BD-RE media Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 26/70] xen/pciback: Return error on XEN_PCI_OP_enable_msix when device has MSI or MSI-X enabled Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 02/70] ipv6: sctp: fix lockdep splat in sctp_v6_get_dst() Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 54/70] ahci: Order SATA device IDs for codename Lewisburg Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 40/70] genirq: Prevent chip buslock deadlock Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 16/70] scripts: recordmcount: break hardlinks Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 31/70] USB: fix invalid memory access in hub_activate() Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 33/70] parisc: Fix syscall restarts Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 12/70] sh_eth: fix TX buffer byte-swapping Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 08/70] tty: Fix GPF in flush_to_ldisc() Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 43/70] KVM: x86: Reload pit counters for all channels when restoring state Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 05/70] rfkill: copy the name into the rfkill struct Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 51/70] ahci: Add Marvell 88se91a2 device id Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 63/70] i2c: i801: Add Device IDs for Intel Sunrise Point PCH Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 28/70] xen/pciback: For XEN_PCI_OP_disable_msi[|x] only disable if device has MSI(X) enabled Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 24/70] xen/pciback: Save xen_pci_op commands before processing it Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 19/70] s390/dis: Fix handling of format specifiers Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 52/70] ahci: add new Intel device IDs Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 04/70] crypto: skcipher - Copy iv from desc even for 0-len walks Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 30/70] USB: ipaq.c: fix a timeout loop Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 70/70] HID: dragonrise: fix HID Descriptor for 0x0006 PID Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 32/70] KEYS: Fix race between read and revoke Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 34/70] ipv6/addrlabel: fix ip6addrlbl_get() Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 47/70] vmstat: allocate vmstat_wq before it is used Ben Hutchings
2016-01-18 22:26   ` Luis Henriques
2016-01-18  3:18 ` [PATCH 3.2 23/70] xen-blkback: only read request operation from shared ring once Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 29/70] xen/pciback: Don't allow MSI-X ops if PCI_COMMAND_MEMORY is not set Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 64/70] i2c: i801: Add DeviceIDs for SunrisePoint LP Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 17/70] net: fix warnings in 'make htmldocs' by moving macro definition out of field declaration Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 09/70] ALSA: tlv: compute TLV_*_ITEM lengths automatically Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 50/70] ahci: Remove Device ID for Intel Sunrise Point PCH Ben Hutchings
2016-01-18  3:18 ` [PATCH 3.2 22/70] xen-netback: use RING_COPY_REQUEST() throughout Ben Hutchings
2016-01-18  3:45 ` [PATCH 3.2 00/70] 3.2.76-rc1 review Ben Hutchings
2016-01-18  9:12 ` Guenter Roeck
2016-01-18 11:50   ` Ben Hutchings

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=lsq.1453087115.475982168@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox