From 93c06cbbf9fea5d5be1778febb7fa9ab1a74e5f5 Mon Sep 17 00:00:00 2001 From: "Serge E. Hallyn" Date: Tue, 26 Aug 2008 14:47:57 -0500 Subject: selinux: add support for installing a dummy policy (v2) In August 2006 I posted a patch generating a minimal SELinux policy. This week, David P. Quigley posted an updated version of that as a patch against the kernel. It also had nice logic for auto-installing the policy. Following is David's original patch intro (preserved especially bc it has stats on the generated policies): se interested in the changes there were only two significant changes. The first is that the iteration through the list of classes used NULL as a sentinel value. The problem with this is that the class_to_string array actually has NULL entries in its table as place holders for the user space object classes. The second change was that it would seem at some point the initial sids table was NULL terminated. This is no longer the case so that iteration has to be done on array length instead of looking for NULL. Some statistics on the policy that it generates: The policy consists of 523 lines which contain no blank lines. Of those 523 lines 453 of them are class, permission, and initial sid definitions. These lines are usually little to no concern to the policy developer since they will not be adding object classes or permissions. Of the remaining 70 lines there is one type, one role, and one user statement. The remaining lines are broken into three portions. The first group are TE allow rules which make up 29 of the remaining lines, the second is assignment of labels to the initial sids which consist of 27 lines, and file system labeling statements which are the remaining 11. In addition to the policy.conf generated there is a single file_contexts file containing two lines which labels the entire system with base_t. This policy generates a policy.23 binary that is 7920 bytes. (then a few versions later...): The new policy is 587 lines (stripped of blank lines) with 476 of those lines being the boilerplate that I mentioned last time. The remaining 111 lines have the 3 lines for type, user, and role, 70 lines for the allow rules (one for each object class including user space object classes), 27 lines to assign types to the initial sids, and 11 lines for file system labeling. The policy binary is 9194 bytes. Changelog: Aug 26: Added Documentation/SELinux.txt Aug 26: Incorporated a set of comments by Stephen Smalley: 1. auto-setup SELINUXTYPE=dummy 2. don't auto-install if selinux is enabled with non-dummy policy 3. don't re-compute policy version 4. /sbin/setfiles not /usr/sbin/setfiles Aug 22: As per JMorris comments, made sure make distclean cleans up the mdp directory. Removed a check for file_contexts which is now created in the same file as the check, making it superfluous. Signed-off-by: Serge Hallyn Signed-off-by: David Quigley Signed-off-by: James Morris --- scripts/Makefile | 3 +- scripts/selinux/Makefile | 2 + scripts/selinux/README | 2 + scripts/selinux/install_policy.sh | 69 +++++++++++ scripts/selinux/mdp/Makefile | 5 + scripts/selinux/mdp/dbus_contexts | 6 + scripts/selinux/mdp/mdp.c | 242 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 scripts/selinux/Makefile create mode 100644 scripts/selinux/README create mode 100644 scripts/selinux/install_policy.sh create mode 100644 scripts/selinux/mdp/Makefile create mode 100644 scripts/selinux/mdp/dbus_contexts create mode 100644 scripts/selinux/mdp/mdp.c (limited to 'scripts') diff --git a/scripts/Makefile b/scripts/Makefile index 1c73c5aea66b..aafdf064feef 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -20,6 +20,7 @@ hostprogs-y += unifdef subdir-$(CONFIG_MODVERSIONS) += genksyms subdir-y += mod +subdir-$(CONFIG_SECURITY_SELINUX) += selinux # Let clean descend into subdirs -subdir- += basic kconfig package +subdir- += basic kconfig package selinux diff --git a/scripts/selinux/Makefile b/scripts/selinux/Makefile new file mode 100644 index 000000000000..ca4b1ec01822 --- /dev/null +++ b/scripts/selinux/Makefile @@ -0,0 +1,2 @@ +subdir-y := mdp +subdir- += mdp diff --git a/scripts/selinux/README b/scripts/selinux/README new file mode 100644 index 000000000000..a936315ba2c8 --- /dev/null +++ b/scripts/selinux/README @@ -0,0 +1,2 @@ +Please see Documentation/SELinux.txt for information on +installing a dummy SELinux policy. diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh new file mode 100644 index 000000000000..7b9ccf61f8f9 --- /dev/null +++ b/scripts/selinux/install_policy.sh @@ -0,0 +1,69 @@ +#!/bin/sh +if [ `id -u` -ne 0 ]; then + echo "$0: must be root to install the selinux policy" + exit 1 +fi +SF=`which setfiles` +if [ $? -eq 1 ]; then + if [ -f /sbin/setfiles ]; then + SF="/usr/setfiles" + else + echo "no selinux tools installed: setfiles" + exit 1 + fi +fi + +cd mdp + +CP=`which checkpolicy` +VERS=`$CP -V | awk '{print $1}'` + +./mdp policy.conf file_contexts +$CP -o policy.$VERS policy.conf + +mkdir -p /etc/selinux/dummy/policy +mkdir -p /etc/selinux/dummy/contexts/files + +cp file_contexts /etc/selinux/dummy/contexts/files +cp dbus_contexts /etc/selinux/dummy/contexts +cp policy.$VERS /etc/selinux/dummy/policy +FC_FILE=/etc/selinux/dummy/contexts/files/file_contexts + +if [ ! -d /etc/selinux ]; then + mkdir -p /etc/selinux +fi +if [ ! -f /etc/selinux/config ]; then + cat > /etc/selinux/config << EOF +SELINUX=enforcing +SELINUXTYPE=dummy +EOF +else + TYPE=`cat /etc/selinux/config | grep "^SELINUXTYPE" | tail -1 | awk -F= '{ print $2 '}` + if [ "eq$TYPE" != "eqdummy" ]; then + selinuxenabled + if [ $? -eq 0 ]; then + echo "SELinux already enabled with a non-dummy policy." + echo "Exiting. Please install policy by hand if that" + echo "is what you REALLY want." + exit 1 + fi + mv /etc/selinux/config /etc/selinux/config.mdpbak + grep -v "^SELINUXTYPE" /etc/selinux/config.mdpbak >> /etc/selinux/config + echo "SELINUXTYPE=dummy" >> /etc/selinux/config + fi +fi + +cd /etc/selinux/dummy/contexts/files +$SF file_contexts / + +mounts=`cat /proc/$$/mounts | egrep "ext2|ext3|xfs|jfs|ext4|ext4dev|gfs2" | awk '{ print $2 '}` +$SF file_contexts $mounts + + +dodev=`cat /proc/$$/mounts | grep "/dev "` +if [ "eq$dodev" != "eq" ]; then + mount --move /dev /mnt + $SF file_contexts /dev + mount --move /mnt /dev +fi + diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile new file mode 100644 index 000000000000..eb365b333441 --- /dev/null +++ b/scripts/selinux/mdp/Makefile @@ -0,0 +1,5 @@ +hostprogs-y := mdp +HOST_EXTRACFLAGS += -Isecurity/selinux/include + +always := $(hostprogs-y) +clean-files := $(hostprogs-y) policy.* file_contexts diff --git a/scripts/selinux/mdp/dbus_contexts b/scripts/selinux/mdp/dbus_contexts new file mode 100644 index 000000000000..116e684f9fc1 --- /dev/null +++ b/scripts/selinux/mdp/dbus_contexts @@ -0,0 +1,6 @@ + + + + + diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c new file mode 100644 index 000000000000..ca757d486187 --- /dev/null +++ b/scripts/selinux/mdp/mdp.c @@ -0,0 +1,242 @@ +/* + * + * mdp - make dummy policy + * + * When pointed at a kernel tree, builds a dummy policy for that kernel + * with exactly one type with full rights to itself. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2006 + * + * Authors: Serge E. Hallyn + */ + +#include +#include +#include +#include + +#include "flask.h" + +void usage(char *name) +{ + printf("usage: %s [-m] policy_file context_file\n", name); + exit(1); +} + +void find_common_name(char *cname, char *dest, int len) +{ + char *start, *end; + + start = strchr(cname, '_')+1; + end = strchr(start, '_'); + if (!start || !end || start-cname > len || end-start > len) { + printf("Error with commons defines\n"); + exit(1); + } + strncpy(dest, start, end-start); + dest[end-start] = '\0'; +} + +#define S_(x) x, +static char *classlist[] = { +#include "class_to_string.h" + NULL +}; +#undef S_ + +#include "initial_sid_to_string.h" + +#define TB_(x) char *x[] = { +#define TE_(x) NULL }; +#define S_(x) x, +#include "common_perm_to_string.h" +#undef TB_ +#undef TE_ +#undef S_ + +struct common { + char *cname; + char **perms; +}; +struct common common[] = { +#define TB_(x) { #x, x }, +#define S_(x) +#define TE_(x) +#include "common_perm_to_string.h" +#undef TB_ +#undef TE_ +#undef S_ +}; + +#define S_(x, y, z) {x, #y}, +struct av_inherit { + int class; + char *common; +}; +struct av_inherit av_inherit[] = { +#include "av_inherit.h" +}; +#undef S_ + +#include "av_permissions.h" +#define S_(x, y, z) {x, y, z}, +struct av_perms { + int class; + int perm_i; + char *perm_s; +}; +struct av_perms av_perms[] = { +#include "av_perm_to_string.h" +}; +#undef S_ + +int main(int argc, char *argv[]) +{ + int i, j, mls = 0; + char **arg, *polout, *ctxout; + int classlist_len, initial_sid_to_string_len; + FILE *fout; + + if (argc < 3) + usage(argv[0]); + arg = argv+1; + if (argc==4 && strcmp(argv[1], "-m") == 0) { + mls = 1; + arg++; + } + polout = *arg++; + ctxout = *arg; + + fout = fopen(polout, "w"); + if (!fout) { + printf("Could not open %s for writing\n", polout); + usage(argv[0]); + } + + classlist_len = sizeof(classlist) / sizeof(char *); + /* print out the classes */ + for (i=1; i < classlist_len; i++) { + if(classlist[i]) + fprintf(fout, "class %s\n", classlist[i]); + else + fprintf(fout, "class user%d\n", i); + } + fprintf(fout, "\n"); + + initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); + /* print out the sids */ + for (i=1; i < initial_sid_to_string_len; i++) + fprintf(fout, "sid %s\n", initial_sid_to_string[i]); + fprintf(fout, "\n"); + + /* print out the commons */ + for (i=0; i< sizeof(common)/sizeof(struct common); i++) { + char cname[101]; + find_common_name(common[i].cname, cname, 100); + cname[100] = '\0'; + fprintf(fout, "common %s\n{\n", cname); + for (j=0; common[i].perms[j]; j++) + fprintf(fout, "\t%s\n", common[i].perms[j]); + fprintf(fout, "}\n\n"); + } + fprintf(fout, "\n"); + + /* print out the class permissions */ + for (i=1; i < classlist_len; i++) { + if (classlist[i]) { + int firstperm = -1, numperms = 0; + + fprintf(fout, "class %s\n", classlist[i]); + /* does it inherit from a common? */ + for (j=0; j < sizeof(av_inherit)/sizeof(struct av_inherit); j++) + if (av_inherit[j].class == i) + fprintf(fout, "inherits %s\n", av_inherit[j].common); + + for (j=0; j < sizeof(av_perms)/sizeof(struct av_perms); j++) { + if (av_perms[j].class == i) { + if (firstperm == -1) + firstperm = j; + numperms++; + } + } + if (!numperms) { + fprintf(fout, "\n"); + continue; + } + + fprintf(fout, "{\n"); + /* print out the av_perms */ + for (j=0; j < numperms; j++) { + fprintf(fout, "\t%s\n", av_perms[firstperm+j].perm_s); + } + fprintf(fout, "}\n\n"); + } + } + fprintf(fout, "\n"); + + /* NOW PRINT OUT MLS STUFF */ + if (mls) { + printf("MLS not yet implemented\n"); + exit(1); + } + + /* types, roles, and allows */ + fprintf(fout, "type base_t;\n"); + fprintf(fout, "role base_r types { base_t };\n"); + for (i=1; i < classlist_len; i++) { + if (classlist[i]) + fprintf(fout, "allow base_t base_t:%s *;\n", classlist[i]); + else + fprintf(fout, "allow base_t base_t:user%d *;\n", i); + } + fprintf(fout, "user user_u roles { base_r };\n"); + fprintf(fout, "\n"); + + /* default sids */ + for (i=1; i < initial_sid_to_string_len; i++) + fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]); + fprintf(fout, "\n"); + + + fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n"); + fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n"); + fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n"); + fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n"); + fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); + + fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); + fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n"); + + fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n"); + fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n"); + fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n"); + + fprintf(fout, "genfscon proc / user_u:base_r:base_t\n"); + + fclose(fout); + + fout = fopen(ctxout, "w"); + if (!fout) { + printf("Wrote policy, but cannot open %s for writing\n", ctxout); + usage(argv[0]); + } + fprintf(fout, "/ user_u:base_r:base_t\n"); + fprintf(fout, "/.* user_u:base_r:base_t\n"); + fclose(fout); + + return 0; +} -- cgit v1.2.3 From b56c8c221d192e4ffa719d00907c3b60fbaa2737 Mon Sep 17 00:00:00 2001 From: James Morris Date: Fri, 5 Sep 2008 21:43:38 +1000 Subject: SELinux: add gitignore file for mdp script Add gitignore file for scripts/selinux/mdp/mdp. Signed-off-by: James Morris --- scripts/selinux/mdp/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 scripts/selinux/mdp/.gitignore (limited to 'scripts') diff --git a/scripts/selinux/mdp/.gitignore b/scripts/selinux/mdp/.gitignore new file mode 100644 index 000000000000..654546d8dffd --- /dev/null +++ b/scripts/selinux/mdp/.gitignore @@ -0,0 +1,2 @@ +# Generated file +mdp -- cgit v1.2.3 From 43789e21638626d826c0e8d62e50ceb76b9d61ed Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 8 Sep 2008 14:43:11 -0700 Subject: kbuild: fix cc-option and cc-option-yn David Sanders wrote: > I'm getting this error: > as: unrecognized option `-mtune=generic32' > I have binutils 2.17. Use -c instead of -S in cc-option and cc-option-yn, so we can probe options related to the assembler. Signed-off-by: H. Peter Anvin Cc: Sam Ravnborg Cc: kbuild devel Signed-off-by: Ingo Molnar --- scripts/Kbuild.include | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index d64e6badc942..982dcae7bbe2 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -105,12 +105,12 @@ as-instr = $(call try-run,\ # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) cc-option = $(call try-run,\ - $(CC) $(KBUILD_CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",$(1),$(2)) + $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2)) # cc-option-yn # Usage: flag := $(call cc-option-yn,-march=winchip-c6) cc-option-yn = $(call try-run,\ - $(CC) $(KBUILD_CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",y,n) + $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n) # cc-option-align # Prefix align with either -falign or -malign -- cgit v1.2.3 From 89d49841e9e7a90b04b036b7dbe7521b55edbe24 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Fri, 10 Oct 2008 21:33:30 +0200 Subject: [S390] Fix checkstack for s390 With -march=z990 and later gcc can use the long displacement facility insruction lay for stack register handling. This patch adopts checkstack to catch lay in addition to ahi and aghi. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- scripts/checkstack.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index 3eca62566d6b..f7e8e93ff30d 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -81,7 +81,10 @@ my (@stack, $re, $dre, $x, $xs); $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o; } elsif ($arch =~ /^s390x?$/) { # 11160: a7 fb ff 60 aghi %r15,-160 - $re = qr/.*ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})/o; + # or + # 100092: e3 f0 ff c8 ff 71 lay %r15,-56(%r15) + $re = qr/.*(?:lay|ag?hi).*\%r15,-(([0-9]{2}|[3-9])[0-9]{2}) + (?:\(\%r15\))?$/ox; } elsif ($arch =~ /^sh64$/) { #XXX: we only check for the immediate case presently, # though we will want to check for the movi/sub -- cgit v1.2.3 From a9860bf05f4cb94f60f8f3459908d5621f75dd06 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 24 Sep 2008 14:46:44 -0700 Subject: Staging: add TAINT_CRAP flag to drivers/staging modules We need to add a flag for all code that is in the drivers/staging/ directory to prevent all other kernel developers from worrying about issues here, and to notify users that the drivers might not be as good as they are normally used to. Based on code from Andreas Gruenbacher and Jeff Mahoney to provide a TAINT flag for the support level of a kernel module in the Novell enterprise kernel release. This is the code that actually modifies the modules, adding the flag to any files in the drivers/staging directory. Cc: Andreas Gruenbacher Cc: Jeff Mahoney Signed-off-by: Greg Kroah-Hartman --- scripts/mod/modpost.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 8e0de6a5e18a..88921611b22e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1726,6 +1726,14 @@ static void add_header(struct buffer *b, struct module *mod) buf_printf(b, "};\n"); } +void add_staging_flag(struct buffer *b, const char *name) +{ + static const char *staging_dir = "drivers/staging"; + + if (strncmp(staging_dir, name, strlen(staging_dir)) == 0) + buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); +} + /** * Record CRCs for unresolved symbols **/ @@ -2135,6 +2143,7 @@ int main(int argc, char **argv) buf.pos = 0; add_header(&buf, mod); + add_staging_flag(&buf, mod->name); err |= add_versions(&buf, mod); add_depends(&buf, mod, modules); add_moddevtable(&buf, mod); -- cgit v1.2.3 From f9b9796ade7609cd62571d38f064e20c77d31281 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 13 Sep 2008 09:36:06 -0700 Subject: Add a script to visualize the kernel boot process / time When optimizing the kernel boot time, it's very valuable to visualize what is going on at which time. In addition, with some of the initializing going asynchronous soon, it's valuable to track/print which worker thread is executing the initialization. This patch adds a script to turn a dmesg into a SVG graph (that can be shown with tools such as InkScape, Gimp or Firefox) and a small change to the initcall code to print the PID of the thread calling the initcall (so that the script can work out the parallelism). Signed-off-by: Arjan van de Ven --- scripts/bootgraph.pl | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 scripts/bootgraph.pl (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl new file mode 100644 index 000000000000..d459b8bdef02 --- /dev/null +++ b/scripts/bootgraph.pl @@ -0,0 +1,138 @@ +#!/usr/bin/perl + +# Copyright 2008, Intel Corporation +# +# This file is part of the Linux kernel +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# +# Authors: +# Arjan van de Ven + + +# +# This script turns a dmesg output into a SVG graphic that shows which +# functions take how much time. You can view SVG graphics with various +# programs, including Inkscape, The Gimp and Firefox. +# +# +# For this script to work, the kernel needs to be compiled with the +# CONFIG_PRINTK_TIME configuration option enabled, and with +# "initcall_debug" passed on the kernel command line. +# +# usage: +# dmesg | perl scripts/bootgraph.pl > output.svg +# + +my @rows; +my %start, %end, %row; +my $done = 0; +my $rowcount = 0; +my $maxtime = 0; +my $count = 0; +while (<>) { + my $line = $_; + if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z\_]+)\+/) { + my $func = $2; + if ($done == 0) { + $start{$func} = $1; + } + $row{$func} = 1; + if ($line =~ /\@ ([0-9]+)/) { + my $pid = $1; + if (!defined($rows[$pid])) { + $rowcount = $rowcount + 1; + $rows[$pid] = $rowcount; + } + $row{$func} = $rows[$pid]; + } + $count = $count + 1; + } + + if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z\_]+)\+.*returned/) { + if ($done == 0) { + $end{$2} = $1; + $maxtime = $1; + } + } + if ($line =~ /Write protecting the/) { + $done = 1; + } +} + +if ($count == 0) { + print "No data found in the dmesg. Make sure CONFIG_PRINTK_TIME is enabled and\n"; + print "that initcall_debug is passed on the kernel command line.\n\n"; + print "Usage: \n"; + print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n"; + exit; +} + +print " \n"; +print "\n"; + +my @styles; + +$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[8] = "fill:rgb(255,0,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; + +my $mult = 950.0 / $maxtime; +my $threshold = 0.0500 / $maxtime; +my $stylecounter = 0; +while (($key,$value) = each %start) { + my $duration = $end{$key} - $start{$key}; + + if ($duration >= $threshold) { + my $s, $s2, $e, $y; + $s = $value * $mult; + $s2 = $s + 6; + $e = $end{$key} * $mult; + $w = $e - $s; + + $y = $row{$key} * 150; + $y2 = $y + 4; + + $style = $styles[$stylecounter]; + $stylecounter = $stylecounter + 1; + if ($stylecounter > 11) { + $stylecounter = 0; + }; + + print "\n"; + print "$key\n"; + } +} + + +# print the time line on top +my $time = 0.0; +while ($time < $maxtime) { + my $s2 = $time * $mult; + print "$time\n"; + $time = $time + 0.1; +} + +print "\n"; -- cgit v1.2.3 From 709790a9aafe424785dd02bcb31b0dddb4ef59e4 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 14 Sep 2008 15:30:52 -0700 Subject: fastboot: fix issues and improve output of bootgraph.pl David Sanders reported some issues with bootgraph.pl's display of his sytems bootup; this commit fixes these by scaling the graph not from 0 - end time but from the first initcall to the end time; the minimum display size etc also now need to scale with this, as does the axis display. Signed-off-by: Arjan van de Ven --- scripts/bootgraph.pl | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index d459b8bdef02..4e5f4ab2ed7f 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -42,6 +42,7 @@ my %start, %end, %row; my $done = 0; my $rowcount = 0; my $maxtime = 0; +my $firsttime = 100; my $count = 0; while (<>) { my $line = $_; @@ -49,6 +50,9 @@ while (<>) { my $func = $2; if ($done == 0) { $start{$func} = $1; + if ($1 < $firsttime) { + $firsttime = $1; + } } $row{$func} = 1; if ($line =~ /\@ ([0-9]+)/) { @@ -71,6 +75,9 @@ while (<>) { if ($line =~ /Write protecting the/) { $done = 1; } + if ($line =~ /Freeing unused kernel memory/) { + $done = 1; + } } if ($count == 0) { @@ -99,17 +106,17 @@ $styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0 $styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; $styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; -my $mult = 950.0 / $maxtime; -my $threshold = 0.0500 / $maxtime; +my $mult = 950.0 / ($maxtime - $firsttime); +my $threshold = ($maxtime - $firsttime) / 60.0; my $stylecounter = 0; while (($key,$value) = each %start) { my $duration = $end{$key} - $start{$key}; if ($duration >= $threshold) { my $s, $s2, $e, $y; - $s = $value * $mult; + $s = ($value - $firsttime) * $mult; $s2 = $s + 6; - $e = $end{$key} * $mult; + $e = ($end{$key} - $firsttime) * $mult; $w = $e - $s; $y = $row{$key} * 150; @@ -128,11 +135,13 @@ while (($key,$value) = each %start) { # print the time line on top -my $time = 0.0; +my $time = $firsttime; +my $step = ($maxtime - $firsttime) / 15; while ($time < $maxtime) { - my $s2 = $time * $mult; - print "$time\n"; - $time = $time + 0.1; + my $s2 = ($time - $firsttime) * $mult; + my $tm = int($time * 100) / 100.0; + print "$tm\n"; + $time = $time + $step; } print "\n"; -- cgit v1.2.3 From 8bd9890e94627bc1ef372085e64dda7f9e307e82 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Fri, 19 Sep 2008 20:16:25 -0700 Subject: fastboot: Fix bootgraph.pl initcall name regexp The regexp used to match the start and the end of an initcall are matching only on [a-zA-Z\_]. This rules out initcalls with a number in them. This patch is fixing that. Signed-off-by: Arnaud Patard --- scripts/bootgraph.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index 4e5f4ab2ed7f..2243353fe55d 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -46,7 +46,7 @@ my $firsttime = 100; my $count = 0; while (<>) { my $line = $_; - if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z\_]+)\+/) { + if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_]+)\+/) { my $func = $2; if ($done == 0) { $start{$func} = $1; @@ -66,7 +66,7 @@ while (<>) { $count = $count + 1; } - if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z\_]+)\+.*returned/) { + if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_]+)\+.*returned/) { if ($done == 0) { $end{$2} = $1; $maxtime = $1; @@ -81,8 +81,8 @@ while (<>) { } if ($count == 0) { - print "No data found in the dmesg. Make sure CONFIG_PRINTK_TIME is enabled and\n"; - print "that initcall_debug is passed on the kernel command line.\n\n"; + print "No data found in the dmesg. Make sure that 'printk.time=1' and\n"; + print "'initcall_debug' are passed on the kernel command line.\n\n"; print "Usage: \n"; print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n"; exit; -- cgit v1.2.3 From d945b697d0eea5a811ec299c5f1a25889bb0242b Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 16 Sep 2008 16:23:28 -0700 Subject: Automatic MODULE_ALIAS() for DMI match tables. This makes modpost handle MODULE_DEVICE_TABLE(dmi, xxxx). I had to change the string pointers in the match table to char arrays, and picked a size of 79 bytes almost at random -- do we need to make it bigger than that? I was a bit concerned about the 'bloat' this introduces into the match tables, but they should all be __initdata so it shouldn't matter too much. (Actually, modpost does go through the relocations and look at most of them; it wouldn't be impossible to make it handle string pointers -- but doesn't seem to be worth the effort, since they're __initdata). Signed-off-by: David Woodhouse --- scripts/mod/file2alias.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 4c9890ec2528..473f94e56ead 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -629,6 +629,59 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id, return 1; } +static const struct dmifield { + const char *prefix; + int field; +} dmi_fields[] = { + { "bvn", DMI_BIOS_VENDOR }, + { "bvr", DMI_BIOS_VERSION }, + { "bd", DMI_BIOS_DATE }, + { "svn", DMI_SYS_VENDOR }, + { "pn", DMI_PRODUCT_NAME }, + { "pvr", DMI_PRODUCT_VERSION }, + { "rvn", DMI_BOARD_VENDOR }, + { "rn", DMI_BOARD_NAME }, + { "rvr", DMI_BOARD_VERSION }, + { "cvn", DMI_CHASSIS_VENDOR }, + { "ct", DMI_CHASSIS_TYPE }, + { "cvr", DMI_CHASSIS_VERSION }, + { NULL, DMI_NONE } +}; + +static void dmi_ascii_filter(char *d, const char *s) +{ + /* Filter out characters we don't want to see in the modalias string */ + for (; *s; s++) + if (*s > ' ' && *s < 127 && *s != ':') + *(d++) = *s; + + *d = 0; +} + + +static int do_dmi_entry(const char *filename, struct dmi_system_id *id, + char *alias) +{ + int i, j; + + sprintf(alias, "dmi*"); + + for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) { + for (j = 0; j < 4; j++) { + if (id->matches[j].slot && + id->matches[j].slot == dmi_fields[i].field) { + sprintf(alias + strlen(alias), ":%s*", + dmi_fields[i].prefix); + dmi_ascii_filter(alias + strlen(alias), + id->matches[j].substr); + strcat(alias, "*"); + } + } + } + + strcat(alias, ":"); + return 1; +} /* Ignore any prefix, eg. some architectures prepend _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -760,6 +813,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_table(symval, sym->st_size, sizeof(struct i2c_device_id), "i2c", do_i2c_entry, mod); + else if (sym_is(symname, "__mod_dmi_device_table")) + do_table(symval, sym->st_size, + sizeof(struct dmi_system_id), "dmi", + do_dmi_entry, mod); free(zeros); } -- cgit v1.2.3 From 8da3821ba5634497da63d58a69e24a97697c4a2b Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 14 Aug 2008 15:45:07 -0400 Subject: ftrace: create __mcount_loc section This patch creates a section in the kernel called "__mcount_loc". This will hold a list of pointers to the mcount relocation for each call site of mcount. For example: objdump -dr init/main.o [...] Disassembly of section .text: 0000000000000000 : 0: 55 push %rbp [...] 000000000000017b : 17b: 55 push %rbp 17c: 48 89 e5 mov %rsp,%rbp 17f: 53 push %rbx 180: 48 83 ec 08 sub $0x8,%rsp 184: e8 00 00 00 00 callq 189 185: R_X86_64_PC32 mcount+0xfffffffffffffffc [...] We will add a section to point to each function call. .section __mcount_loc,"a",@progbits [...] .quad .text + 0x185 [...] The offset to of the mcount call site in init_post is an offset from the start of the section, and not the start of the function init_post. The mcount relocation is at the call site 0x185 from the start of the .text section. .text + 0x185 == init_post + 0xa We need a way to add this __mcount_loc section in a way that we do not lose the relocations after final link. The .text section here will be attached to all other .text sections after final link and the offsets will be meaningless. We need to keep track of where these .text sections are. To do this, we use the start of the first function in the section. do_one_initcall. We can make a tmp.s file with this function as a reference to the start of the .text section. .section __mcount_loc,"a",@progbits [...] .quad do_one_initcall + 0x185 [...] Then we can compile the tmp.s into a tmp.o gcc -c tmp.s -o tmp.o And link it into back into main.o. ld -r main.o tmp.o -o tmp_main.o mv tmp_main.o main.o But we have a problem. What happens if the first function in a section is not exported, and is a static function. The linker will not let the tmp.o use it. This case exists in main.o as well. Disassembly of section .init.text: 0000000000000000 : 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: e8 00 00 00 00 callq 9 5: R_X86_64_PC32 mcount+0xfffffffffffffffc The first function in .init.text is a static function. 00000000000000a8 t __setup_set_reset_devices 000000000000105f t __setup_str_set_reset_devices 0000000000000000 t set_reset_devices The lowercase 't' means that set_reset_devices is local and is not exported. If we simply try to link the tmp.o with the set_reset_devices we end up with two symbols: one local and one global. .section __mcount_loc,"a",@progbits .quad set_reset_devices + 0x10 00000000000000a8 t __setup_set_reset_devices 000000000000105f t __setup_str_set_reset_devices 0000000000000000 t set_reset_devices U set_reset_devices We still have an undefined reference to set_reset_devices, and if we try to compile the kernel, we will end up with an undefined reference to set_reset_devices, or even worst, it could be exported someplace else, and then we will have a reference to the wrong location. To handle this case, we make an intermediate step using objcopy. We convert set_reset_devices into a global exported symbol before linking it with tmp.o and set it back afterwards. 00000000000000a8 t __setup_set_reset_devices 000000000000105f t __setup_str_set_reset_devices 0000000000000000 T set_reset_devices 00000000000000a8 t __setup_set_reset_devices 000000000000105f t __setup_str_set_reset_devices 0000000000000000 T set_reset_devices 00000000000000a8 t __setup_set_reset_devices 000000000000105f t __setup_str_set_reset_devices 0000000000000000 t set_reset_devices Now we have a section in main.o called __mcount_loc that we can place somewhere in the kernel using vmlinux.ld.S and access it to convert all these locations that call mcount into nops before starting SMP and thus, eliminating the need to do this with kstop_machine. Note, A well documented perl script (scripts/recordmcount.pl) is used to do all this in one location. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- scripts/Makefile.build | 6 ++ scripts/recordmcount.pl | 280 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 286 insertions(+) create mode 100755 scripts/recordmcount.pl (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 277cfe0b7100..463ddcc583ed 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -198,10 +198,16 @@ cmd_modversions = \ fi; endif +ifdef CONFIG_FTRACE_MCOUNT_RECORD +cmd_record_mcount = scripts/recordmcount.pl "$(ARCH)" \ + "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" "$(@)"; +endif + define rule_cc_o_c $(call echo-cmd,checksrc) $(cmd_checksrc) \ $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ $(cmd_modversions) \ + $(cmd_record_mcount) \ scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ $(dot-target).tmp; \ rm -f $(depfile); \ diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl new file mode 100755 index 000000000000..44b4b23e91b2 --- /dev/null +++ b/scripts/recordmcount.pl @@ -0,0 +1,280 @@ +#!/usr/bin/perl -w +# (c) 2008, Steven Rostedt +# Licensed under the terms of the GNU GPL License version 2 +# +# recordmcount.pl - makes a section called __mcount_loc that holds +# all the offsets to the calls to mcount. +# +# +# What we want to end up with is a section in vmlinux called +# __mcount_loc that contains a list of pointers to all the +# call sites in the kernel that call mcount. Later on boot up, the kernel +# will read this list, save the locations and turn them into nops. +# When tracing or profiling is later enabled, these locations will then +# be converted back to pointers to some function. +# +# This is no easy feat. This script is called just after the original +# object is compiled and before it is linked. +# +# The references to the call sites are offsets from the section of text +# that the call site is in. Hence, all functions in a section that +# has a call site to mcount, will have the offset from the beginning of +# the section and not the beginning of the function. +# +# The trick is to find a way to record the beginning of the section. +# The way we do this is to look at the first function in the section +# which will also be the location of that section after final link. +# e.g. +# +# .section ".text.sched" +# .globl my_func +# my_func: +# [...] +# call mcount (offset: 0x5) +# [...] +# ret +# other_func: +# [...] +# call mcount (offset: 0x1b) +# [...] +# +# Both relocation offsets for the mcounts in the above example will be +# offset from .text.sched. If we make another file called tmp.s with: +# +# .section __mcount_loc +# .quad my_func + 0x5 +# .quad my_func + 0x1b +# +# We can then compile this tmp.s into tmp.o, and link it to the original +# object. +# +# But this gets hard if my_func is not globl (a static function). +# In such a case we have: +# +# .section ".text.sched" +# my_func: +# [...] +# call mcount (offset: 0x5) +# [...] +# ret +# .globl my_func +# other_func: +# [...] +# call mcount (offset: 0x1b) +# [...] +# +# If we make the tmp.s the same as above, when we link together with +# the original object, we will end up with two symbols for my_func: +# one local, one global. After final compile, we will end up with +# an undefined reference to my_func. +# +# Since local objects can reference local variables, we need to find +# a way to make tmp.o reference the local objects of the original object +# file after it is linked together. To do this, we convert the my_func +# into a global symbol before linking tmp.o. Then after we link tmp.o +# we will only have a single symbol for my_func that is global. +# We can convert my_func back into a local symbol and we are done. +# +# Here are the steps we take: +# +# 1) Record all the local symbols by using 'nm' +# 2) Use objdump to find all the call site offsets and sections for +# mcount. +# 3) Compile the list into its own object. +# 4) Do we have to deal with local functions? If not, go to step 8. +# 5) Make an object that converts these local functions to global symbols +# with objcopy. +# 6) Link together this new object with the list object. +# 7) Convert the local functions back to local symbols and rename +# the result as the original object. +# End. +# 8) Link the object with the list object. +# 9) Move the result back to the original object. +# End. +# + +use strict; + +my $P = $0; +$P =~ s@.*/@@g; + +my $V = '0.1'; + +if ($#ARGV < 6) { + print "usage: $P arch objdump objcopy cc ld nm rm mv inputfile\n"; + print "version: $V\n"; + exit(1); +} + +my ($arch, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV; + +$objdump = "objdump" if ((length $objdump) == 0); +$objcopy = "objcopy" if ((length $objcopy) == 0); +$cc = "gcc" if ((length $cc) == 0); +$ld = "ld" if ((length $ld) == 0); +$nm = "nm" if ((length $nm) == 0); +$rm = "rm" if ((length $rm) == 0); +$mv = "mv" if ((length $mv) == 0); + +#print STDERR "running: $P '$arch' '$objdump' '$objcopy' '$cc' '$ld' " . +# "'$nm' '$rm' '$mv' '$inputfile'\n"; + +my %locals; +my %convert; + +my $type; +my $section_regex; # Find the start of a section +my $function_regex; # Find the name of a function (return func name) +my $mcount_regex; # Find the call site to mcount (return offset) + +if ($arch eq "x86_64") { + $section_regex = "Disassembly of section"; + $function_regex = "<(.*?)>:"; + $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$"; + $type = ".quad"; +} elsif ($arch eq "i386") { + $section_regex = "Disassembly of section"; + $function_regex = "<(.*?)>:"; + $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; + $type = ".long"; +} else { + die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; +} + +my $text_found = 0; +my $read_function = 0; +my $opened = 0; +my $text = ""; +my $mcount_section = "__mcount_loc"; + +my $dirname; +my $filename; +my $prefix; +my $ext; + +if ($inputfile =~ m,^(.*)/([^/]*)$,) { + $dirname = $1; + $filename = $2; +} else { + $dirname = "."; + $filename = $inputfile; +} + +if ($filename =~ m,^(.*)(\.\S),) { + $prefix = $1; + $ext = $2; +} else { + $prefix = $filename; + $ext = ""; +} + +my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s"; +my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o"; + +# +# Step 1: find all the local symbols (static functions). +# +open (IN, "$nm $inputfile|") || die "error running $nm"; +while () { + if (/^[0-9a-fA-F]+\s+t\s+(\S+)/) { + $locals{$1} = 1; + } +} +close(IN); + +# +# Step 2: find the sections and mcount call sites +# +open(IN, "$objdump -dr $inputfile|") || die "error running $objdump"; + +while () { + # is it a section? + if (/$section_regex/) { + $read_function = 1; + $text_found = 0; + # section found, now is this a start of a function? + } elsif ($read_function && /$function_regex/) { + $read_function = 0; + $text_found = 1; + $text = $1; + # is this function static? If so, note this fact. + if (defined $locals{$text}) { + $convert{$text} = 1; + } + # is this a call site to mcount? If so, print the offset from the section + } elsif ($text_found && /$mcount_regex/) { + if (!$opened) { + open(FILE, ">$mcount_s") || die "can't create $mcount_s\n"; + $opened = 1; + print FILE "\t.section $mcount_section,\"a\",\@progbits\n"; + } + print FILE "\t$type $text + 0x$1\n"; + } +} + +# If we did not find any mcount callers, we are done (do nothing). +if (!$opened) { + exit(0); +} + +close(FILE); + +# +# Step 3: Compile the file that holds the list of call sites to mcount. +# +`$cc -o $mcount_o -c $mcount_s`; + +my @converts = keys %convert; + +# +# Step 4: Do we have sections that started with local functions? +# +if ($#converts >= 0) { + my $globallist = ""; + my $locallist = ""; + + foreach my $con (@converts) { + $globallist .= " --globalize-symbol $con"; + $locallist .= " --localize-symbol $con"; + } + + my $globalobj = $dirname . "/.tmp_gl_" . $filename; + my $globalmix = $dirname . "/.tmp_mx_" . $filename; + + # + # Step 5: set up each local function as a global + # + `$objcopy $globallist $inputfile $globalobj`; + + # + # Step 6: Link the global version to our list. + # + `$ld -r $globalobj $mcount_o -o $globalmix`; + + # + # Step 7: Convert the local functions back into local symbols + # + `$objcopy $locallist $globalmix $inputfile`; + + # Remove the temp files + `$rm $globalobj $globalmix`; + +} else { + + my $mix = $dirname . "/.tmp_mx_" . $filename; + + # + # Step 8: Link the object with our list of call sites object. + # + `$ld -r $inputfile $mcount_o -o $mix`; + + # + # Step 9: Move the result back to the original object. + # + `$mv $mix $inputfile`; +} + +# Clean up the temp files +`$rm $mcount_o $mcount_s`; + +exit(0); -- cgit v1.2.3 From 3989cce82b272bd6312555fcc47c11715c157102 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jun 2008 20:54:22 +0200 Subject: ftrace: scripts/recordmcount.pl cross-build hack hack around: ld: Relocatable linking with relocations from format elf32-i386 (init/.tmp_gl_calibrate.o) to format elf64-x86-64 (init/.tmp_mx_calibrate.o) i CC arch/x86/mm/extable.o objcopy: 'init/.tmp_mx_calibrate.o': No such file rm: cannot remove `init/.tmp_mx_calibrate.o': No such file or directory ld: Relocatable linking with relocations from format elf32-i386 (arch/x86/mm/extable.o) to format elf64-x86-64 (arch/x86/mm/.tmp_mx_extable.o) is not supported mv: cannot stat `arch/x86/mm/.tmp_mx_extable.o': No such file or directory ld: Relocatable linking with relocations from format elf32-i386 (arch/x86/mm/fault.o) to format elf64-x86-64 (arch/x86/mm/.tmp_mx_fault.o) is not supported Signed-off-by: Ingo Molnar --- scripts/recordmcount.pl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 44b4b23e91b2..e4922a6c963b 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -108,6 +108,20 @@ if ($#ARGV < 6) { my ($arch, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV; +if ($arch eq "i386") { + $ld = "ld -m elf_i386"; + $objdump = "objdump -M i386"; + $objcopy = "objcopy -O elf32-i386"; + $cc = "gcc -m32"; +} + +if ($arch eq "x86_64") { + $ld = "ld -m elf_x86_64"; + $objdump = "objdump -M x86-64"; + $objcopy = "objcopy -O elf64-x86-64"; + $cc = "gcc -m64"; +} + $objdump = "objdump" if ((length $objdump) == 0); $objcopy = "objcopy" if ((length $objcopy) == 0); $cc = "gcc" if ((length $cc) == 0); -- cgit v1.2.3 From 6a4917e3ae5194a10e0723f96edc854c381e3063 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 18 Aug 2008 15:58:12 -0700 Subject: ftrace: fix build problem with CONFIG_FTRACE I'm seeing when I use separate src/build dirs: make[3]: *** [arch/x86/kernel/time_32.o] Error 1 /bin/sh: scripts/recordmcount.pl: No such file or directory make[3]: *** [arch/x86/kernel/irq_32.o] Error 1 /bin/sh: scripts/recordmcount.pl: No such file or directory make[3]: *** [arch/x86/kernel/ldt.o] Error 1 /bin/sh: scripts/recordmcount.pl: No such file or directory make[3]: *** [arch/x86/kernel/i8259.o] Error 1 /bin/sh: scripts/recordmcount.pl: No such file or directory This fixes it. Signed-off-by: Ingo Molnar --- scripts/Makefile.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 463ddcc583ed..232485ec5265 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -199,7 +199,7 @@ cmd_modversions = \ endif ifdef CONFIG_FTRACE_MCOUNT_RECORD -cmd_record_mcount = scripts/recordmcount.pl "$(ARCH)" \ +cmd_record_mcount = $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" "$(@)"; endif -- cgit v1.2.3 From d74fcd1e4e8842d5302cd303ef25cef7e67f68b4 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 15 Aug 2008 11:40:24 -0400 Subject: ftrace: update recordmount.pl arch changes I'm trying to keep all the arch changes in recordmcount.pl in one place. I moved your code into that area, by adding the flags to the commands that were passed in. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- scripts/recordmcount.pl | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index e4922a6c963b..36c8355c555e 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -108,20 +108,6 @@ if ($#ARGV < 6) { my ($arch, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV; -if ($arch eq "i386") { - $ld = "ld -m elf_i386"; - $objdump = "objdump -M i386"; - $objcopy = "objcopy -O elf32-i386"; - $cc = "gcc -m32"; -} - -if ($arch eq "x86_64") { - $ld = "ld -m elf_x86_64"; - $objdump = "objdump -M x86-64"; - $objcopy = "objcopy -O elf64-x86-64"; - $cc = "gcc -m64"; -} - $objdump = "objdump" if ((length $objdump) == 0); $objcopy = "objcopy" if ((length $objcopy) == 0); $cc = "gcc" if ((length $cc) == 0); @@ -146,11 +132,25 @@ if ($arch eq "x86_64") { $function_regex = "<(.*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$"; $type = ".quad"; + + # force flags for this arch + $ld .= " -m elf_x86_64"; + $objdump .= " -M x86-64"; + $objcopy .= " -O elf64-x86-64"; + $cc .= " -m64"; + } elsif ($arch eq "i386") { $section_regex = "Disassembly of section"; $function_regex = "<(.*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; $type = ".long"; + + # force flags for this arch + $ld .= " -m elf_i386"; + $objdump .= " -M i386"; + $objcopy .= " -O elf32-i386"; + $cc .= " -m32"; + } else { die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; } -- cgit v1.2.3 From 8feff1cacc29e9cfdc6d1ce5f2108db87b91046e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 20 Aug 2008 10:07:35 -0400 Subject: ftrace: handle weak symbol functions During tests and checks, I've discovered that there were failures to convert mcount callers into nops. Looking deeper into these failures, code that was attempted to be changed was not an mcount caller. The current code only updates if the code being changed is what it expects, but I still investigate any time there is a failure. What was happening is that a weak symbol was being used as a reference for other mcount callers. That weak symbol was also referenced elsewhere so the offsets were using the strong symbol and not the function symbol that it was referenced from. This patch changes the setting up of the mcount_loc section to search for a global function that is not weak. It will pick a local over a weak but if only a weak is found in a section, a warning is printed and the mcount location is not recorded (just to be safe). Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- scripts/recordmcount.pl | 106 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 20 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 36c8355c555e..1891cf9743fc 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -119,17 +119,19 @@ $mv = "mv" if ((length $mv) == 0); #print STDERR "running: $P '$arch' '$objdump' '$objcopy' '$cc' '$ld' " . # "'$nm' '$rm' '$mv' '$inputfile'\n"; -my %locals; -my %convert; +my %locals; # List of local (static) functions +my %weak; # List of weak functions +my %convert; # List of local functions used that needs conversion my $type; my $section_regex; # Find the start of a section -my $function_regex; # Find the name of a function (return func name) +my $function_regex; # Find the name of a function + # (return offset and func name) my $mcount_regex; # Find the call site to mcount (return offset) if ($arch eq "x86_64") { $section_regex = "Disassembly of section"; - $function_regex = "<(.*?)>:"; + $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$"; $type = ".quad"; @@ -141,7 +143,7 @@ if ($arch eq "x86_64") { } elsif ($arch eq "i386") { $section_regex = "Disassembly of section"; - $function_regex = "<(.*?)>:"; + $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; $type = ".long"; @@ -158,7 +160,6 @@ if ($arch eq "x86_64") { my $text_found = 0; my $read_function = 0; my $opened = 0; -my $text = ""; my $mcount_section = "__mcount_loc"; my $dirname; @@ -186,46 +187,111 @@ my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s"; my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o"; # -# Step 1: find all the local symbols (static functions). +# Step 1: find all the local (static functions) and weak symbols. +# 't' is local, 'w/W' is weak (we never use a weak function) # open (IN, "$nm $inputfile|") || die "error running $nm"; while () { if (/^[0-9a-fA-F]+\s+t\s+(\S+)/) { $locals{$1} = 1; + } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) { + $weak{$2} = $1; } } close(IN); +my @offsets; # Array of offsets of mcount callers +my $ref_func; # reference function to use for offsets +my $offset = 0; # offset of ref_func to section beginning + +## +# update_funcs - print out the current mcount callers +# +# Go through the list of offsets to callers and write them to +# the output file in a format that can be read by an assembler. +# +sub update_funcs +{ + return if ($#offsets < 0); + + defined($ref_func) || die "No function to reference"; + + # A section only had a weak function, to represent it. + # Unfortunately, a weak function may be overwritten by another + # function of the same name, making all these offsets incorrect. + # To be safe, we simply print a warning and bail. + if (defined $weak{$ref_func}) { + print STDERR + "$inputfile: WARNING: referencing weak function" . + " $ref_func for mcount\n"; + return; + } + + # is this function static? If so, note this fact. + if (defined $locals{$ref_func}) { + $convert{$ref_func} = 1; + } + + # Loop through all the mcount caller offsets and print a reference + # to the caller based from the ref_func. + for (my $i=0; $i <= $#offsets; $i++) { + if (!$opened) { + open(FILE, ">$mcount_s") || die "can't create $mcount_s\n"; + $opened = 1; + print FILE "\t.section $mcount_section,\"a\",\@progbits\n"; + } + printf FILE "\t%s %s + %d\n", $type, $ref_func, $offsets[$i] - $offset; + } +} + # # Step 2: find the sections and mcount call sites # open(IN, "$objdump -dr $inputfile|") || die "error running $objdump"; +my $text; + while () { # is it a section? if (/$section_regex/) { $read_function = 1; + # print out any recorded offsets + update_funcs() if ($text_found); + + # reset all markers and arrays $text_found = 0; + undef($ref_func); + undef(@offsets); + # section found, now is this a start of a function? } elsif ($read_function && /$function_regex/) { - $read_function = 0; $text_found = 1; - $text = $1; - # is this function static? If so, note this fact. - if (defined $locals{$text}) { - $convert{$text} = 1; + $offset = hex $1; + $text = $2; + + # if this is either a local function or a weak function + # keep looking for functions that are global that + # we can use safely. + if (!defined($locals{$text}) && !defined($weak{$text})) { + $ref_func = $text; + $read_function = 0; + } else { + # if we already have a function, and this is weak, skip it + if (!defined($ref_func) || !defined($weak{$text})) { + $ref_func = $text; + } } - # is this a call site to mcount? If so, print the offset from the section - } elsif ($text_found && /$mcount_regex/) { - if (!$opened) { - open(FILE, ">$mcount_s") || die "can't create $mcount_s\n"; - $opened = 1; - print FILE "\t.section $mcount_section,\"a\",\@progbits\n"; - } - print FILE "\t$type $text + 0x$1\n"; + } + + # is this a call site to mcount? If so, record it to print later + if ($text_found && /$mcount_regex/) { + $offsets[$#offsets + 1] = hex $1; } } +# dump out anymore offsets that may have been found +update_funcs() if ($text_found); + # If we did not find any mcount callers, we are done (do nothing). if (!$opened) { exit(0); -- cgit v1.2.3 From f2f8458e751f9ae41dfec3c00a46d3e62dc38f60 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 25 Aug 2008 14:52:11 -0400 Subject: ftrace: objcopy version test for local symbols The --globalize-symbols option came out in objcopy version 2.17. If the kernel is being compiled on a system with a lower version of objcopy, then we can not use the globalize / localize trick to link to symbols pointing to local functions. This patch tests the version of objcopy and will only use the trick if the version is greater than or equal to 2.17. Otherwise, if an object has only local functions within a section, it will give a nice warning and recommend the user to upgrade their objcopy. Leaving the symbols unrecorded is not that big of a deal, since the mcount record method changes the actual mcount code to be a simple "ret" without recording registers or anything. Reported-by: Stephen Rothwell Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- scripts/recordmcount.pl | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 1891cf9743fc..ee9e12676776 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -186,6 +186,36 @@ if ($filename =~ m,^(.*)(\.\S),) { my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s"; my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o"; +# +# --globalize-symbols came out in 2.17, we must test the version +# of objcopy, and if it is less than 2.17, then we can not +# record local functions. +my $use_locals = 01; +my $local_warn_once = 0; +my $found_version = 0; + +open (IN, "$objcopy --version |") || die "error running $objcopy"; +while () { + if (/objcopy.*\s(\d+)\.(\d+)/) { + my $major = $1; + my $minor = $2; + + $found_version = 1; + if ($major < 2 || + ($major == 2 && $minor < 17)) { + $use_locals = 0; + } + last; + } +} +close (IN); + +if (!$found_version) { + print STDERR "WARNING: could not find objcopy version.\n" . + "\tDisabling local function references.\n"; +} + + # # Step 1: find all the local (static functions) and weak symbols. # 't' is local, 'w/W' is weak (we never use a weak function) @@ -229,6 +259,17 @@ sub update_funcs # is this function static? If so, note this fact. if (defined $locals{$ref_func}) { + + # only use locals if objcopy supports globalize-symbols + if (!$use_locals) { + print STDERR + "$inputfile: WARNING: referencing local function " . + "$ref_func for mcount\n" . + "\tConsider upgrading objcopy to support the globalize-" . + "symbols option.\n" + if (!$local_warn_once++); + return; + } $convert{$ref_func} = 1; } -- cgit v1.2.3 From b3a320417484a6d6b9d28098944df58341353992 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 27 Aug 2008 09:08:30 +0200 Subject: kbuild: ftrace: don't assume that scripts/recordmcount.pl is executable CHK include/linux/version.h CHK include/linux/utsrelease.h CC scripts/mod/empty.o /bin/sh: /usr/src/25/scripts/recordmcount.pl: Permission denied We shouldn't assume that files have their `x' bits set. There are various ways in which file permissions get lost, including use of patch(1). It might not be correct to assume that perl lives in $PATH? Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar --- scripts/Makefile.build | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 232485ec5265..5ed4cbf1e0e1 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -199,8 +199,9 @@ cmd_modversions = \ endif ifdef CONFIG_FTRACE_MCOUNT_RECORD -cmd_record_mcount = $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ - "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" "$(@)"; +cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl \ + "$(ARCH)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" \ + "$(MV)" "$(@)"; endif define rule_cc_o_c -- cgit v1.2.3 From d53475b5aa946752e3306b2ecb5a8c9c51cf8dd0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 27 Aug 2008 13:02:01 -0400 Subject: ftrace: remove warning of old objcopy and local functions The warning messages about old objcopy and local functions spam the user quite drastically. Remove the warning until we can find a nicer way of tell the user to upgrade their objcopy. Signed-off-by: Steven Rostedt Cc: Stephen Rothwell Signed-off-by: Ingo Molnar --- scripts/recordmcount.pl | 6 ------ 1 file changed, 6 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index ee9e12676776..f56d760bd589 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -262,12 +262,6 @@ sub update_funcs # only use locals if objcopy supports globalize-symbols if (!$use_locals) { - print STDERR - "$inputfile: WARNING: referencing local function " . - "$ref_func for mcount\n" . - "\tConsider upgrading objcopy to support the globalize-" . - "symbols option.\n" - if (!$local_warn_once++); return; } $convert{$ref_func} = 1; -- cgit v1.2.3 From aa5d9151f745b6ee6a236a1f109118034277eb92 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 13 Sep 2008 09:36:06 -0700 Subject: tracing/fastboot: add a script to visualize the kernel boot process / time When optimizing the kernel boot time, it's very valuable to visualize what is going on at which time. In addition, with the fastboot asynchronous initcall level, it's very valuable to see which initcall gets run where and when. This patch adds a script to turn a dmesg into a SVG graph (that can be shown with tools such as InkScape, Gimp or Firefox) and a small change to the initcall code to print the PID of the thread calling the initcall (so that the script can work out the parallelism). Signed-off-by: Arjan van de Ven --- scripts/bootgraph.pl | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 scripts/bootgraph.pl (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl new file mode 100644 index 000000000000..d459b8bdef02 --- /dev/null +++ b/scripts/bootgraph.pl @@ -0,0 +1,138 @@ +#!/usr/bin/perl + +# Copyright 2008, Intel Corporation +# +# This file is part of the Linux kernel +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# +# Authors: +# Arjan van de Ven + + +# +# This script turns a dmesg output into a SVG graphic that shows which +# functions take how much time. You can view SVG graphics with various +# programs, including Inkscape, The Gimp and Firefox. +# +# +# For this script to work, the kernel needs to be compiled with the +# CONFIG_PRINTK_TIME configuration option enabled, and with +# "initcall_debug" passed on the kernel command line. +# +# usage: +# dmesg | perl scripts/bootgraph.pl > output.svg +# + +my @rows; +my %start, %end, %row; +my $done = 0; +my $rowcount = 0; +my $maxtime = 0; +my $count = 0; +while (<>) { + my $line = $_; + if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z\_]+)\+/) { + my $func = $2; + if ($done == 0) { + $start{$func} = $1; + } + $row{$func} = 1; + if ($line =~ /\@ ([0-9]+)/) { + my $pid = $1; + if (!defined($rows[$pid])) { + $rowcount = $rowcount + 1; + $rows[$pid] = $rowcount; + } + $row{$func} = $rows[$pid]; + } + $count = $count + 1; + } + + if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z\_]+)\+.*returned/) { + if ($done == 0) { + $end{$2} = $1; + $maxtime = $1; + } + } + if ($line =~ /Write protecting the/) { + $done = 1; + } +} + +if ($count == 0) { + print "No data found in the dmesg. Make sure CONFIG_PRINTK_TIME is enabled and\n"; + print "that initcall_debug is passed on the kernel command line.\n\n"; + print "Usage: \n"; + print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n"; + exit; +} + +print " \n"; +print "\n"; + +my @styles; + +$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[8] = "fill:rgb(255,0,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; +$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; + +my $mult = 950.0 / $maxtime; +my $threshold = 0.0500 / $maxtime; +my $stylecounter = 0; +while (($key,$value) = each %start) { + my $duration = $end{$key} - $start{$key}; + + if ($duration >= $threshold) { + my $s, $s2, $e, $y; + $s = $value * $mult; + $s2 = $s + 6; + $e = $end{$key} * $mult; + $w = $e - $s; + + $y = $row{$key} * 150; + $y2 = $y + 4; + + $style = $styles[$stylecounter]; + $stylecounter = $stylecounter + 1; + if ($stylecounter > 11) { + $stylecounter = 0; + }; + + print "\n"; + print "$key\n"; + } +} + + +# print the time line on top +my $time = 0.0; +while ($time < $maxtime) { + my $s2 = $time * $mult; + print "$time\n"; + $time = $time + 0.1; +} + +print "\n"; -- cgit v1.2.3 From ddc7a01aad195708fc943d9446411d11e3547784 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sat, 4 Oct 2008 21:35:48 +0200 Subject: tracing/fastboot: fix initcalls disposition in bootgraph.pl When bootgraph.pl parses a file, it gives one row for each initcall's pid. But only few of them will be displayed => the longest. This patch corrects it by giving only a rows for pids which have initcalls that will be displayed. [ mingo@elte.hu: resolved conflicts ] Signed-off-by: Frederic Weisbecker Acked-by: Arjan van de Ven Signed-off-by: Ingo Molnar --- scripts/bootgraph.pl | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index d459b8bdef02..c34b359c34a3 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -37,12 +37,12 @@ # dmesg | perl scripts/bootgraph.pl > output.svg # -my @rows; -my %start, %end, %row; +my %start, %end; my $done = 0; -my $rowcount = 0; my $maxtime = 0; my $count = 0; +my %pids; + while (<>) { my $line = $_; if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z\_]+)\+/) { @@ -50,14 +50,8 @@ while (<>) { if ($done == 0) { $start{$func} = $1; } - $row{$func} = 1; if ($line =~ /\@ ([0-9]+)/) { - my $pid = $1; - if (!defined($rows[$pid])) { - $rowcount = $rowcount + 1; - $rows[$pid] = $rowcount; - } - $row{$func} = $rows[$pid]; + $pids{$func} = $1; } $count = $count + 1; } @@ -102,17 +96,25 @@ $styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb( my $mult = 950.0 / $maxtime; my $threshold = 0.0500 / $maxtime; my $stylecounter = 0; +my %rows; +my $rowscount = 1; while (($key,$value) = each %start) { my $duration = $end{$key} - $start{$key}; if ($duration >= $threshold) { my $s, $s2, $e, $y; - $s = $value * $mult; + $pid = $pids{$key}; + + if (!defined($rows{$pid})) { + $rows{$pid} = $rowscount; + $rowscount = $rowscount + 1; + } + $s = ($value - $firsttime) * $mult; $s2 = $s + 6; $e = $end{$key} * $mult; $w = $e - $s; - $y = $row{$key} * 150; + $y = $rows{$pid} * 150; $y2 = $y + 4; $style = $styles[$stylecounter]; -- cgit v1.2.3 From 80a398a55d3096ff4572b44271d095413749ebb4 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 14 Sep 2008 15:30:52 -0700 Subject: tracing/fastboot: fix issues and improve output of bootgraph.pl David Sanders reported some issues with bootgraph.pl's display of his sytems bootup; this commit fixes these by scaling the graph not from 0 - end time but from the first initcall to the end time; the minimum display size etc also now need to scale with this, as does the axis display. Signed-off-by: Arjan van de Ven --- scripts/bootgraph.pl | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index c34b359c34a3..4baf49985589 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -40,6 +40,7 @@ my %start, %end; my $done = 0; my $maxtime = 0; +my $firsttime = 100; my $count = 0; my %pids; @@ -49,6 +50,9 @@ while (<>) { my $func = $2; if ($done == 0) { $start{$func} = $1; + if ($1 < $firsttime) { + $firsttime = $1; + } } if ($line =~ /\@ ([0-9]+)/) { $pids{$func} = $1; @@ -65,6 +69,9 @@ while (<>) { if ($line =~ /Write protecting the/) { $done = 1; } + if ($line =~ /Freeing unused kernel memory/) { + $done = 1; + } } if ($count == 0) { @@ -93,8 +100,8 @@ $styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0 $styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; $styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; -my $mult = 950.0 / $maxtime; -my $threshold = 0.0500 / $maxtime; +my $mult = 950.0 / ($maxtime - $firsttime); +my $threshold = ($maxtime - $firsttime) / 60.0; my $stylecounter = 0; my %rows; my $rowscount = 1; @@ -103,15 +110,9 @@ while (($key,$value) = each %start) { if ($duration >= $threshold) { my $s, $s2, $e, $y; - $pid = $pids{$key}; - - if (!defined($rows{$pid})) { - $rows{$pid} = $rowscount; - $rowscount = $rowscount + 1; - } $s = ($value - $firsttime) * $mult; $s2 = $s + 6; - $e = $end{$key} * $mult; + $e = ($end{$key} - $firsttime) * $mult; $w = $e - $s; $y = $rows{$pid} * 150; @@ -130,11 +131,13 @@ while (($key,$value) = each %start) { # print the time line on top -my $time = 0.0; +my $time = $firsttime; +my $step = ($maxtime - $firsttime) / 15; while ($time < $maxtime) { - my $s2 = $time * $mult; - print "$time\n"; - $time = $time + 0.1; + my $s2 = ($time - $firsttime) * $mult; + my $tm = int($time * 100) / 100.0; + print "$tm\n"; + $time = $time + $step; } print "\n"; -- cgit v1.2.3 From 5c542368a3ded88bed98239fb3570dda416203ee Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Fri, 19 Sep 2008 20:16:25 -0700 Subject: tracing/fastboot: fix bootgraph.pl initcall name regexp The regexp used to match the start and the end of an initcall are matching only on [a-zA-Z\_]. This rules out initcalls with a number in them. This patch is fixing that. Signed-off-by: Arnaud Patard Signed-off-by: Ingo Molnar --- scripts/bootgraph.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index 4baf49985589..479fb4ea8914 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -46,7 +46,7 @@ my %pids; while (<>) { my $line = $_; - if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z\_]+)\+/) { + if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_]+)\+/) { my $func = $2; if ($done == 0) { $start{$func} = $1; @@ -60,7 +60,7 @@ while (<>) { $count = $count + 1; } - if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z\_]+)\+.*returned/) { + if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_]+)\+.*returned/) { if ($done == 0) { $end{$2} = $1; $maxtime = $1; @@ -75,8 +75,8 @@ while (<>) { } if ($count == 0) { - print "No data found in the dmesg. Make sure CONFIG_PRINTK_TIME is enabled and\n"; - print "that initcall_debug is passed on the kernel command line.\n\n"; + print "No data found in the dmesg. Make sure that 'printk.time=1' and\n"; + print "'initcall_debug' are passed on the kernel command line.\n\n"; print "Usage: \n"; print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n"; exit; -- cgit v1.2.3 From 07d1890420cce95c577736e4d67f70cbd39845fe Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sat, 4 Oct 2008 21:35:48 +0200 Subject: tracing/fastboot: fix initcalls disposition in bootgraph.pl When bootgraph.pl parses a file, it gives one row for each initcall's pid. But only few of them will be displayed => the longest. This patch corrects it by giving only a rows for pids which have initcalls that will be displayed. Signed-off-by: Frederic Weisbecker Acked-by: Arjan van de Ven Signed-off-by: Ingo Molnar --- scripts/bootgraph.pl | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index 479fb4ea8914..5e7316e5aa39 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -110,6 +110,12 @@ while (($key,$value) = each %start) { if ($duration >= $threshold) { my $s, $s2, $e, $y; + $pid = $pids{$key}; + + if (!defined($rows{$pid})) { + $rows{$pid} = $rowscount; + $rowscount = $rowscount + 1; + } $s = ($value - $firsttime) * $mult; $s2 = $s + 6; $e = ($end{$key} - $firsttime) * $mult; -- cgit v1.2.3 From e8c84f9a5f06912c94c38961096c994da3890a2e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 19 May 2008 15:50:01 +0200 Subject: modpost: add support for hid Generate aliases for hid device modules to support autoloading. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- scripts/mod/file2alias.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 473f94e56ead..d4dc222a74f3 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -206,6 +206,20 @@ static void do_usb_table(void *symval, unsigned long size, do_usb_entry_multi(symval + i, mod); } +/* Looks like: hid:bNvNpN */ +static int do_hid_entry(const char *filename, + struct hid_device_id *id, char *alias) +{ + id->vendor = TO_NATIVE(id->vendor); + id->product = TO_NATIVE(id->product); + + sprintf(alias, "hid:b%04X", id->bus); + ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor); + ADD(alias, "p", id->product != HID_ANY_ID, id->product); + + return 1; +} + /* Looks like: ieee1394:venNmoNspNverN */ static int do_ieee1394_entry(const char *filename, struct ieee1394_device_id *id, char *alias) @@ -745,6 +759,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, else if (sym_is(symname, "__mod_usb_device_table")) /* special case to handle bcdDevice ranges */ do_usb_table(symval, sym->st_size, mod); + else if (sym_is(symname, "__mod_hid_device_table")) + do_table(symval, sym->st_size, + sizeof(struct hid_device_id), "hid", + do_hid_entry, mod); else if (sym_is(symname, "__mod_ieee1394_device_table")) do_table(symval, sym->st_size, sizeof(struct ieee1394_device_id), "ieee1394", -- cgit v1.2.3 From 346e15beb5343c2eb8216d820f2ed8f150822b08 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Tue, 12 Aug 2008 16:46:19 -0400 Subject: driver core: basic infrastructure for per-module dynamic debug messages Base infrastructure to enable per-module debug messages. I've introduced CONFIG_DYNAMIC_PRINTK_DEBUG, which when enabled centralizes control of debugging statements on a per-module basis in one /proc file, currently, /dynamic_printk/modules. When, CONFIG_DYNAMIC_PRINTK_DEBUG, is not set, debugging statements can still be enabled as before, often by defining 'DEBUG' for the proper compilation unit. Thus, this patch set has no affect when CONFIG_DYNAMIC_PRINTK_DEBUG is not set. The infrastructure currently ties into all pr_debug() and dev_dbg() calls. That is, if CONFIG_DYNAMIC_PRINTK_DEBUG is set, all pr_debug() and dev_dbg() calls can be dynamically enabled/disabled on a per-module basis. Future plans include extending this functionality to subsystems, that define their own debug levels and flags. Usage: Dynamic debugging is controlled by the debugfs file, /dynamic_printk/modules. This file contains a list of the modules that can be enabled. The format of the file is as follows: . . . : Name of the module in which the debug call resides : whether the messages are enabled or not For example: snd_hda_intel enabled=0 fixup enabled=1 driver enabled=0 Enable a module: $echo "set enabled=1 " > dynamic_printk/modules Disable a module: $echo "set enabled=0 " > dynamic_printk/modules Enable all modules: $echo "set enabled=1 all" > dynamic_printk/modules Disable all modules: $echo "set enabled=0 all" > dynamic_printk/modules Finally, passing "dynamic_printk" at the command line enables debugging for all modules. This mode can be turned off via the above disable command. [gkh: minor cleanups and tweaks to make the build work quietly] Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- scripts/Makefile.lib | 11 ++++++++- scripts/basic/Makefile | 2 +- scripts/basic/hash.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 scripts/basic/hash.c (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index ea48b82a3707..b4ca38a21158 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") +#hash values +ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\ + -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))" +else +debug_flags = +endif + orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o) @@ -121,7 +129,8 @@ endif c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__c_flags) $(modkern_cflags) \ - -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ + $(debug_flags) a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__a_flags) $(modkern_aflags) diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index 4c324a1f1e0e..09559951df12 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -9,7 +9,7 @@ # fixdep: Used to generate dependency information during build process # docproc: Used in Documentation/DocBook -hostprogs-y := fixdep docproc +hostprogs-y := fixdep docproc hash always := $(hostprogs-y) # fixdep is needed to compile other host programs diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c new file mode 100644 index 000000000000..3299ad7fc8c0 --- /dev/null +++ b/scripts/basic/hash.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008 Red Hat, Inc., Jason Baron + * + */ + +#include +#include +#include + +#define DYNAMIC_DEBUG_HASH_BITS 6 + +static const char *program; + +static void usage(void) +{ + printf("Usage: %s \n", program); + exit(1); +} + +/* djb2 hashing algorithm by Dan Bernstein. From: + * http://www.cse.yorku.ca/~oz/hash.html + */ + +unsigned int djb2_hash(char *str) +{ + unsigned long hash = 5381; + int c; + + c = *str; + while (c) { + hash = ((hash << 5) + hash) + c; + c = *++str; + } + return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1)); +} + +unsigned int r5_hash(char *str) +{ + unsigned long hash = 0; + int c; + + c = *str; + while (c) { + hash = (hash + (c << 4) + (c >> 4)) * 11; + c = *++str; + } + return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1)); +} + +int main(int argc, char *argv[]) +{ + program = argv[0]; + + if (argc != 3) + usage(); + if (!strcmp(argv[1], "djb2")) + printf("%d\n", djb2_hash(argv[2])); + else if (!strcmp(argv[1], "r5")) + printf("%d\n", r5_hash(argv[2])); + else + usage(); + exit(0); +} + -- cgit v1.2.3 From fe2a7dbc85f37c721133c83c856f845c4ce9b602 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:15 -0700 Subject: checkpatch: square brackets -- exemption for array slices in braces It is wholy reasonable to have square brackets representing array slices in braces on the same line. These should be spaced. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index bc6779398229..6f821a0e0024 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1493,11 +1493,13 @@ sub process { # check for spacing round square brackets; allowed: # 1. with a type on the left -- int [] a; -# 2. at the beginning of a line for slice initialisers -- [0..10] = 5, +# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, +# 3. inside a curly brace -- = { [0...10] = 5 } while ($line =~ /(.*?\s)\[/g) { my ($where, $prefix) = ($-[1], $1); if ($prefix !~ /$Type\s+$/ && - ($where != 0 || $prefix !~ /^.\s+$/)) { + ($where != 0 || $prefix !~ /^.\s+$/) && + $prefix !~ /{\s+$/) { ERROR("space prohibited before open square bracket '['\n" . $herecurr); } } -- cgit v1.2.3 From 0d413866c7df63794790518e3fd5890969c206ad Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:16 -0700 Subject: checkpatch: values: double ampersand may be unary It is possible to use double ampersand (&&) in unary context where it means the address of a goto label. Handle spacing for it. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6f821a0e0024..114821364c00 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -858,7 +858,7 @@ sub annotate_values { print "CLOSE($1)\n" if ($dbg_values > 1); $type = 'N'; - } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&(?!\&))/o) { + } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { my $variant; print "OPV($1)\n" if ($dbg_values > 1); @@ -1634,7 +1634,7 @@ sub process { # unary operator, or a cast } elsif ($op eq '!' || $op eq '~' || $opv eq '*U' || $opv eq '-U' || - $opv eq '&U') { + $opv eq '&U' || $opv eq '&&U') { if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { ERROR("space required before that '$op' $at\n" . $hereptr); } -- cgit v1.2.3 From 14b111c158116f02c1c862397075e28ac12d65d6 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:16 -0700 Subject: checkpatch: conditional indent -- labels have different indent rules Labels have different indent rules and must be ignored when checking the conditional indent levels. Also correct identify labels in single statement conditionals. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 114821364c00..1e7d2cdd0c20 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -782,9 +782,9 @@ sub annotate_values { } $type = 'N'; - } elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) { + } elsif ($cur =~ /^(if|while|for)\b/o) { print "COND($1)\n" if ($dbg_values > 1); - $av_pending = 'N'; + $av_pending = 'E'; $type = 'N'; } elsif ($cur =~/^(case)/o) { @@ -792,7 +792,7 @@ sub annotate_values { $av_pend_colon = 'C'; $type = 'N'; - } elsif ($cur =~/^(return|else|goto)/o) { + } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { print "KEYWORD($1)\n" if ($dbg_values > 1); $type = 'N'; @@ -1846,6 +1846,11 @@ sub process { $check = 0; } + # Ignore the current line if it is label. + if ($s =~ /^\s*$Ident\s*:/) { + $check = 0; + } + my (undef, $sindent) = line_stats("+" . $s); ##print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s>\n"; -- cgit v1.2.3 From 1bdab9e5881fde3bf66528db5b91477ce4b35b3b Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:17 -0700 Subject: checkpatch: switch indent allow plain return It is a common and sane idiom to allow a single return on the end of a case statement: switch (...) { case foo: return bar; } Add an exception for this. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 1e7d2cdd0c20..c6782ac6f130 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1295,7 +1295,11 @@ sub process { } } if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && - $line !~ /\G(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$/g) { + $line !~ /\G(?: + (?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| + \s*return\s+ + )/xg) + { ERROR("trailing statements should be on next line\n" . $herecurr); } -- cgit v1.2.3 From a1ef277e2c88c80cfa00580469133e2215442c8d Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:17 -0700 Subject: checkpatch: add tests for the attribute matcher Add support for direct testing of the attribute matcher, add basic tests for it. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c6782ac6f130..1c032b1fa9eb 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -66,6 +66,7 @@ if ($#ARGV < 0) { my $dbg_values = 0; my $dbg_possible = 0; my $dbg_type = 0; +my $dbg_attr = 0; for my $key (keys %debug) { eval "\${dbg_$key} = '$debug{$key}';" } @@ -1367,6 +1368,15 @@ sub process { } next; } +# TEST: allow direct testing of the attribute matcher. + if ($dbg_attr) { + if ($line =~ /^.\s*$Attribute\s*$/) { + ERROR("TEST: is attr\n" . $herecurr); + } elsif ($dbg_attr > 1 && $line =~ /^.+($Attribute)/) { + ERROR("TEST: is not attr ($1 is)\n". $herecurr); + } + next; + } # check for initialisation to aggregates open brace on the next line if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ && -- cgit v1.2.3 From 24e1d81acd447c3a7ec9eb90f24c00edc5a4b09f Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:18 -0700 Subject: checkpatch: ____cacheline_aligned et al are modifiers Add the cacheline alignment modifiers to the attribute lists. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 1c032b1fa9eb..303c3634198b 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -113,7 +113,10 @@ our $Attribute = qr{ const| __read_mostly| __kprobes| - __(?:mem|cpu|dev|)(?:initdata|init) + __(?:mem|cpu|dev|)(?:initdata|init)| + ____cacheline_aligned| + ____cacheline_aligned_in_smp| + ____cacheline_internodealigned_in_smp }x; our $Modifier; our $Inline = qr{inline|__always_inline|noinline}; -- cgit v1.2.3 From 636d140a80912693be466e8d978e658189972989 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:18 -0700 Subject: checkpatch: complex macros -- fix up extension handling Only pull in new extension lines where the current contents ends with a \. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 303c3634198b..586f9a4f0ad0 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1977,8 +1977,8 @@ sub process { # Extract the remainder of the define (if any) and # rip off surrounding spaces, and trailing \'s. $rest = ''; - while ($off != 0 || ($cnt > 0 && $rest =~ /(?:^|\\)\s*$/)) { - #print "ADDING $off <" . substr($lines[$ln - 1], $off) . ">\n"; + while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) { + #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n"; if ($off != 0 || $lines[$ln - 1] !~ /^-/) { $rest .= substr($lines[$ln - 1], $off) . "\n"; $cnt--; -- cgit v1.2.3 From 01fa91471e9559d72c0c93ea7cca6f9fe6c2d1c3 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:19 -0700 Subject: checkpatch: fix up comment checks search to scan the entire block We are not counting the lines in the block correctly which causes the comment scan to stop prematurly and thus miss comments which end at the end of the block. Fix this up. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 586f9a4f0ad0..482768cd5790 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1029,9 +1029,14 @@ sub process { # edge is a close comment then we must be in a comment # at context start. my $edge; - for (my $ln = $linenr + 1; $ln < ($linenr + $realcnt); $ln++) { - next if ($line =~ /^-/); - ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@); + my $cnt = $realcnt; + for (my $ln = $linenr + 1; $cnt > 0; $ln++) { + next if (defined $rawlines[$ln - 1] && + $rawlines[$ln - 1] =~ /^-/); + $cnt--; + #print "RAW<$rawlines[$ln - 1]>\n"; + ($edge) = (defined $rawlines[$ln - 1] && + $rawlines[$ln - 1] =~ m@(/\*|\*/)@); last if (defined $edge); } if (defined $edge && $edge eq '*/') { -- cgit v1.2.3 From c1ab33269a84d6056d2ffc728d8bbaa26377d3e3 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:20 -0700 Subject: checkpatch: include/asm checks should be anchored It is possible to have other include/asm paths within the tree which are not subject to the do not edit checks. Ignore those. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 482768cd5790..0e5af8ed107e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1134,7 +1134,7 @@ sub process { $realfile = $1; $realfile =~ s@^[^/]*/@@; - if ($realfile =~ m@include/asm/@) { + if ($realfile =~ m@^include/asm/@) { ERROR("do not modify files in include/asm, change architecture specific files in include/asm-\n" . "$here$rawline\n"); } next; -- cgit v1.2.3 From e09dec4831bbb319987215ea0a280b2a620021b7 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:20 -0700 Subject: checkpatch: reduce warnings for #include of asm/foo.h to check from arch/bar.c It is much more likely that an architecture file will want to directly include asm header files. Reduce this WARNING to a CHECK when the referencing file is in the arch directory. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 0e5af8ed107e..9e7e9d1d5958 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1942,12 +1942,17 @@ sub process { #warn if is #included and is available (uses RAW line) if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\}) { - my $checkfile = "include/linux/$1.h"; - if (-f "$root/$checkfile" && $realfile ne $checkfile && + my $file = "$1.h"; + my $checkfile = "include/linux/$file"; + if (-f "$root/$checkfile" && + $realfile ne $checkfile && $1 ne 'irq') { - WARN("Use #include instead of \n" . - $herecurr); + if ($realfile =~ m{^arch/}) { + CHK("Consider using #include instead of \n" . $herecurr); + } else { + WARN("Use #include instead of \n" . $herecurr); + } } } -- cgit v1.2.3 From 6ecd967444223cea4a02d55fdc0f0510baa69523 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:21 -0700 Subject: checkpatch: report any absolute references to kernel source files Absolute references to kernel source files are generally only useful locally to the originator of the patch. Check for any such references and report them. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 9e7e9d1d5958..cc61cf7187ef 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -958,6 +958,33 @@ sub CHK { } } +sub check_absolute_file { + my ($absolute, $herecurr) = @_; + my $file = $absolute; + + ##print "absolute<$absolute>\n"; + + # See if any suffix of this path is a path within the tree. + while ($file =~ s@^[^/]*/@@) { + if (-f "$root/$file") { + ##print "file<$file>\n"; + last; + } + } + if (! -f _) { + return 0; + } + + # It is, so see if the prefix is acceptable. + my $prefix = $absolute; + substr($prefix, -length($file)) = ''; + + ##print "prefix<$prefix>\n"; + if ($prefix ne ".../") { + WARN("use relative pathname instead of absolute in changelog text\n" . $herecurr); + } +} + sub process { my $filename = shift; @@ -1168,6 +1195,20 @@ sub process { $herecurr) if (!$emitted_corrupt++); } +# Check for absolute kernel paths. + if ($tree) { + while ($line =~ m{(?:^|\s)(/\S*)}g) { + my $file = $1; + + if ($file =~ m{^(.*?)(?::\d+)+:?$} && + check_absolute_file($1, $herecurr)) { + # + } else { + check_absolute_file($file, $herecurr); + } + } + } + # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php if (($realfile =~ /^$/ || $line =~ /^\+/) && $rawline !~ m/^$UTF8*$/) { -- cgit v1.2.3 From 4d001e4d88a57ba8347b43e3a20412cd6b67fbd7 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:21 -0700 Subject: checkpatch: report the real first line of all suspect indents We are currently only reporting syspect indents if the conditional is modified but the indent missmatch could be generated by the body changing, make sure we catch both. Also only report the first line of the body, and more importantly make sure we report the raw copy of the line. Finally report the indent levels to make it easier to understand what is wrong. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 141 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 55 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index cc61cf7187ef..e3ae79ab2cab 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -673,6 +673,22 @@ sub ctx_has_comment { return ($cmt ne ''); } +sub raw_line { + my ($linenr, $cnt) = @_; + + my $offset = $linenr - 1; + $cnt++; + + my $line; + while ($cnt) { + $line = $rawlines[$offset++]; + next if (defined($line) && $line =~ /^-/); + $cnt--; + } + + return $line; +} + sub cat_vet { my ($vet) = @_; my ($res, $coded); @@ -1392,6 +1408,76 @@ sub process { } } +# Check relative indent for conditionals and blocks. + if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { + my ($s, $c) = ($stat, $cond); + + substr($s, 0, length($c), ''); + + # Make sure we remove the line prefixes as we have + # none on the first line, and are going to readd them + # where necessary. + $s =~ s/\n./\n/gs; + + # Find out how long the conditional actually is. + my $cond_lines = 0 + $c =~ /\n/gs; + + # We want to check the first line inside the block + # starting at the end of the conditional, so remove: + # 1) any blank line termination + # 2) any opening brace { on end of the line + # 3) any do (...) { + my $continuation = 0; + my $check = 0; + $s =~ s/^.*\bdo\b//; + $s =~ s/^\s*{//; + if ($s =~ s/^\s*\\//) { + $continuation = 1; + } + if ($s =~ s/^\s*\n//) { + $check = 1; + $cond_lines++; + } + + # Also ignore a loop construct at the end of a + # preprocessor statement. + if (($prevline =~ /^.\s*#\s*define\s/ || + $prevline =~ /\\\s*$/) && $continuation == 0) { + $check = 0; + } + + # Ignore the current line if its is a preprocessor + # line. + if ($s =~ /^\s*#\s*/) { + $check = 0; + } + + # Ignore the current line if it is label. + if ($s =~ /^\s*$Ident\s*:/) { + $check = 0; + } + + my (undef, $sindent) = line_stats("+" . $s); + my $stat_real = raw_line($linenr, $cond_lines); + + # Check if either of these lines are modified, else + # this is not this patch's fault. + if (!defined($stat_real) || + $stat !~ /^\+/ && $stat_real !~ /^\+/) { + $check = 0; + } + if (defined($stat_real) && $cond_lines > 1) { + $stat_real = "[...]\n$stat_real"; + } + + ##print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; + + if ($check && (($sindent % 8) != 0 || + ($sindent <= $indent && $s ne ''))) { + WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); + } + } + # Track the 'values' across context and added lines. my $opline = $line; $opline =~ s/^./ /; my ($curr_values, $curr_vars) = @@ -1869,61 +1955,6 @@ sub process { } } -# Check relative indent for conditionals and blocks. - if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { - my ($s, $c) = ($stat, $cond); - - substr($s, 0, length($c), ''); - - # Make sure we remove the line prefixes as we have - # none on the first line, and are going to readd them - # where necessary. - $s =~ s/\n./\n/gs; - - # We want to check the first line inside the block - # starting at the end of the conditional, so remove: - # 1) any blank line termination - # 2) any opening brace { on end of the line - # 3) any do (...) { - my $continuation = 0; - my $check = 0; - $s =~ s/^.*\bdo\b//; - $s =~ s/^\s*{//; - if ($s =~ s/^\s*\\//) { - $continuation = 1; - } - if ($s =~ s/^\s*\n//) { - $check = 1; - } - - # Also ignore a loop construct at the end of a - # preprocessor statement. - if (($prevline =~ /^.\s*#\s*define\s/ || - $prevline =~ /\\\s*$/) && $continuation == 0) { - $check = 0; - } - - # Ignore the current line if its is a preprocessor - # line. - if ($s =~ /^\s*#\s*/) { - $check = 0; - } - - # Ignore the current line if it is label. - if ($s =~ /^\s*$Ident\s*:/) { - $check = 0; - } - - my (undef, $sindent) = line_stats("+" . $s); - - ##print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s>\n"; - - if ($check && (($sindent % 8) != 0 || - ($sindent <= $indent && $s ne ''))) { - WARN("suspect code indent for conditional statements\n" . $herecurr); - } - } - # Check for bitwise tests written as boolean if ($line =~ / (?: -- cgit v1.2.3 From 9bd49efe4e4bf88d9c1026db50325fd1b2e59519 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:22 -0700 Subject: checkpatch: suspect indent -- skip over preprocessor, label and blank lines We should skip over and check the lines which follow preprocessor statements, labels, and blank lines. These all have legitimate reasons to be indented differently. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e3ae79ab2cab..6ddae89c3cfa 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1434,7 +1434,7 @@ sub process { if ($s =~ s/^\s*\\//) { $continuation = 1; } - if ($s =~ s/^\s*\n//) { + if ($s =~ s/^\s*?\n//) { $check = 1; $cond_lines++; } @@ -1446,15 +1446,20 @@ sub process { $check = 0; } - # Ignore the current line if its is a preprocessor - # line. - if ($s =~ /^\s*#\s*/) { - $check = 0; - } + my $cond_ptr = -1; + while ($cond_ptr != $cond_lines) { + $cond_ptr = $cond_lines; - # Ignore the current line if it is label. - if ($s =~ /^\s*$Ident\s*:/) { - $check = 0; + # Ignore: + # 1) blank lines, they should be at 0, + # 2) preprocessor lines, and + # 3) labels. + if ($s =~ /^\s*?\n/ || + $s =~ /^\s*#\s*?/ || + $s =~ /^\s*$Ident\s*:/) { + $s =~ s/^.*?\n//; + $cond_lines++; + } } my (undef, $sindent) = line_stats("+" . $s); @@ -1470,7 +1475,7 @@ sub process { $stat_real = "[...]\n$stat_real"; } - ##print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; + #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; if ($check && (($sindent % 8) != 0 || ($sindent <= $indent && $s ne ''))) { -- cgit v1.2.3 From 2a1bc5d5c5096f2dfb6f8b18f39ecb718f101535 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:23 -0700 Subject: checkpatch: %Lx tests should hand %% as a literal Ensure that we handle literal %'s correctly when adjacent to a %Lx. %Lx bad %%Lx good %%%Lx bad Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6ddae89c3cfa..c7980ff2975e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2392,6 +2392,7 @@ sub process { my $string; while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { $string = substr($rawline, $-[1], $+[1] - $-[1]); + $string =~ s/%%/__/g; if ($string =~ /(? Date: Wed, 15 Oct 2008 22:02:23 -0700 Subject: checkpatch: report the correct lines for single statement blocks Report the correct lines for single statement blocks. Currently we are reporting the right number of lines, but not skipping the negative lines. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c7980ff2975e..36825c3d7d79 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2214,10 +2214,10 @@ sub process { } if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { my $herectx = $here . "\n";; - my $end = $linenr + statement_rawlines($block) - 1; + my $cnt = statement_rawlines($block); - for (my $ln = $linenr - 1; $ln < $end; $ln++) { - $herectx .= $rawlines[$ln] . "\n";; + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n";; } WARN("braces {} are not necessary for single statement blocks\n" . $herectx); -- cgit v1.2.3 From b9ea10d691ecb616ce9e4d7a51400dfd93f52b2d Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:24 -0700 Subject: checkpatch: perform indent checks on perl So that we eat our own dog food ensure the indent checks apply to perl too. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 36825c3d7d79..ba677c17c334 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1266,8 +1266,8 @@ sub process { WARN("adding a line without newline at end of file\n" . $herecurr); } -# check we are in a valid source file *.[hc] if not then ignore this hunk - next if ($realfile !~ /\.[hc]$/); +# check we are in a valid source file C or perl if not then ignore this hunk + next if ($realfile !~ /\.(h|c|pl)$/); # at the beginning of a line any tabs must come first and anything # more than 8 must use tabs. @@ -1277,6 +1277,9 @@ sub process { ERROR("code indent should use tabs where possible\n" . $herevet); } +# check we are in a valid C source file if not then ignore this hunk + next if ($realfile !~ /\.(h|c)$/); + # check for RCS/CVS revision markers if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr); -- cgit v1.2.3 From dea79cd3dfb4a50e4c3d0dcb7294f6d633b455d1 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:24 -0700 Subject: checkpatch: version: 0.22 Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index ba677c17c334..66bcedc0c8b3 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -9,7 +9,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.21'; +my $V = '0.22'; use Getopt::Long qw(:config no_auto_abbrev); -- cgit v1.2.3 From a1080bf80862c571b5f0a20cb601e24dd90e2026 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:25 -0700 Subject: checkpatch: case/default checks should only check changed lines We should only be checking changes lines for the trailing statement check on case/default statements. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 66bcedc0c8b3..457f87460d6e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1363,14 +1363,6 @@ sub process { ERROR("switch and case should be at the same indent\n$hereline$err"); } } - if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && - $line !~ /\G(?: - (?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| - \s*return\s+ - )/xg) - { - ERROR("trailing statements should be on next line\n" . $herecurr); - } # if/while/etc brace do not go on next line, unless defining a do while loop, # or if that brace on the next line is for something else @@ -1986,6 +1978,15 @@ sub process { ERROR("trailing statements should be on next line\n" . $herecurr); } } +# case and default should not have general statements after them + if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && + $line !~ /\G(?: + (?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| + \s*return\s+ + )/xg) + { + ERROR("trailing statements should be on next line\n" . $herecurr); + } # Check for }else {, these must be at the same # indent level to be relevant to each other. -- cgit v1.2.3 From dea33496ddc2bf1a50e9def87b4ef14709d8cb6d Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:25 -0700 Subject: checkpatch: suppress errors triggered by short patch When the last hunk of a patch is short it will trigger errors from checkpatch: Use of uninitialized value in pattern match (m//) at /usr/local/bin/checkpatch.pl line 394. Use of uninitialized value in concatenation (.) or string at /usr/local/bin/checkpatch.pl line 397. Use of uninitialized value in pattern match (m//) Avoid touching beyond the last line. Reported by Julien Brunel. Signed-off-by: Andy Whitcroft Cc: Julien Brunel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 457f87460d6e..5382f7287397 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -408,6 +408,7 @@ sub ctx_statement_block { # context. if ($off >= $len) { for (; $remain > 0; $line++) { + last if (!defined $lines[$line]); next if ($lines[$line] =~ /^-/); $remain--; $loff = $len; -- cgit v1.2.3 From 81bc0e020232a1e1e7010376382bb59ca82927ac Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:26 -0700 Subject: checkpatch: handle comment/quote nesting correctly Ensure that a close comment cannot incorrectly trigger in the middle of a string. Reported by Jaswinder Singh. Signed-off-by: Andy Whitcroft Cc: Jaswinder Singh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 5382f7287397..18646f076a84 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -335,7 +335,7 @@ sub sanitise_line { $off++; next; } - if (substr($line, $off, 2) eq '*/') { + if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { $sanitise_quote = ''; substr($res, $off, 2, "$;$;"); $off++; -- cgit v1.2.3 From 5368df20fb364e394da3ab88d3d60ee3c0a9e5ba Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:27 -0700 Subject: checkpatch: check line endings in text format files Firmware may be included in the kernel as .ihex files. These are inherantly text, but not source. The line ending checks are applicable to these kinds of file, allow just these checks to apply to all files. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 18646f076a84..a2e4a3d9c6d7 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1241,9 +1241,6 @@ sub process { #ignore lines being removed if ($line=~/^-/) {next;} -# check we are in a valid source file if not then ignore this hunk - next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); - #trailing whitespace if ($line =~ /^\+.*\015/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; @@ -1253,6 +1250,10 @@ sub process { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; ERROR("trailing whitespace\n" . $herevet); } + +# check we are in a valid source file if not then ignore this hunk + next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); + #80 column limit if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && $rawline !~ /^.\s*\*\s*\@$Ident\s/ && -- cgit v1.2.3 From 6f779c18ca74358b6ac8eb8f5d502843fa92be4e Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:27 -0700 Subject: checkpatch: suspect indent count condition lines correctly Correct calculation of the number of lines of condition where we have suspect indent. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index a2e4a3d9c6d7..2e513fdf3043 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1417,7 +1417,8 @@ sub process { $s =~ s/\n./\n/gs; # Find out how long the conditional actually is. - my $cond_lines = 0 + $c =~ /\n/gs; + my @newlines = ($c =~ /\n/gs); + my $cond_lines = 1 + $#newlines; # We want to check the first line inside the block # starting at the end of the conditional, so remove: -- cgit v1.2.3 From 306708547b566ef6a0ccd470c84568807571885c Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:28 -0700 Subject: checkpatch: ensure we only apply checks to the lines within hunks We should only apply source checks to lines within hunks. Checks which are anchored in the context may falsly trigger in the commentory. Ensure they only match within valid hunk lines. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2e513fdf3043..fe4553c070b1 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1128,6 +1128,7 @@ sub process { $linenr++; my $rawline = $rawlines[$linenr - 1]; + my $hunk_line = ($realcnt != 0); #extract the line range in the file after the patch is applied if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { @@ -1238,8 +1239,8 @@ sub process { ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); } -#ignore lines being removed - if ($line=~/^-/) {next;} +# ignore non-hunk lines and lines being removed + next if (!$hunk_line || $line =~ /^-/); #trailing whitespace if ($line =~ /^\+.*\015/) { -- cgit v1.2.3 From 5fdd23acf9cd7f658746b119436ed1d787326c46 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:28 -0700 Subject: checkpatch: version: 0.23 Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index fe4553c070b1..118fe1f30e76 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -9,7 +9,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.22'; +my $V = '0.23'; use Getopt::Long qw(:config no_auto_abbrev); -- cgit v1.2.3 From 0776e594606e32a045e0a99bb919b2280b945495 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:29 -0700 Subject: checkpatch: do is not a possible type A do without braces '{' may trigger a false possible type 'do' and then this may be interpreted as an external definition of foo(): do foo(); while (bar); Add do to the type exclusions. Fix up tests so we can check for them. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 118fe1f30e76..6b21188d2cf7 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -913,12 +913,22 @@ sub annotate_values { sub possible { my ($possible, $line) = @_; - print "CHECK<$possible> ($line)\n" if ($dbg_possible > 1); - if ($possible !~ /^(?:$Modifier|$Storage|$Type|DEFINE_\S+)$/ && - $possible ne 'goto' && $possible ne 'return' && - $possible ne 'case' && $possible ne 'else' && - $possible ne 'asm' && $possible ne '__asm__' && - $possible !~ /^(typedef|struct|enum)\b/) { + print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); + if ($possible !~ /(?: + ^(?: + $Modifier| + $Storage| + $Type| + DEFINE_\S+| + goto| + return| + case| + else| + asm|__asm__| + do + )$| + ^(?:typedef|struct|enum)\b + )/x) { # Check for modifiers. $possible =~ s/\s*$Storage\s*//g; $possible =~ s/\s*$Sparse\s*//g; @@ -936,6 +946,8 @@ sub possible { push(@typeList, $possible); } build_types(); + } else { + warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); } } -- cgit v1.2.3 From a6a84062821738426ed4f58f4d584ecb7feb3dee Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:30 -0700 Subject: checkpatch: labels are not possible types A label is not a candidate for a possible type. Exclude them. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6b21188d2cf7..17e1d94fa1fa 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1324,7 +1324,7 @@ sub process { possible($type, "A:" . $s); # definitions in global scope can only start with types - } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/s) { + } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { possible($1, "B:" . $s); } -- cgit v1.2.3 From 170d3a22688f06fda42e353bbccd0f3df89f3d94 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:30 -0700 Subject: checkpatch: handle do without braces if we have enough context If we have sufficient context detect and handle do without braces ({). Else these incorrectly trigger a trailing statements error for the associated while. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 17e1d94fa1fa..19690a2ddb74 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1051,6 +1051,7 @@ sub process { # suppression flags my %suppress_ifbraces; + my %suppress_whiletrailers; # Pre-scan the patch sanitizing the lines. # Pre-scan the patch looking for any __setup documentation. @@ -1156,6 +1157,7 @@ sub process { $prev_values = 'E'; %suppress_ifbraces = (); + %suppress_whiletrailers = (); next; # track the line number as we move through the hunk, note that @@ -1301,9 +1303,9 @@ sub process { } # Check for potential 'bare' types - my ($stat, $cond, $line_nr_next, $remain_next); + my ($stat, $cond, $line_nr_next, $remain_next, $off_next); if ($realcnt && $line =~ /.\s*\S/) { - ($stat, $cond, $line_nr_next, $remain_next) = + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = ctx_statement_block($linenr, $realcnt, 0); $stat =~ s/\n./\n /g; $cond =~ s/\n./\n /g; @@ -1952,7 +1954,26 @@ sub process { # Check for illegal assignment in if conditional -- and check for trailing # statements after the conditional. - if ($line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { + if ($line =~ /do\s*(?!{)/) { + my ($stat_next) = ctx_statement_block($line_nr_next, + $remain_next, $off_next); + $stat_next =~ s/\n./\n /g; + ##print "stat<$stat> stat_next<$stat_next>\n"; + + if ($stat_next =~ /^\s*while\b/) { + # If the statement carries leading newlines, + # then count those as offsets. + my ($whitespace) = + ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); + my $offset = + statement_rawlines($whitespace) - 1; + + $suppress_whiletrailers{$line_nr_next + + $offset} = 1; + } + } + if (!defined $suppress_whiletrailers{$linenr} && + $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { my ($s, $c) = ($stat, $cond); if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) { -- cgit v1.2.3 From b132e5d5865325a9aa42b122c4c466903bf48348 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:31 -0700 Subject: checkpatch: macros which define structure members are not complex We often see macros which define structure members, these are not complex and necessarily do not have braces or brackets. For example: #define _PLIST_HEAD_INIT(head) \ .prio_list = LIST_HEAD_INIT((head).prio_list), \ .node_list = LIST_HEAD_INIT((head).node_list) Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 19690a2ddb74..6eceda7a4bd9 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2155,6 +2155,7 @@ sub process { if ($dstat ne '' && $dstat !~ /^(?:$Ident|-?$Constant)$/ && $dstat !~ /$exceptions/ && + $dstat !~ /^\.$Ident\s*=/ && $dstat =~ /$Operators/) { ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); -- cgit v1.2.3 From afbe8d283b97b2317dab900fb11d2a8878ee3c23 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:31 -0700 Subject: checkpatch: accept any sized le/be type We are likely going to have 24 bit types. Expand the type matcher to match any size. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6eceda7a4bd9..bb88df2d001b 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -159,7 +159,7 @@ our @typeList = ( qr{float}, qr{double}, qr{bool}, - qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)}, + qr{(?:__)?(?:u|s|be|le)(?:\d|\d\d)}, qr{struct\s+$Ident}, qr{union\s+$Ident}, qr{enum\s+$Ident}, -- cgit v1.2.3 From 8ed22cad9ce16e3d8915ae75544a133c3050d96f Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:32 -0700 Subject: checkpatch: pull out known acceptable typedefs Within the type checker we have a number of common kernel types which must be implemented as typedefs. Pull those out so that we can use the same expressions to trigger exclusions. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index bb88df2d001b..4680ccf7760c 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -146,6 +146,11 @@ our $UTF8 = qr { | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 }x; +our $typeTypedefs = qr{(?x: + (?:__)?(?:u|s|be|le)(?:\d|\d\d)| + atomic_t +)}; + our @typeList = ( qr{void}, qr{(?:unsigned\s+)?char}, @@ -159,7 +164,6 @@ our @typeList = ( qr{float}, qr{double}, qr{bool}, - qr{(?:__)?(?:u|s|be|le)(?:\d|\d\d)}, qr{struct\s+$Ident}, qr{union\s+$Ident}, qr{enum\s+$Ident}, @@ -179,6 +183,7 @@ sub build_types { (?:$Modifier\s+|const\s+)* (?: (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)| + (?:$typeTypedefs\b)| (?:${all}\b) ) (?:\s+$Modifier|\s+const)* @@ -1589,6 +1594,7 @@ sub process { if ($line =~ /\btypedef\s/ && $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ && $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && + $line !~ /\b$typeTypedefs\b/ && $line !~ /\b__bitwise(?:__|)\b/) { WARN("do not add new typedefs\n" . $herecurr); } -- cgit v1.2.3 From f16fa28f7b3d95e989fc64c8480e44c1bcf4bac3 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:32 -0700 Subject: checkpatch: suspect code indent must stop at #else/#elif When we hit and #else or #elif we know we are meeting an alternative piece of code. All bets are off on indent if we did not see the open of the control so stop checking. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4680ccf7760c..c479bdefc779 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1468,6 +1468,12 @@ sub process { while ($cond_ptr != $cond_lines) { $cond_ptr = $cond_lines; + # If we see an #else/#elif then the code + # is not linear. + if ($s =~ /^\s*\#\s*(?:else|elif)/) { + $check = 0; + } + # Ignore: # 1) blank lines, they should be at 0, # 2) preprocessor lines, and -- cgit v1.2.3 From bf30d6ede099c2a31b13bbd05b1022dc0da684d5 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:33 -0700 Subject: checkpatch: complex macros checks miss square brackets We are missing 'simple' values which include square brackets. Refactor to ensure we handle nesting correctly and detect these simple forms. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c479bdefc779..54dfa2b543dd 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2142,9 +2142,10 @@ sub process { $dstat =~ s/\s*$//s; # Flatten any parentheses and braces - while ($dstat =~ s/\([^\(\)]*\)/1/) { - } - while ($dstat =~ s/\{[^\{\}]*\}/1/) { + while ($dstat =~ s/\([^\(\)]*\)/1/ || + $dstat =~ s/\{[^\{\}]*\}/1/ || + $dstat =~ s/\[[^\{\}]*\]/1/) + { } my $exceptions = qr{ -- cgit v1.2.3 From 480120586464e5a8cd2289a90ffbb5c042e66ba0 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:34 -0700 Subject: checkpatch: DEFINE_ macros are real definitions for exports When we want to confirm an export is directly after its definition we need to allow for DEFINE_ style macros. Add these to the execeptions. Refactor the exceptions. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 54dfa2b543dd..a675f067b572 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1573,13 +1573,14 @@ sub process { if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { my $name = $1; - if (($prevline !~ /^}/) && - ($prevline !~ /^\+}/) && - ($prevline !~ /^ }/) && - ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) && - ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) && - ($prevline !~ /^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(/) && - ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) { + if ($prevline !~ /(?: + ^.}| + ^.DEFINE_$Ident\(\Q$name\E\)| + ^.DECLARE_$Ident\(\Q$name\E\)| + ^.LIST_HEAD\(\Q$name\E\)| + ^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| + \b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[) + )/x) { WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); } } -- cgit v1.2.3 From bb44ad39c886401e1ffe0876565f8b3fcea64e9d Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:34 -0700 Subject: checkpatch: trailing statements ensure we report the end of the line When reporting some complex trailing statements we report only the starting line of the error, that tends to imply the shown line is in error and confuse the reader. As we do know where the actual error is report that line too with an appropriate gap marker where applicable. #ERROR: trailing statements should be on next line #1: FILE: Z202.c:1: + for (pbh = page_buffers(bh->b_page); pbh != bh; + pbh = pbh->b_this_page, key++); #ERROR: trailing statements should be on next line #4: FILE: Z202.c:4: + for (pbh = page_buffers(bh->b_page); [...] + pbh = pbh->b_this_page, key++); Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index a675f067b572..2c1afba57580 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2001,7 +2001,16 @@ sub process { if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && $c !~ /}\s*while\s*/) { - ERROR("trailing statements should be on next line\n" . $herecurr); + # Find out how long the conditional actually is. + my @newlines = ($c =~ /\n/gs); + my $cond_lines = 1 + $#newlines; + + my $stat_real = raw_line($linenr, $cond_lines); + if (defined($stat_real) && $cond_lines > 1) { + $stat_real = "[...]\n$stat_real"; + } + + ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real); } } -- cgit v1.2.3 From 740504c61f79a932564fb7117d79ad53d950b201 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:35 -0700 Subject: checkpatch: suspect indent handle macro continuation When ignoring a macro in the middle of a conditional, we need to ignore the macro start and any continuation lines. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2c1afba57580..862e8e0e86ae 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1465,6 +1465,7 @@ sub process { } my $cond_ptr = -1; + $continuation = 0; while ($cond_ptr != $cond_lines) { $cond_ptr = $cond_lines; @@ -1478,9 +1479,11 @@ sub process { # 1) blank lines, they should be at 0, # 2) preprocessor lines, and # 3) labels. - if ($s =~ /^\s*?\n/ || + if ($continuation || + $s =~ /^\s*?\n/ || $s =~ /^\s*#\s*?/ || $s =~ /^\s*$Ident\s*:/) { + $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; $s =~ s/^.*?\n//; $cond_lines++; } -- cgit v1.2.3 From 3fef12d6cb832327a981b03326f8f07abebb51b7 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:36 -0700 Subject: checkpatch: allow for comments either side of a brace on case When specifying case we may have comments and/or braces at the end without actually having a 'statement'. Allow for these to occur in any order. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 862e8e0e86ae..ada27c44da02 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2043,7 +2043,7 @@ sub process { # case and default should not have general statements after them if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && $line !~ /\G(?: - (?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| + (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| \s*return\s+ )/xg) { -- cgit v1.2.3 From 6e144ee546b4bb4902524e639dc9c2cd4f7f97a4 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Oct 2008 22:02:36 -0700 Subject: checkpatch: version: 0.24 Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index ada27c44da02..e30bac141b21 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -9,7 +9,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.23'; +my $V = '0.24'; use Getopt::Long qw(:config no_auto_abbrev); -- cgit v1.2.3 From db7a6d8d01b21829d28638258cbbc9553210bac1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 20 Oct 2008 11:24:31 -0700 Subject: Update .gitignore files for generated targets The generated 'capflags.c' file wasn't properly ignored, and the list of files in scripts/basic/ wasn't up-to-date. Signed-off-by: Linus Torvalds --- scripts/basic/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore index 7304e19782c7..bf8b199ec598 100644 --- a/scripts/basic/.gitignore +++ b/scripts/basic/.gitignore @@ -1,3 +1,3 @@ +hash fixdep -split-include docproc -- cgit v1.2.3 From f4432c5caec5fa95ea7eefd00f8e6cee17e2e023 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 20 Oct 2008 13:31:45 -0400 Subject: Update email addresses. Update assorted email addresses and related info to point to a single current, valid address. additionally - trivial CREDITS entry updates. (Not that this file means much any more) - remove arjans dead redhat.com address from powernow driver Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e30bac141b21..f88bb3e21cda 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# (c) 2001, Dave Jones. (the file handling bit) +# (c) 2001, Dave Jones. (the file handling bit) # (c) 2005, Joel Schopp (the ugly bit) # (c) 2007, Andy Whitcroft (new conditions, test suite, etc) # Licensed under the terms of the GNU GPL License version 2 -- cgit v1.2.3 From 2a813f8cd8ce91d588a595c5709502dece3af289 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Tue, 14 Oct 2008 14:18:07 +0100 Subject: tracing/fastboot: fix bootgraph.pl to run with "use strict" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As a perl novice, I would prefer to have the benefit of the interpreters' wisdom. It turns out there were already some warnings, so let's fix them. Signed-off-by: Alan Jenkins Acked-by: Frédéric Weisbecker Signed-off-by: Ingo Molnar --- scripts/bootgraph.pl | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index 5e7316e5aa39..ea2b079af9fd 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -37,7 +37,10 @@ # dmesg | perl scripts/bootgraph.pl > output.svg # -my %start, %end; +use strict; + +my %start; +my %end; my $done = 0; my $maxtime = 0; my $firsttime = 100; @@ -105,12 +108,14 @@ my $threshold = ($maxtime - $firsttime) / 60.0; my $stylecounter = 0; my %rows; my $rowscount = 1; +my $key; +my $value; while (($key,$value) = each %start) { my $duration = $end{$key} - $start{$key}; if ($duration >= $threshold) { - my $s, $s2, $e, $y; - $pid = $pids{$key}; + my ($s, $s2, $e, $w, $y, $y2, $style); + my $pid = $pids{$key}; if (!defined($rows{$pid})) { $rows{$pid} = $rowscount; @@ -140,9 +145,9 @@ while (($key,$value) = each %start) { my $time = $firsttime; my $step = ($maxtime - $firsttime) / 15; while ($time < $maxtime) { - my $s2 = ($time - $firsttime) * $mult; + my $s3 = ($time - $firsttime) * $mult; my $tm = int($time * 100) / 100.0; - print "$tm\n"; + print "$tm\n"; $time = $time + $step; } -- cgit v1.2.3 From 06d1cd267ca0a2a76beb9a762465572dd3d0cce6 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Tue, 14 Oct 2008 14:19:15 +0100 Subject: tracing/fastboot: fix row order in bootgraph.pl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When bootgraph.pl parses a file, it gives one row for each initcall's pid. But they are displayed in random (perl hash) order. Let's sort the pids by the start time of their first initcall instead. This helps trace module initcalls, where each has a separate pid. bootgraph.pl will show module initcalls during the initramfs; it may also be adapted to show subsequent module initcalls. Signed-off-by: Alan Jenkins Acked-by: Frédéric Weisbecker Signed-off-by: Ingo Molnar --- scripts/bootgraph.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index ea2b079af9fd..d2c61efc216f 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -108,9 +108,9 @@ my $threshold = ($maxtime - $firsttime) / 60.0; my $stylecounter = 0; my %rows; my $rowscount = 1; +my @initcalls = sort { $start{$a} <=> $start{$b} } keys(%start); my $key; -my $value; -while (($key,$value) = each %start) { +foreach $key (@initcalls) { my $duration = $end{$key} - $start{$key}; if ($duration >= $threshold) { @@ -121,7 +121,7 @@ while (($key,$value) = each %start) { $rows{$pid} = $rowscount; $rowscount = $rowscount + 1; } - $s = ($value - $firsttime) * $mult; + $s = ($start{$key} - $firsttime) * $mult; $s2 = $s + 6; $e = ($end{$key} - $firsttime) * $mult; $w = $e - $s; -- cgit v1.2.3 From d41e2d7317cd55cc5135356a05c289537b0f6d70 Mon Sep 17 00:00:00 2001 From: Martin Habets Date: Tue, 21 Oct 2008 21:58:29 -0700 Subject: sparc: Add checkstack support Add sparc support to checkstack. Signed-off-by: Martin Habets Signed-off-by: David S. Miller --- scripts/checkstack.pl | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index f7e8e93ff30d..14ee68e991dd 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -14,6 +14,7 @@ # M68k port by Geert Uytterhoeven and Andreas Schwab # AVR32 port by Haavard Skinnemoen # PARISC port by Kyle McMartin +# sparc port by Martin Habets # # Usage: # objdump -d vmlinux | scripts/checkstack.pl [arch] @@ -94,6 +95,9 @@ my (@stack, $re, $dre, $x, $xs); } elsif ($arch =~ /^blackfin$/) { # 0: 00 e8 38 01 LINK 0x4e0; $re = qr/.*[[:space:]]LINK[[:space:]]*(0x$x{1,8})/o; + } elsif ($arch eq 'sparc' || $arch eq 'sparc64') { + # f0019d10: 9d e3 bf 90 save %sp, -112, %sp + $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o; } else { print("wrong or unknown architecture \"$arch\"\n"); exit -- cgit v1.2.3 From bb8985586b7a906e116db835c64773b7a7d51663 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 17 Aug 2008 21:05:42 -0400 Subject: x86, um: ... and asm-x86 move Signed-off-by: Al Viro Signed-off-by: H. Peter Anvin --- scripts/checksyscalls.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 366f8c7f62bf..41564b142c04 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -119,5 +119,5 @@ sed -n -e '/^\#define/ { s/[^_]*__NR_\([^[:space:]]*\).*/\ \#endif/p }' $1 } -(ignore_list && syscall_list ${srctree}/include/asm-x86/unistd_32.h) | \ +(ignore_list && syscall_list ${srctree}/arch/x86/include/asm/unistd_32.h) | \ $* -E -x c - > /dev/null -- cgit v1.2.3 From 61bee20445935ee9802d25c261849440497497d3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 25 Aug 2008 04:51:27 -0400 Subject: x86, um: get rid of arch/um/Kconfig.arch Teach scripts/kconfig/Makefile and top-level Makefile that arch/*/Makefile is allowed to say Kconfig := . Rewrite arch/um/Kconfig and arch/um/Kconfig. so that the latter would be top-level one (and include the pieces of the former). Signed-off-by: Al Viro Signed-off-by: H. Peter Anvin --- scripts/kconfig/Makefile | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index fa1a7d565903..fa8c2dd9c983 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -4,7 +4,11 @@ PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config +ifdef KBUILD_KCONFIG +Kconfig := $(KBUILD_KCONFIG) +else Kconfig := arch/$(SRCARCH)/Kconfig +endif xconfig: $(obj)/qconf $< $(Kconfig) -- cgit v1.2.3 From dce9d18adde74b8e36b9e4a8a49ddf066bad0b3b Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 23 Oct 2008 09:32:57 -0400 Subject: ftrace: handle generic arch calls The recordmcount script requires that the actual arch is passed in. This works well when ARCH=i386 or ARCH=x86_64 but does not handle the case of ARCH=x86. This patch adds a parameter to the function to pass in the number of bits of the architecture. So that it can determine if x86 should be run for x86_64 or i386 archs. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- scripts/Makefile.build | 10 ++++++++-- scripts/recordmcount.pl | 11 ++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 5ed4cbf1e0e1..468fbc9016c7 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -198,10 +198,16 @@ cmd_modversions = \ fi; endif +ifdef CONFIG_64BIT +arch_bits = 64 +else +arch_bits = 32 +endif + ifdef CONFIG_FTRACE_MCOUNT_RECORD cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl \ - "$(ARCH)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" \ - "$(MV)" "$(@)"; + "$(ARCH)" "$(arch_bits)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" \ + "$(NM)" "$(RM)" "$(MV)" "$(@)"; endif define rule_cc_o_c diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index f56d760bd589..c1c618cd96f6 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -106,7 +106,8 @@ if ($#ARGV < 6) { exit(1); } -my ($arch, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV; +my ($arch, $bits, $objdump, $objcopy, $cc, + $ld, $nm, $rm, $mv, $inputfile) = @ARGV; $objdump = "objdump" if ((length $objdump) == 0); $objcopy = "objcopy" if ((length $objcopy) == 0); @@ -129,6 +130,14 @@ my $function_regex; # Find the name of a function # (return offset and func name) my $mcount_regex; # Find the call site to mcount (return offset) +if ($arch eq "x86") { + if ($bits == 64) { + $arch = "x86_64"; + } else { + $arch = "i386"; + } +} + if ($arch eq "x86_64") { $section_regex = "Disassembly of section"; $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; -- cgit v1.2.3 From 34698bcbdf7b0629d6c873b5da7c63073fb45361 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 23 Oct 2008 09:32:58 -0400 Subject: ftrace: dynamic ftrace process only text section The text section stays in memory without ever leaving. With the exception of modules, but modules know how to handle that case. With the dynamic ftrace tracer, we need to make sure that it does not try to modify code that no longer exists. The only safe section is .text. This patch changes the recordmcount script to only record the mcount calls in the .text sections. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- scripts/recordmcount.pl | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index c1c618cd96f6..6b9fe3eb8360 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -109,6 +109,11 @@ if ($#ARGV < 6) { my ($arch, $bits, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV; +# Acceptable sections to record. +my %text_sections = ( + ".text" => 1, +); + $objdump = "objdump" if ((length $objdump) == 0); $objcopy = "objcopy" if ((length $objcopy) == 0); $cc = "gcc" if ((length $cc) == 0); @@ -139,7 +144,7 @@ if ($arch eq "x86") { } if ($arch eq "x86_64") { - $section_regex = "Disassembly of section"; + $section_regex = "Disassembly of section\\s+(\\S+):"; $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$"; $type = ".quad"; @@ -151,7 +156,7 @@ if ($arch eq "x86_64") { $cc .= " -m64"; } elsif ($arch eq "i386") { - $section_regex = "Disassembly of section"; + $section_regex = "Disassembly of section\\s+(\\S+):"; $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; $type = ".long"; @@ -298,7 +303,13 @@ my $text; while () { # is it a section? if (/$section_regex/) { - $read_function = 1; + + # Only record text sections that we know are safe + if (defined($text_sections{$1})) { + $read_function = 1; + } else { + $read_function = 0; + } # print out any recorded offsets update_funcs() if ($text_found); -- cgit v1.2.3 From ce97e13e52848c6388598696b7d44748598db759 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 26 Oct 2008 05:12:34 +0000 Subject: fix allmodconfig breakage If you use KCONFIG_ALLCONFIG (even with empty file) you get broken allmodconfig/allyesconfig; CONFIG_MODULES gets turned off, with obvious massive fallout. Breakage had been introduced when conf_set_all_new_symbols() got used for allmodconfig et.al. What happens is that sym_calc_value(modules_sym) done in conf_read_simple() sets SYMBOL_VALID on both modules_sym and MODULES. When we get to conf_set_all_new_symbols(), we set sym->def[S_DEF_USER] on everything, but it has no effect on sym->curr for the symbols that already have SYMBOL_VALID - these are stuck. Solution: use sym_clear_all_valid() in there. Note that it makes reevaluation of modules_sym redundant - sym_clear_all_valid() will do that itself. [ Fixes http://bugzilla.kernel.org/show_bug.cgi?id=11512, says Alexey ] Signed-off-by: Al Viro Cc: Sam Ravnborg Cc: Roman Zippel Cc: Alexey Dobriyan Signed-off-by: Linus Torvalds --- scripts/kconfig/confdata.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index b91cf241a539..830d9eae11f9 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -852,8 +852,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) } - if (modules_sym) - sym_calc_value(modules_sym); + sym_clear_all_valid(); if (mode != def_random) return; -- cgit v1.2.3 From 890c78c2d681a8dc89c78eb9177990cad3a77dc3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 25 Oct 2008 17:06:43 -0700 Subject: kernel-doc: allow more whitespace in macros Allow macros that are annotated with kernel-doc to contain whitespace between the '#' and "define". It's valid and being used, so allow it. Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 44ee94d2ab76..a53e2fc8dfb5 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1648,7 +1648,7 @@ sub dump_function($$) { $prototype =~ s/^noinline +//; $prototype =~ s/__devinit +//; $prototype =~ s/__init +//; - $prototype =~ s/^#define\s+//; #ak added + $prototype =~ s/^#\s*define\s+//; #ak added $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; # Yes, this truly is vile. We are looking for: @@ -1764,13 +1764,13 @@ sub process_state3_function($$) { $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line - if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#define/)) { + if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) { # do nothing } elsif ($x =~ /([^\{]*)/) { $prototype .= $1; } - if (($x =~ /\{/) || ($x =~ /\#define/) || ($x =~ /;/)) { + if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) { $prototype =~ s@/\*.*?\*/@@gos; # strip comments. $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. $prototype =~ s@^\s+@@gos; # strip leading spaces -- cgit v1.2.3 From 46dca86cb93db80992a45e4b55737ff2b2f61cd0 Mon Sep 17 00:00:00 2001 From: Evgeniy Manachkin Date: Wed, 15 Oct 2008 23:37:26 +0600 Subject: kbuild: mkspec - fix build rpm This is patch to fix incorrect mkspec script to make rpm correctly at 2.6.27 vanilla kernel. This is regression in 2.6.27. 2.6.26 make rpm work good. In 2.6.27 'make rpm' say error from rpmbuild "Many unpacked files (*.fw)." Signed-off-by: Evgeniy Manachkin Acked-by: Alan Cox Signed-off-by: Sam Ravnborg Cc: Stable --- scripts/package/mkspec | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/package/mkspec b/scripts/package/mkspec index ffd61fe0c1ad..62c5ffdf2fdf 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -64,8 +64,10 @@ fi echo "%install" echo "%ifarch ia64" echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib/modules' +echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware' echo "%else" echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules' +echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware' echo "%endif" echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install' @@ -92,5 +94,6 @@ echo "%files" echo '%defattr (-, root, root)' echo "%dir /lib/modules" echo "/lib/modules/$KERNELRELEASE" +echo "/lib/firmware" echo "/boot/*" echo "" -- cgit v1.2.3 From e3da2fb712bb75b6035ba0743f3256df1de30bce Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 25 Oct 2008 17:43:50 -0400 Subject: kbuild: setlocalversion: dont include svn change count The number of pending changes is pretty useless, so encoding it into the version is just annoying by the constant shuffle in corresponding modules. Signed-off-by: Mike Frysinger Signed-off-by: Sam Ravnborg --- scripts/setlocalversion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 83b75126c9f7..453faffe18a7 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -55,7 +55,7 @@ if rev=`svn info 2>/dev/null | grep '^Revision'`; then # Are there uncommitted changes? if [ $changes != 0 ]; then - printf -- '-svn%s%s%s' "$rev" -dirty "$changes" + printf -- '-svn%s%s' "$rev" -dirty else printf -- '-svn%s' "$rev" fi -- cgit v1.2.3 From 13797b77d419fc1b16eebf2993bf7b5cea65f0bf Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Sat, 25 Oct 2008 15:02:47 -0700 Subject: scripts/package: don't break if %{_smp_mflags} isn't set Currently, if we do a 'make rpm-pkg' without the _smp_mflags rpm macro defined, the build fails with: [snip] Executing(%build): /bin/bash -e /var/tmp/rpm-tmp.67959 + umask 022 + cd /home/jk/devel/kernel-snapshot/rpm/BUILD + cd kernel-2.6.26 + make clean + make '%{_smp_mflags}' make[3]: *** No rule to make target `%{_smp_mflags}'. Stop. error: Bad exit status from /var/tmp/rpm-tmp.67959 (%build) This change uses the 'null if not set' reference to the _smp_mflags macro instead. Signed-off-by: Jeremy Kerr Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/package/mkspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 62c5ffdf2fdf..2500886fb90a 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -57,7 +57,7 @@ fi echo "%build" if ! $PREBUILT; then -echo "make clean && make %{_smp_mflags}" +echo "make clean && make %{?_smp_mflags}" echo "" fi -- cgit v1.2.3 From bd8f89ff47f11941a109220dbd51d81fd7ed2058 Mon Sep 17 00:00:00 2001 From: Thomas Volpini Date: Sat, 25 Oct 2008 15:02:50 -0700 Subject: scripts/checksyscalls.sh: fix for non-gnu sed Make the checksyscalls script work even on systems where sed is non-gnu. Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/checksyscalls.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 41564b142c04..60d00d1c4eee 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -113,10 +113,10 @@ EOF } syscall_list() { -sed -n -e '/^\#define/ { s/[^_]*__NR_\([^[:space:]]*\).*/\ +sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\ \#if !defined \(__NR_\1\) \&\& !defined \(__IGNORE_\1\)\ \#warning syscall \1 not implemented\ -\#endif/p }' $1 +\#endif/p' $1 } (ignore_list && syscall_list ${srctree}/arch/x86/include/asm/unistd_32.h) | \ -- cgit v1.2.3 From 92f83cc56eeafdb8fcf07ceb89fd9a0212bd498c Mon Sep 17 00:00:00 2001 From: Peter Volkov Date: Sat, 25 Oct 2008 15:02:52 -0700 Subject: kbuild: fix KBUILD_EXTRA_SYMBOLS Taken from http://bugzilla.kernel.org/show_bug.cgi?id=11567 If you even define KBUILD_EXTRA_SYMBOLS in Makefile it will not be expanded into command line argument for modpost. Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/Makefile.modpost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 9ee9783aea57..f4053dc7b5d6 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -82,7 +82,7 @@ modpost = scripts/mod/modpost \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \ $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ - $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(EXTRA_SYMBOLS))) \ + $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ $(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \ -- cgit v1.2.3 From e6e6733ed9451827165d853f25bf99ba55e12feb Mon Sep 17 00:00:00 2001 From: Ashutosh Naik Date: Sat, 25 Oct 2008 15:02:53 -0700 Subject: kbuild: prevent modpost from looking for a .cmd file for a static library linked into a module This fixes a compile time warning which occurs whenever a static library is linked into a kernel module. MODPOST tries to look for a "..cmd" file to look for its dependencies, but that file doesn't exist or get generated for static libraries. This patch prevents modpost from looking for a .cmd file when a module is linked with a static library [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Ashutosh Naik Cc: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/mod/sumversion.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index d9cc6901d680..aadc5223dcdb 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -290,6 +290,15 @@ static int parse_file(const char *fname, struct md4_ctx *md) release_file(file, len); return 1; } +/* Check whether the file is a static library or not */ +static int is_static_library(const char *objfile) +{ + int len = strlen(objfile); + if (objfile[len - 2] == '.' && objfile[len - 1] == 'a') + return 1; + else + return 0; +} /* We have dir/file.o. Open dir/.file.o.cmd, look for deps_ line to * figure out source file. */ @@ -420,7 +429,8 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) while ((fname = strsep(&sources, " ")) != NULL) { if (!*fname) continue; - if (!parse_source_files(fname, &md)) + if (!(is_static_library(fname)) && + !parse_source_files(fname, &md)) goto release; } -- cgit v1.2.3 From f03b283f081f538ec71b9e87cb8411bb62e2abc9 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Fri, 12 Sep 2008 12:26:24 -0700 Subject: kbuild: tag with git revision when git describe is missing setlocalversion used to use an abbreviated git commit sha1 to generate the tag. This was changed in commit d882421f4e08ddf0a94245cdbe516db260aa6f41 "kbuild: change CONFIG_LOCALVERSION_AUTO to use a git-describe-ish format" to use git describe to come up with a tag. Which is nice, but git describe sometimes can't describe the revision. Commit 56b2f0706d82535fd8d85503f2dcc0be40c8e55d ("setlocalversion: do not describe if there is nothing to describe") addressed this, but there is still no tag generated. So, generate a plain abbreviated sha1 tag like setlocalversion used to when git describe comes up short. Signed-off-by: Trent Piepho CC: Jan Engelhardt Signed-off-by: Sam Ravnborg --- scripts/setlocalversion | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 453faffe18a7..72d233528ade 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -9,11 +9,13 @@ usage() { cd "${1:-.}" || usage # Check for git and a git repo. -if head=`git rev-parse --verify HEAD 2>/dev/null`; then +if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then # Do we have an untagged version? if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then if tag=`git describe 2>/dev/null`; then echo $tag | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' + else + printf '%s%s' -g $head fi fi -- cgit v1.2.3 From 15a2ee74d22674c58f347b16b3af5601fa4e15db Mon Sep 17 00:00:00 2001 From: Jeremy Huntwork Date: Wed, 29 Oct 2008 14:20:13 -0700 Subject: Fix incompatibility with versions of Perl less than 5.6.0 Fix headers_install.pl and headers_check.pl to be compatible with versions of Perl less than 5.6.0. It has been tested with Perl 5.005_03 and 5.8.8. I realize this may not be an issue for most people, but there will still be some that hit it, I imagine. There are three basic issues: 1. Prior to 5.6.0 open() only used 2 arguments, and the versions of the scripts in 2.6.27.1 use 3. 2. 5.6.0 also introduced the ability to use uninitialized scalar variables as file handles, which the current scripts make use of. 3. Lastly, 5.6.0 also introduced the pragma 'use warnings'. We can use the -w switch and be backwards compatible. Signed-off-by: Jeremy Huntwork Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/headers_check.pl | 10 +++++----- scripts/headers_install.pl | 17 +++++++++-------- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index 15d53a6b1a1f..488a3b1f760f 100644 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # # headers_check.pl execute a number of trivial consistency checks # @@ -17,7 +17,6 @@ # 2) TODO: check for leaked CONFIG_ symbols use strict; -use warnings; my ($dir, $arch, @files) = @ARGV; @@ -27,14 +26,15 @@ my $lineno = 0; my $filename; foreach my $file (@files) { + local *FH; $filename = $file; - open(my $fh, '<', "$filename") or die "$filename: $!\n"; + open(FH, "<$filename") or die "$filename: $!\n"; $lineno = 0; - while ($line = <$fh>) { + while ($line = ) { $lineno++; check_include(); } - close $fh; + close FH; } exit $ret; diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl index 68591cd08731..7d2b4146e02f 100644 --- a/scripts/headers_install.pl +++ b/scripts/headers_install.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # # headers_install prepare the listed header files for use in # user space and copy the files to their destination. @@ -17,28 +17,29 @@ # 3) Drop all sections defined out by __KERNEL__ (using unifdef) use strict; -use warnings; my ($readdir, $installdir, $arch, @files) = @ARGV; my $unifdef = "scripts/unifdef -U__KERNEL__"; foreach my $file (@files) { + local *INFILE; + local *OUTFILE; my $tmpfile = "$installdir/$file.tmp"; - open(my $infile, '<', "$readdir/$file") + open(INFILE, "<$readdir/$file") or die "$readdir/$file: $!\n"; - open(my $outfile, '>', "$tmpfile") or die "$tmpfile: $!\n"; - while (my $line = <$infile>) { + open(OUTFILE, ">$tmpfile") or die "$tmpfile: $!\n"; + while (my $line = ) { $line =~ s/([\s(])__user\s/$1/g; $line =~ s/([\s(])__force\s/$1/g; $line =~ s/([\s(])__iomem\s/$1/g; $line =~ s/\s__attribute_const__\s/ /g; $line =~ s/\s__attribute_const__$//g; $line =~ s/^#include //; - printf $outfile "%s", $line; + printf OUTFILE "%s", $line; } - close $outfile; - close $infile; + close OUTFILE; + close INFILE; system $unifdef . " $tmpfile > $installdir/$file"; unlink $tmpfile; } -- cgit v1.2.3 From bf1b36445dc868cbbde194aa1dd87e38fe24cf16 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sat, 13 Sep 2008 17:08:31 +0100 Subject: kbuild: Fixup deb-pkg target to generate separate firmware deb The below is a simplistic fix for "make deb-pkg"; it splits the firmware out to a linux-firmware-image package and adds an (unversioned) Suggests to the linux package for this firmware. Signed-Off-By: Jonathan McDowell Acked-by: Frans Pop Signed-off-by: Sam Ravnborg --- scripts/package/builddeb | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/package/builddeb b/scripts/package/builddeb index ba6bf5d5abf9..1264b8e2829d 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -15,15 +15,18 @@ set -e version=$KERNELRELEASE revision=`cat .version` tmpdir="$objtree/debian/tmp" +fwdir="$objtree/debian/fwtmp" packagename=linux-$version +fwpackagename=linux-firmware-image if [ "$ARCH" == "um" ] ; then packagename=user-mode-linux-$version fi # Setup the directory structure -rm -rf "$tmpdir" +rm -rf "$tmpdir" "$fwdir" mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot" +mkdir -p "$fwdir/DEBIAN" "$fwdir/lib" if [ "$ARCH" == "um" ] ; then mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/share/doc/$packagename" "$tmpdir/usr/bin" fi @@ -107,6 +110,7 @@ Standards-Version: 3.6.1 Package: $packagename Provides: kernel-image-$version, linux-image-$version +Suggests: $fwpackagename Architecture: any Description: Linux kernel, version $version This package contains the Linux kernel, modules and corresponding other @@ -118,8 +122,24 @@ fi chown -R root:root "$tmpdir" chmod -R go-w "$tmpdir" +# Do we have firmware? Move it out of the way and build it into a package. +if [ -e "$tmpdir/lib/firmware" ]; then + mv "$tmpdir/lib/firmware" "$fwdir/lib/" + + cat <> debian/control + +Package: $fwpackagename +Architecture: all +Description: Linux kernel firmware, version $version + This package contains firmware from the Linux kernel, version $version +EOF + + dpkg-gencontrol -isp -p$fwpackagename -P"$fwdir" + dpkg --build "$fwdir" .. +fi + # Perform the final magic -dpkg-gencontrol -isp +dpkg-gencontrol -isp -p$packagename dpkg --build "$tmpdir" .. exit 0 -- cgit v1.2.3