diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Kbuild.include | 7 | ||||
| -rw-r--r-- | scripts/Makefile | 1 | ||||
| -rw-r--r-- | scripts/Makefile.build | 5 | ||||
| -rw-r--r-- | scripts/Makefile.clean | 3 | ||||
| -rw-r--r-- | scripts/Makefile.kasan | 25 | ||||
| -rw-r--r-- | scripts/Makefile.lib | 10 | ||||
| -rw-r--r-- | scripts/asn1_compiler.c | 30 | ||||
| -rwxr-xr-x | scripts/checkpatch.pl | 147 | ||||
| -rwxr-xr-x | scripts/diffconfig | 1 | ||||
| -rw-r--r-- | scripts/gdb/Makefile | 1 | ||||
| -rw-r--r-- | scripts/gdb/linux/.gitignore | 2 | ||||
| -rw-r--r-- | scripts/gdb/linux/Makefile | 11 | ||||
| -rw-r--r-- | scripts/gdb/linux/__init__.py | 1 | ||||
| -rw-r--r-- | scripts/gdb/linux/cpus.py | 135 | ||||
| -rw-r--r-- | scripts/gdb/linux/dmesg.py | 65 | ||||
| -rw-r--r-- | scripts/gdb/linux/modules.py | 103 | ||||
| -rw-r--r-- | scripts/gdb/linux/symbols.py | 177 | ||||
| -rw-r--r-- | scripts/gdb/linux/tasks.py | 100 | ||||
| -rw-r--r-- | scripts/gdb/linux/utils.py | 156 | ||||
| -rw-r--r-- | scripts/gdb/vmlinux-gdb.py | 30 | ||||
| -rw-r--r-- | scripts/kconfig/confdata.c | 1 | ||||
| -rwxr-xr-x | scripts/kconfig/merge_config.sh | 5 | ||||
| -rw-r--r-- | scripts/module-common.lds | 23 | ||||
| -rwxr-xr-x | scripts/package/builddeb | 17 | ||||
| -rwxr-xr-x | scripts/recordmcount.pl | 9 |
25 files changed, 1002 insertions, 63 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index edd2794569db..d3437b82ac25 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include | |||
| @@ -129,17 +129,15 @@ cc-disable-warning = $(call try-run,\ | |||
| 129 | $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) | 129 | $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) |
| 130 | 130 | ||
| 131 | # cc-version | 131 | # cc-version |
| 132 | # Usage gcc-ver := $(call cc-version) | ||
| 133 | cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) | 132 | cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) |
| 134 | 133 | ||
| 135 | # cc-fullversion | 134 | # cc-fullversion |
| 136 | # Usage gcc-ver := $(call cc-fullversion) | ||
| 137 | cc-fullversion = $(shell $(CONFIG_SHELL) \ | 135 | cc-fullversion = $(shell $(CONFIG_SHELL) \ |
| 138 | $(srctree)/scripts/gcc-version.sh -p $(CC)) | 136 | $(srctree)/scripts/gcc-version.sh -p $(CC)) |
| 139 | 137 | ||
| 140 | # cc-ifversion | 138 | # cc-ifversion |
| 141 | # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) | 139 | # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) |
| 142 | cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3)) | 140 | cc-ifversion = $(shell [ $(cc-version) $(1) $(2) ] && echo $(3) || echo $(4)) |
| 143 | 141 | ||
| 144 | # cc-ldoption | 142 | # cc-ldoption |
| 145 | # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both) | 143 | # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both) |
| @@ -157,13 +155,12 @@ ld-option = $(call try-run,\ | |||
| 157 | ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2)) | 155 | ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2)) |
| 158 | 156 | ||
| 159 | # ld-version | 157 | # ld-version |
| 160 | # Usage: $(call ld-version) | ||
| 161 | # Note this is mainly for HJ Lu's 3 number binutil versions | 158 | # Note this is mainly for HJ Lu's 3 number binutil versions |
| 162 | ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh) | 159 | ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh) |
| 163 | 160 | ||
| 164 | # ld-ifversion | 161 | # ld-ifversion |
| 165 | # Usage: $(call ld-ifversion, -ge, 22252, y) | 162 | # Usage: $(call ld-ifversion, -ge, 22252, y) |
| 166 | ld-ifversion = $(shell [ $(call ld-version) $(1) $(2) ] && echo $(3)) | 163 | ld-ifversion = $(shell [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4)) |
| 167 | 164 | ||
| 168 | ###### | 165 | ###### |
| 169 | 166 | ||
diff --git a/scripts/Makefile b/scripts/Makefile index 72902b5f2721..2016a64497ab 100644 --- a/scripts/Makefile +++ b/scripts/Makefile | |||
| @@ -36,6 +36,7 @@ subdir-$(CONFIG_MODVERSIONS) += genksyms | |||
| 36 | subdir-y += mod | 36 | subdir-y += mod |
| 37 | subdir-$(CONFIG_SECURITY_SELINUX) += selinux | 37 | subdir-$(CONFIG_SECURITY_SELINUX) += selinux |
| 38 | subdir-$(CONFIG_DTC) += dtc | 38 | subdir-$(CONFIG_DTC) += dtc |
| 39 | subdir-$(CONFIG_GDB_SCRIPTS) += gdb | ||
| 39 | 40 | ||
| 40 | # Let clean descend into subdirs | 41 | # Let clean descend into subdirs |
| 41 | subdir- += basic kconfig package | 42 | subdir- += basic kconfig package |
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 649ce6844033..01df30af4d4a 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build | |||
| @@ -234,8 +234,9 @@ sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH | |||
| 234 | "$(if $(part-of-module),1,0)" "$(@)"; | 234 | "$(if $(part-of-module),1,0)" "$(@)"; |
| 235 | recordmcount_source := $(srctree)/scripts/recordmcount.pl | 235 | recordmcount_source := $(srctree)/scripts/recordmcount.pl |
| 236 | endif | 236 | endif |
| 237 | cmd_record_mcount = \ | 237 | cmd_record_mcount = \ |
| 238 | if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \ | 238 | if [ "$(findstring $(CC_FLAGS_FTRACE),$(_c_flags))" = \ |
| 239 | "$(CC_FLAGS_FTRACE)" ]; then \ | ||
| 239 | $(sub_cmd_record_mcount) \ | 240 | $(sub_cmd_record_mcount) \ |
| 240 | fi; | 241 | fi; |
| 241 | endif | 242 | endif |
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 627f8cbbedb8..55c96cb8070f 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean | |||
| @@ -71,9 +71,6 @@ endif | |||
| 71 | ifneq ($(strip $(__clean-dirs)),) | 71 | ifneq ($(strip $(__clean-dirs)),) |
| 72 | +$(call cmd,cleandir) | 72 | +$(call cmd,cleandir) |
| 73 | endif | 73 | endif |
| 74 | ifneq ($(strip $(clean-rule)),) | ||
| 75 | +$(clean-rule) | ||
| 76 | endif | ||
| 77 | @: | 74 | @: |
| 78 | 75 | ||
| 79 | 76 | ||
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan new file mode 100644 index 000000000000..631619b2b118 --- /dev/null +++ b/scripts/Makefile.kasan | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | ifdef CONFIG_KASAN | ||
| 2 | ifdef CONFIG_KASAN_INLINE | ||
| 3 | call_threshold := 10000 | ||
| 4 | else | ||
| 5 | call_threshold := 0 | ||
| 6 | endif | ||
| 7 | |||
| 8 | CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address | ||
| 9 | |||
| 10 | CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \ | ||
| 11 | -fasan-shadow-offset=$(CONFIG_KASAN_SHADOW_OFFSET) \ | ||
| 12 | --param asan-stack=1 --param asan-globals=1 \ | ||
| 13 | --param asan-instrumentation-with-call-threshold=$(call_threshold)) | ||
| 14 | |||
| 15 | ifeq ($(call cc-option, $(CFLAGS_KASAN_MINIMAL) -Werror),) | ||
| 16 | $(warning Cannot use CONFIG_KASAN: \ | ||
| 17 | -fsanitize=kernel-address is not supported by compiler) | ||
| 18 | else | ||
| 19 | ifeq ($(CFLAGS_KASAN),) | ||
| 20 | $(warning CONFIG_KASAN: compiler does not support all options.\ | ||
| 21 | Trying minimal configuration) | ||
| 22 | CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL) | ||
| 23 | endif | ||
| 24 | endif | ||
| 25 | endif | ||
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 511755200634..044eb4f89a91 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib | |||
| @@ -119,6 +119,16 @@ _c_flags += $(if $(patsubst n%,, \ | |||
| 119 | $(CFLAGS_GCOV)) | 119 | $(CFLAGS_GCOV)) |
| 120 | endif | 120 | endif |
| 121 | 121 | ||
| 122 | # | ||
| 123 | # Enable address sanitizer flags for kernel except some files or directories | ||
| 124 | # we don't want to check (depends on variables KASAN_SANITIZE_obj.o, KASAN_SANITIZE) | ||
| 125 | # | ||
| 126 | ifeq ($(CONFIG_KASAN),y) | ||
| 127 | _c_flags += $(if $(patsubst n%,, \ | ||
| 128 | $(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \ | ||
| 129 | $(CFLAGS_KASAN)) | ||
| 130 | endif | ||
| 131 | |||
| 122 | # If building the kernel in a separate objtree expand all occurrences | 132 | # If building the kernel in a separate objtree expand all occurrences |
| 123 | # of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). | 133 | # of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). |
| 124 | 134 | ||
diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c index 91c4117637ae..7750e9c31483 100644 --- a/scripts/asn1_compiler.c +++ b/scripts/asn1_compiler.c | |||
| @@ -311,6 +311,9 @@ struct token { | |||
| 311 | 311 | ||
| 312 | static struct token *token_list; | 312 | static struct token *token_list; |
| 313 | static unsigned nr_tokens; | 313 | static unsigned nr_tokens; |
| 314 | static _Bool verbose; | ||
| 315 | |||
| 316 | #define debug(fmt, ...) do { if (verbose) printf(fmt, ## __VA_ARGS__); } while (0) | ||
| 314 | 317 | ||
| 315 | static int directive_compare(const void *_key, const void *_pdir) | 318 | static int directive_compare(const void *_key, const void *_pdir) |
| 316 | { | 319 | { |
| @@ -322,21 +325,21 @@ static int directive_compare(const void *_key, const void *_pdir) | |||
| 322 | dlen = strlen(dir); | 325 | dlen = strlen(dir); |
| 323 | clen = (dlen < token->size) ? dlen : token->size; | 326 | clen = (dlen < token->size) ? dlen : token->size; |
| 324 | 327 | ||
| 325 | //printf("cmp(%*.*s,%s) = ", | 328 | //debug("cmp(%*.*s,%s) = ", |
| 326 | // (int)token->size, (int)token->size, token->value, | 329 | // (int)token->size, (int)token->size, token->value, |
| 327 | // dir); | 330 | // dir); |
| 328 | 331 | ||
| 329 | val = memcmp(token->value, dir, clen); | 332 | val = memcmp(token->value, dir, clen); |
| 330 | if (val != 0) { | 333 | if (val != 0) { |
| 331 | //printf("%d [cmp]\n", val); | 334 | //debug("%d [cmp]\n", val); |
| 332 | return val; | 335 | return val; |
| 333 | } | 336 | } |
| 334 | 337 | ||
| 335 | if (dlen == token->size) { | 338 | if (dlen == token->size) { |
| 336 | //printf("0\n"); | 339 | //debug("0\n"); |
| 337 | return 0; | 340 | return 0; |
| 338 | } | 341 | } |
| 339 | //printf("%d\n", (int)dlen - (int)token->size); | 342 | //debug("%d\n", (int)dlen - (int)token->size); |
| 340 | return dlen - token->size; /* shorter -> negative */ | 343 | return dlen - token->size; /* shorter -> negative */ |
| 341 | } | 344 | } |
| 342 | 345 | ||
| @@ -515,13 +518,13 @@ static void tokenise(char *buffer, char *end) | |||
| 515 | } | 518 | } |
| 516 | 519 | ||
| 517 | nr_tokens = tix; | 520 | nr_tokens = tix; |
| 518 | printf("Extracted %u tokens\n", nr_tokens); | 521 | debug("Extracted %u tokens\n", nr_tokens); |
| 519 | 522 | ||
| 520 | #if 0 | 523 | #if 0 |
| 521 | { | 524 | { |
| 522 | int n; | 525 | int n; |
| 523 | for (n = 0; n < nr_tokens; n++) | 526 | for (n = 0; n < nr_tokens; n++) |
| 524 | printf("Token %3u: '%*.*s'\n", | 527 | debug("Token %3u: '%*.*s'\n", |
| 525 | n, | 528 | n, |
| 526 | (int)token_list[n].size, (int)token_list[n].size, | 529 | (int)token_list[n].size, (int)token_list[n].size, |
| 527 | token_list[n].value); | 530 | token_list[n].value); |
| @@ -542,6 +545,7 @@ int main(int argc, char **argv) | |||
| 542 | ssize_t readlen; | 545 | ssize_t readlen; |
| 543 | FILE *out, *hdr; | 546 | FILE *out, *hdr; |
| 544 | char *buffer, *p; | 547 | char *buffer, *p; |
| 548 | char *kbuild_verbose; | ||
| 545 | int fd; | 549 | int fd; |
| 546 | 550 | ||
| 547 | if (argc != 4) { | 551 | if (argc != 4) { |
| @@ -550,6 +554,10 @@ int main(int argc, char **argv) | |||
| 550 | exit(2); | 554 | exit(2); |
| 551 | } | 555 | } |
| 552 | 556 | ||
| 557 | kbuild_verbose = getenv("KBUILD_VERBOSE"); | ||
| 558 | if (kbuild_verbose) | ||
| 559 | verbose = atoi(kbuild_verbose); | ||
| 560 | |||
| 553 | filename = argv[1]; | 561 | filename = argv[1]; |
| 554 | outputname = argv[2]; | 562 | outputname = argv[2]; |
| 555 | headername = argv[3]; | 563 | headername = argv[3]; |
| @@ -748,11 +756,11 @@ static void build_type_list(void) | |||
| 748 | 756 | ||
| 749 | qsort(type_index, nr, sizeof(type_index[0]), type_index_compare); | 757 | qsort(type_index, nr, sizeof(type_index[0]), type_index_compare); |
| 750 | 758 | ||
| 751 | printf("Extracted %u types\n", nr_types); | 759 | debug("Extracted %u types\n", nr_types); |
| 752 | #if 0 | 760 | #if 0 |
| 753 | for (n = 0; n < nr_types; n++) { | 761 | for (n = 0; n < nr_types; n++) { |
| 754 | struct type *type = type_index[n]; | 762 | struct type *type = type_index[n]; |
| 755 | printf("- %*.*s\n", | 763 | debug("- %*.*s\n", |
| 756 | (int)type->name->size, | 764 | (int)type->name->size, |
| 757 | (int)type->name->size, | 765 | (int)type->name->size, |
| 758 | type->name->value); | 766 | type->name->value); |
| @@ -793,7 +801,7 @@ static void parse(void) | |||
| 793 | 801 | ||
| 794 | } while (type++, !(type->flags & TYPE_STOP_MARKER)); | 802 | } while (type++, !(type->flags & TYPE_STOP_MARKER)); |
| 795 | 803 | ||
| 796 | printf("Extracted %u actions\n", nr_actions); | 804 | debug("Extracted %u actions\n", nr_actions); |
| 797 | } | 805 | } |
| 798 | 806 | ||
| 799 | static struct element *element_list; | 807 | static struct element *element_list; |
| @@ -1284,7 +1292,7 @@ static void render(FILE *out, FILE *hdr) | |||
| 1284 | } | 1292 | } |
| 1285 | 1293 | ||
| 1286 | /* We do two passes - the first one calculates all the offsets */ | 1294 | /* We do two passes - the first one calculates all the offsets */ |
| 1287 | printf("Pass 1\n"); | 1295 | debug("Pass 1\n"); |
| 1288 | nr_entries = 0; | 1296 | nr_entries = 0; |
| 1289 | root = &type_list[0]; | 1297 | root = &type_list[0]; |
| 1290 | render_element(NULL, root->element, NULL); | 1298 | render_element(NULL, root->element, NULL); |
| @@ -1295,7 +1303,7 @@ static void render(FILE *out, FILE *hdr) | |||
| 1295 | e->flags &= ~ELEMENT_RENDERED; | 1303 | e->flags &= ~ELEMENT_RENDERED; |
| 1296 | 1304 | ||
| 1297 | /* And then we actually render */ | 1305 | /* And then we actually render */ |
| 1298 | printf("Pass 2\n"); | 1306 | debug("Pass 2\n"); |
| 1299 | fprintf(out, "\n"); | 1307 | fprintf(out, "\n"); |
| 1300 | fprintf(out, "static const unsigned char %s_machine[] = {\n", | 1308 | fprintf(out, "static const unsigned char %s_machine[] = {\n", |
| 1301 | grammar_name); | 1309 | grammar_name); |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index f0bb6d60c07b..d12435992dea 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
| @@ -278,6 +278,7 @@ our $Attribute = qr{ | |||
| 278 | __noreturn| | 278 | __noreturn| |
| 279 | __used| | 279 | __used| |
| 280 | __cold| | 280 | __cold| |
| 281 | __pure| | ||
| 281 | __noclone| | 282 | __noclone| |
| 282 | __deprecated| | 283 | __deprecated| |
| 283 | __read_mostly| | 284 | __read_mostly| |
| @@ -298,6 +299,7 @@ our $Binary = qr{(?i)0b[01]+$Int_type?}; | |||
| 298 | our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; | 299 | our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; |
| 299 | our $Int = qr{[0-9]+$Int_type?}; | 300 | our $Int = qr{[0-9]+$Int_type?}; |
| 300 | our $Octal = qr{0[0-7]+$Int_type?}; | 301 | our $Octal = qr{0[0-7]+$Int_type?}; |
| 302 | our $String = qr{"[X\t]*"}; | ||
| 301 | our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; | 303 | our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; |
| 302 | our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; | 304 | our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; |
| 303 | our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; | 305 | our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; |
| @@ -337,6 +339,11 @@ our $UTF8 = qr{ | |||
| 337 | | $NON_ASCII_UTF8 | 339 | | $NON_ASCII_UTF8 |
| 338 | }x; | 340 | }x; |
| 339 | 341 | ||
| 342 | our $typeOtherOSTypedefs = qr{(?x: | ||
| 343 | u_(?:char|short|int|long) | # bsd | ||
| 344 | u(?:nchar|short|int|long) # sysv | ||
| 345 | )}; | ||
| 346 | |||
| 340 | our $typeTypedefs = qr{(?x: | 347 | our $typeTypedefs = qr{(?x: |
| 341 | (?:__)?(?:u|s|be|le)(?:8|16|32|64)| | 348 | (?:__)?(?:u|s|be|le)(?:8|16|32|64)| |
| 342 | atomic_t | 349 | atomic_t |
| @@ -473,6 +480,7 @@ sub build_types { | |||
| 473 | (?:$Modifier\s+|const\s+)* | 480 | (?:$Modifier\s+|const\s+)* |
| 474 | (?: | 481 | (?: |
| 475 | (?:typeof|__typeof__)\s*\([^\)]*\)| | 482 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
| 483 | (?:$typeOtherOSTypedefs\b)| | ||
| 476 | (?:$typeTypedefs\b)| | 484 | (?:$typeTypedefs\b)| |
| 477 | (?:${all}\b) | 485 | (?:${all}\b) |
| 478 | ) | 486 | ) |
| @@ -490,6 +498,7 @@ sub build_types { | |||
| 490 | (?: | 498 | (?: |
| 491 | (?:typeof|__typeof__)\s*\([^\)]*\)| | 499 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
| 492 | (?:$typeTypedefs\b)| | 500 | (?:$typeTypedefs\b)| |
| 501 | (?:$typeOtherOSTypedefs\b)| | ||
| 493 | (?:${allWithAttr}\b) | 502 | (?:${allWithAttr}\b) |
| 494 | ) | 503 | ) |
| 495 | (?:\s+$Modifier|\s+const)* | 504 | (?:\s+$Modifier|\s+const)* |
| @@ -517,7 +526,7 @@ our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; | |||
| 517 | 526 | ||
| 518 | our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; | 527 | our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; |
| 519 | our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; | 528 | our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; |
| 520 | our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)}; | 529 | our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; |
| 521 | 530 | ||
| 522 | our $declaration_macros = qr{(?x: | 531 | our $declaration_macros = qr{(?x: |
| 523 | (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,2}\s*\(| | 532 | (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,2}\s*\(| |
| @@ -632,6 +641,8 @@ sub git_commit_info { | |||
| 632 | $output =~ s/^\s*//gm; | 641 | $output =~ s/^\s*//gm; |
| 633 | my @lines = split("\n", $output); | 642 | my @lines = split("\n", $output); |
| 634 | 643 | ||
| 644 | return ($id, $desc) if ($#lines < 0); | ||
| 645 | |||
| 635 | if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { | 646 | if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { |
| 636 | # Maybe one day convert this block of bash into something that returns | 647 | # Maybe one day convert this block of bash into something that returns |
| 637 | # all matching commit ids, but it's very slow... | 648 | # all matching commit ids, but it's very slow... |
| @@ -2159,6 +2170,13 @@ sub process { | |||
| 2159 | } | 2170 | } |
| 2160 | } | 2171 | } |
| 2161 | 2172 | ||
| 2173 | # Check email subject for common tools that don't need to be mentioned | ||
| 2174 | if ($in_header_lines && | ||
| 2175 | $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { | ||
| 2176 | WARN("EMAIL_SUBJECT", | ||
| 2177 | "A patch subject line should describe the change not the tool that found it\n" . $herecurr); | ||
| 2178 | } | ||
| 2179 | |||
| 2162 | # Check for old stable address | 2180 | # Check for old stable address |
| 2163 | if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { | 2181 | if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { |
| 2164 | ERROR("STABLE_ADDRESS", | 2182 | ERROR("STABLE_ADDRESS", |
| @@ -2171,21 +2189,49 @@ sub process { | |||
| 2171 | "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); | 2189 | "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); |
| 2172 | } | 2190 | } |
| 2173 | 2191 | ||
| 2174 | # Check for improperly formed commit descriptions | 2192 | # Check for git id commit length and improperly formed commit descriptions |
| 2175 | if ($in_commit_log && | 2193 | if ($in_commit_log && $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i) { |
| 2176 | $line =~ /\bcommit\s+[0-9a-f]{5,}/i && | ||
| 2177 | !($line =~ /\b[Cc]ommit [0-9a-f]{12,40} \("/ || | ||
| 2178 | ($line =~ /\b[Cc]ommit [0-9a-f]{12,40}\s*$/ && | ||
| 2179 | defined $rawlines[$linenr] && | ||
| 2180 | $rawlines[$linenr] =~ /^\s*\("/))) { | ||
| 2181 | $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i; | ||
| 2182 | my $init_char = $1; | 2194 | my $init_char = $1; |
| 2183 | my $orig_commit = lc($2); | 2195 | my $orig_commit = lc($2); |
| 2184 | my $id = '01234567890ab'; | 2196 | my $short = 1; |
| 2185 | my $desc = 'commit description'; | 2197 | my $long = 0; |
| 2186 | ($id, $desc) = git_commit_info($orig_commit, $id, $desc); | 2198 | my $case = 1; |
| 2187 | ERROR("GIT_COMMIT_ID", | 2199 | my $space = 1; |
| 2188 | "Please use 12 or more chars for the git commit ID like: '${init_char}ommit $id (\"$desc\")'\n" . $herecurr); | 2200 | my $hasdesc = 0; |
| 2201 | my $hasparens = 0; | ||
| 2202 | my $id = '0123456789ab'; | ||
| 2203 | my $orig_desc = "commit description"; | ||
| 2204 | my $description = ""; | ||
| 2205 | |||
| 2206 | $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); | ||
| 2207 | $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); | ||
| 2208 | $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); | ||
| 2209 | $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); | ||
| 2210 | if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { | ||
| 2211 | $orig_desc = $1; | ||
| 2212 | $hasparens = 1; | ||
| 2213 | } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && | ||
| 2214 | defined $rawlines[$linenr] && | ||
| 2215 | $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { | ||
| 2216 | $orig_desc = $1; | ||
| 2217 | $hasparens = 1; | ||
| 2218 | } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && | ||
| 2219 | defined $rawlines[$linenr] && | ||
| 2220 | $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { | ||
| 2221 | $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; | ||
| 2222 | $orig_desc = $1; | ||
| 2223 | $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; | ||
| 2224 | $orig_desc .= " " . $1; | ||
| 2225 | $hasparens = 1; | ||
| 2226 | } | ||
| 2227 | |||
| 2228 | ($id, $description) = git_commit_info($orig_commit, | ||
| 2229 | $id, $orig_desc); | ||
| 2230 | |||
| 2231 | if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) { | ||
| 2232 | ERROR("GIT_COMMIT_ID", | ||
| 2233 | "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); | ||
| 2234 | } | ||
| 2189 | } | 2235 | } |
| 2190 | 2236 | ||
| 2191 | # Check for added, moved or deleted files | 2237 | # Check for added, moved or deleted files |
| @@ -2355,6 +2401,13 @@ sub process { | |||
| 2355 | "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); | 2401 | "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); |
| 2356 | } | 2402 | } |
| 2357 | 2403 | ||
| 2404 | # discourage the use of boolean for type definition attributes of Kconfig options | ||
| 2405 | if ($realfile =~ /Kconfig/ && | ||
| 2406 | $line =~ /^\+\s*\bboolean\b/) { | ||
| 2407 | WARN("CONFIG_TYPE_BOOLEAN", | ||
| 2408 | "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); | ||
| 2409 | } | ||
| 2410 | |||
| 2358 | if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && | 2411 | if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && |
| 2359 | ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { | 2412 | ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { |
| 2360 | my $flag = $1; | 2413 | my $flag = $1; |
| @@ -2499,7 +2552,7 @@ sub process { | |||
| 2499 | } | 2552 | } |
| 2500 | } | 2553 | } |
| 2501 | 2554 | ||
| 2502 | if ($line =~ /^\+.*(\w+\s*)?\(\s*$Type\s*\)[ \t]+(?!$Assignment|$Arithmetic|[,;\({\[\<\>])/ && | 2555 | if ($line =~ /^\+.*(\w+\s*)?\(\s*$Type\s*\)[ \t]+(?!$Assignment|$Arithmetic|[,;:\?\(\{\}\[\<\>]|&&|\|\||\\$)/ && |
| 2503 | (!defined($1) || $1 !~ /sizeof\s*/)) { | 2556 | (!defined($1) || $1 !~ /sizeof\s*/)) { |
| 2504 | if (CHK("SPACING", | 2557 | if (CHK("SPACING", |
| 2505 | "No space is necessary after a cast\n" . $herecurr) && | 2558 | "No space is necessary after a cast\n" . $herecurr) && |
| @@ -3124,6 +3177,7 @@ sub process { | |||
| 3124 | $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && | 3177 | $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && |
| 3125 | $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && | 3178 | $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && |
| 3126 | $line !~ /\b$typeTypedefs\b/ && | 3179 | $line !~ /\b$typeTypedefs\b/ && |
| 3180 | $line !~ /\b$typeOtherOSTypedefs\b/ && | ||
| 3127 | $line !~ /\b__bitwise(?:__|)\b/) { | 3181 | $line !~ /\b__bitwise(?:__|)\b/) { |
| 3128 | WARN("NEW_TYPEDEFS", | 3182 | WARN("NEW_TYPEDEFS", |
| 3129 | "do not add new typedefs\n" . $herecurr); | 3183 | "do not add new typedefs\n" . $herecurr); |
| @@ -3200,7 +3254,7 @@ sub process { | |||
| 3200 | # check for uses of printk_ratelimit | 3254 | # check for uses of printk_ratelimit |
| 3201 | if ($line =~ /\bprintk_ratelimit\s*\(/) { | 3255 | if ($line =~ /\bprintk_ratelimit\s*\(/) { |
| 3202 | WARN("PRINTK_RATELIMITED", | 3256 | WARN("PRINTK_RATELIMITED", |
| 3203 | "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); | 3257 | "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); |
| 3204 | } | 3258 | } |
| 3205 | 3259 | ||
| 3206 | # printk should use KERN_* levels. Note that follow on printk's on the | 3260 | # printk should use KERN_* levels. Note that follow on printk's on the |
| @@ -3646,7 +3700,22 @@ sub process { | |||
| 3646 | $op eq '*' or $op eq '/' or | 3700 | $op eq '*' or $op eq '/' or |
| 3647 | $op eq '%') | 3701 | $op eq '%') |
| 3648 | { | 3702 | { |
| 3649 | if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { | 3703 | if ($check) { |
| 3704 | if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { | ||
| 3705 | if (CHK("SPACING", | ||
| 3706 | "spaces preferred around that '$op' $at\n" . $hereptr)) { | ||
| 3707 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; | ||
| 3708 | $fix_elements[$n + 2] =~ s/^\s+//; | ||
| 3709 | $line_fixed = 1; | ||
| 3710 | } | ||
| 3711 | } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { | ||
| 3712 | if (CHK("SPACING", | ||
| 3713 | "space preferred before that '$op' $at\n" . $hereptr)) { | ||
| 3714 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); | ||
| 3715 | $line_fixed = 1; | ||
| 3716 | } | ||
| 3717 | } | ||
| 3718 | } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { | ||
| 3650 | if (ERROR("SPACING", | 3719 | if (ERROR("SPACING", |
| 3651 | "need consistent spacing around '$op' $at\n" . $hereptr)) { | 3720 | "need consistent spacing around '$op' $at\n" . $hereptr)) { |
| 3652 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; | 3721 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; |
| @@ -4251,6 +4320,7 @@ sub process { | |||
| 4251 | $ctx = $dstat; | 4320 | $ctx = $dstat; |
| 4252 | 4321 | ||
| 4253 | $dstat =~ s/\\\n.//g; | 4322 | $dstat =~ s/\\\n.//g; |
| 4323 | $dstat =~ s/$;/ /g; | ||
| 4254 | 4324 | ||
| 4255 | if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { | 4325 | if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { |
| 4256 | my $stmts = $2; | 4326 | my $stmts = $2; |
| @@ -4417,12 +4487,18 @@ sub process { | |||
| 4417 | 4487 | ||
| 4418 | # check for unnecessary blank lines around braces | 4488 | # check for unnecessary blank lines around braces |
| 4419 | if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { | 4489 | if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { |
| 4420 | CHK("BRACES", | 4490 | if (CHK("BRACES", |
| 4421 | "Blank lines aren't necessary before a close brace '}'\n" . $hereprev); | 4491 | "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && |
| 4492 | $fix && $prevrawline =~ /^\+/) { | ||
| 4493 | fix_delete_line($fixlinenr - 1, $prevrawline); | ||
| 4494 | } | ||
| 4422 | } | 4495 | } |
| 4423 | if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { | 4496 | if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { |
| 4424 | CHK("BRACES", | 4497 | if (CHK("BRACES", |
| 4425 | "Blank lines aren't necessary after an open brace '{'\n" . $hereprev); | 4498 | "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && |
| 4499 | $fix) { | ||
| 4500 | fix_delete_line($fixlinenr, $rawline); | ||
| 4501 | } | ||
| 4426 | } | 4502 | } |
| 4427 | 4503 | ||
| 4428 | # no volatiles please | 4504 | # no volatiles please |
| @@ -4545,7 +4621,7 @@ sub process { | |||
| 4545 | } | 4621 | } |
| 4546 | 4622 | ||
| 4547 | # check for logging functions with KERN_<LEVEL> | 4623 | # check for logging functions with KERN_<LEVEL> |
| 4548 | if ($line !~ /printk\s*\(/ && | 4624 | if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && |
| 4549 | $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { | 4625 | $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { |
| 4550 | my $level = $1; | 4626 | my $level = $1; |
| 4551 | if (WARN("UNNECESSARY_KERN_LEVEL", | 4627 | if (WARN("UNNECESSARY_KERN_LEVEL", |
| @@ -4804,7 +4880,8 @@ sub process { | |||
| 4804 | # check for seq_printf uses that could be seq_puts | 4880 | # check for seq_printf uses that could be seq_puts |
| 4805 | if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { | 4881 | if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { |
| 4806 | my $fmt = get_quoted_string($line, $rawline); | 4882 | my $fmt = get_quoted_string($line, $rawline); |
| 4807 | if ($fmt ne "" && $fmt !~ /[^\\]\%/) { | 4883 | $fmt =~ s/%%//g; |
| 4884 | if ($fmt !~ /%/) { | ||
| 4808 | if (WARN("PREFER_SEQ_PUTS", | 4885 | if (WARN("PREFER_SEQ_PUTS", |
| 4809 | "Prefer seq_puts to seq_printf\n" . $herecurr) && | 4886 | "Prefer seq_puts to seq_printf\n" . $herecurr) && |
| 4810 | $fix) { | 4887 | $fix) { |
| @@ -5089,6 +5166,12 @@ sub process { | |||
| 5089 | } | 5166 | } |
| 5090 | } | 5167 | } |
| 5091 | 5168 | ||
| 5169 | # check for uses of __DATE__, __TIME__, __TIMESTAMP__ | ||
| 5170 | while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { | ||
| 5171 | ERROR("DATE_TIME", | ||
| 5172 | "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); | ||
| 5173 | } | ||
| 5174 | |||
| 5092 | # check for use of yield() | 5175 | # check for use of yield() |
| 5093 | if ($line =~ /\byield\s*\(\s*\)/) { | 5176 | if ($line =~ /\byield\s*\(\s*\)/) { |
| 5094 | WARN("YIELD", | 5177 | WARN("YIELD", |
| @@ -5140,8 +5223,9 @@ sub process { | |||
| 5140 | "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); | 5223 | "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); |
| 5141 | } | 5224 | } |
| 5142 | 5225 | ||
| 5143 | # check for various ops structs, ensure they are const. | 5226 | # check for various structs that are normally const (ops, kgdb, device_tree) |
| 5144 | my $struct_ops = qr{acpi_dock_ops| | 5227 | my $const_structs = qr{ |
| 5228 | acpi_dock_ops| | ||
| 5145 | address_space_operations| | 5229 | address_space_operations| |
| 5146 | backlight_ops| | 5230 | backlight_ops| |
| 5147 | block_device_operations| | 5231 | block_device_operations| |
| @@ -5164,6 +5248,7 @@ sub process { | |||
| 5164 | mtrr_ops| | 5248 | mtrr_ops| |
| 5165 | neigh_ops| | 5249 | neigh_ops| |
| 5166 | nlmsvc_binding| | 5250 | nlmsvc_binding| |
| 5251 | of_device_id| | ||
| 5167 | pci_raw_ops| | 5252 | pci_raw_ops| |
| 5168 | pipe_buf_operations| | 5253 | pipe_buf_operations| |
| 5169 | platform_hibernation_ops| | 5254 | platform_hibernation_ops| |
| @@ -5179,7 +5264,7 @@ sub process { | |||
| 5179 | usb_mon_operations| | 5264 | usb_mon_operations| |
| 5180 | wd_ops}x; | 5265 | wd_ops}x; |
| 5181 | if ($line !~ /\bconst\b/ && | 5266 | if ($line !~ /\bconst\b/ && |
| 5182 | $line =~ /\bstruct\s+($struct_ops)\b/) { | 5267 | $line =~ /\bstruct\s+($const_structs)\b/) { |
| 5183 | WARN("CONST_STRUCT", | 5268 | WARN("CONST_STRUCT", |
| 5184 | "struct $1 should normally be const\n" . | 5269 | "struct $1 should normally be const\n" . |
| 5185 | $herecurr); | 5270 | $herecurr); |
| @@ -5204,6 +5289,13 @@ sub process { | |||
| 5204 | "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); | 5289 | "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); |
| 5205 | } | 5290 | } |
| 5206 | 5291 | ||
| 5292 | # likely/unlikely comparisons similar to "(likely(foo) > 0)" | ||
| 5293 | if ($^V && $^V ge 5.10.0 && | ||
| 5294 | $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { | ||
| 5295 | WARN("LIKELY_MISUSE", | ||
| 5296 | "Using $1 should generally have parentheses around the comparison\n" . $herecurr); | ||
| 5297 | } | ||
| 5298 | |||
| 5207 | # whine mightly about in_atomic | 5299 | # whine mightly about in_atomic |
| 5208 | if ($line =~ /\bin_atomic\s*\(/) { | 5300 | if ($line =~ /\bin_atomic\s*\(/) { |
| 5209 | if ($realfile =~ m@^drivers/@) { | 5301 | if ($realfile =~ m@^drivers/@) { |
| @@ -5255,6 +5347,9 @@ sub process { | |||
| 5255 | length($val) ne 4)) { | 5347 | length($val) ne 4)) { |
| 5256 | ERROR("NON_OCTAL_PERMISSIONS", | 5348 | ERROR("NON_OCTAL_PERMISSIONS", |
| 5257 | "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr); | 5349 | "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr); |
| 5350 | } elsif ($val =~ /^$Octal$/ && (oct($val) & 02)) { | ||
| 5351 | ERROR("EXPORTED_WORLD_WRITABLE", | ||
| 5352 | "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); | ||
| 5258 | } | 5353 | } |
| 5259 | } | 5354 | } |
| 5260 | } | 5355 | } |
diff --git a/scripts/diffconfig b/scripts/diffconfig index 6d672836e187..0db267d0adc9 100755 --- a/scripts/diffconfig +++ b/scripts/diffconfig | |||
| @@ -28,7 +28,6 @@ If no config files are specified, .config and .config.old are used. | |||
| 28 | Example usage: | 28 | Example usage: |
| 29 | $ diffconfig .config config-with-some-changes | 29 | $ diffconfig .config config-with-some-changes |
| 30 | -EXT2_FS_XATTR n | 30 | -EXT2_FS_XATTR n |
| 31 | -EXT2_FS_XIP n | ||
| 32 | CRAMFS n -> y | 31 | CRAMFS n -> y |
| 33 | EXT2_FS y -> n | 32 | EXT2_FS y -> n |
| 34 | LOG_BUF_SHIFT 14 -> 16 | 33 | LOG_BUF_SHIFT 14 -> 16 |
diff --git a/scripts/gdb/Makefile b/scripts/gdb/Makefile new file mode 100644 index 000000000000..62f5f65becfd --- /dev/null +++ b/scripts/gdb/Makefile | |||
| @@ -0,0 +1 @@ | |||
| subdir-y := linux | |||
diff --git a/scripts/gdb/linux/.gitignore b/scripts/gdb/linux/.gitignore new file mode 100644 index 000000000000..52e4e61140d1 --- /dev/null +++ b/scripts/gdb/linux/.gitignore | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | *.pyc | ||
| 2 | *.pyo | ||
diff --git a/scripts/gdb/linux/Makefile b/scripts/gdb/linux/Makefile new file mode 100644 index 000000000000..6cf1ecf61057 --- /dev/null +++ b/scripts/gdb/linux/Makefile | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | always := gdb-scripts | ||
| 2 | |||
| 3 | SRCTREE := $(shell cd $(srctree) && /bin/pwd) | ||
| 4 | |||
| 5 | $(obj)/gdb-scripts: | ||
| 6 | ifneq ($(KBUILD_SRC),) | ||
| 7 | $(Q)ln -fsn $(SRCTREE)/$(obj)/*.py $(objtree)/$(obj) | ||
| 8 | endif | ||
| 9 | @: | ||
| 10 | |||
| 11 | clean-files := *.pyc *.pyo $(if $(KBUILD_SRC),*.py) | ||
diff --git a/scripts/gdb/linux/__init__.py b/scripts/gdb/linux/__init__.py new file mode 100644 index 000000000000..4680fb176337 --- /dev/null +++ b/scripts/gdb/linux/__init__.py | |||
| @@ -0,0 +1 @@ | |||
| # nothing to do for the initialization of this package | |||
diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py new file mode 100644 index 000000000000..4297b83fedef --- /dev/null +++ b/scripts/gdb/linux/cpus.py | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | # | ||
| 2 | # gdb helper commands and functions for Linux kernel debugging | ||
| 3 | # | ||
| 4 | # per-cpu tools | ||
| 5 | # | ||
| 6 | # Copyright (c) Siemens AG, 2011-2013 | ||
| 7 | # | ||
| 8 | # Authors: | ||
| 9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
| 10 | # | ||
| 11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
| 12 | # | ||
| 13 | |||
| 14 | import gdb | ||
| 15 | |||
| 16 | from linux import tasks, utils | ||
| 17 | |||
| 18 | |||
| 19 | MAX_CPUS = 4096 | ||
| 20 | |||
| 21 | |||
| 22 | def get_current_cpu(): | ||
| 23 | if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU: | ||
| 24 | return gdb.selected_thread().num - 1 | ||
| 25 | elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB: | ||
| 26 | tid = gdb.selected_thread().ptid[2] | ||
| 27 | if tid > (0x100000000 - MAX_CPUS - 2): | ||
| 28 | return 0x100000000 - tid - 2 | ||
| 29 | else: | ||
| 30 | return tasks.get_thread_info(tasks.get_task_by_pid(tid))['cpu'] | ||
| 31 | else: | ||
| 32 | raise gdb.GdbError("Sorry, obtaining the current CPU is not yet " | ||
| 33 | "supported with this gdb server.") | ||
| 34 | |||
| 35 | |||
| 36 | def per_cpu(var_ptr, cpu): | ||
| 37 | if cpu == -1: | ||
| 38 | cpu = get_current_cpu() | ||
| 39 | if utils.is_target_arch("sparc:v9"): | ||
| 40 | offset = gdb.parse_and_eval( | ||
| 41 | "trap_block[{0}].__per_cpu_base".format(str(cpu))) | ||
| 42 | else: | ||
| 43 | try: | ||
| 44 | offset = gdb.parse_and_eval( | ||
| 45 | "__per_cpu_offset[{0}]".format(str(cpu))) | ||
| 46 | except gdb.error: | ||
| 47 | # !CONFIG_SMP case | ||
| 48 | offset = 0 | ||
| 49 | pointer = var_ptr.cast(utils.get_long_type()) + offset | ||
| 50 | return pointer.cast(var_ptr.type).dereference() | ||
| 51 | |||
| 52 | |||
| 53 | cpu_mask = {} | ||
| 54 | |||
| 55 | |||
| 56 | def cpu_mask_invalidate(event): | ||
| 57 | global cpu_mask | ||
| 58 | cpu_mask = {} | ||
| 59 | gdb.events.stop.disconnect(cpu_mask_invalidate) | ||
| 60 | if hasattr(gdb.events, 'new_objfile'): | ||
| 61 | gdb.events.new_objfile.disconnect(cpu_mask_invalidate) | ||
| 62 | |||
| 63 | |||
| 64 | def cpu_list(mask_name): | ||
| 65 | global cpu_mask | ||
| 66 | mask = None | ||
| 67 | if mask_name in cpu_mask: | ||
| 68 | mask = cpu_mask[mask_name] | ||
| 69 | if mask is None: | ||
| 70 | mask = gdb.parse_and_eval(mask_name + ".bits") | ||
| 71 | if hasattr(gdb, 'events'): | ||
| 72 | cpu_mask[mask_name] = mask | ||
| 73 | gdb.events.stop.connect(cpu_mask_invalidate) | ||
| 74 | if hasattr(gdb.events, 'new_objfile'): | ||
| 75 | gdb.events.new_objfile.connect(cpu_mask_invalidate) | ||
| 76 | bits_per_entry = mask[0].type.sizeof * 8 | ||
| 77 | num_entries = mask.type.sizeof * 8 / bits_per_entry | ||
| 78 | entry = -1 | ||
| 79 | bits = 0 | ||
| 80 | |||
| 81 | while True: | ||
| 82 | while bits == 0: | ||
| 83 | entry += 1 | ||
| 84 | if entry == num_entries: | ||
| 85 | return | ||
| 86 | bits = mask[entry] | ||
| 87 | if bits != 0: | ||
| 88 | bit = 0 | ||
| 89 | break | ||
| 90 | |||
| 91 | while bits & 1 == 0: | ||
| 92 | bits >>= 1 | ||
| 93 | bit += 1 | ||
| 94 | |||
| 95 | cpu = entry * bits_per_entry + bit | ||
| 96 | |||
| 97 | bits >>= 1 | ||
| 98 | bit += 1 | ||
| 99 | |||
| 100 | yield cpu | ||
| 101 | |||
| 102 | |||
| 103 | class PerCpu(gdb.Function): | ||
| 104 | """Return per-cpu variable. | ||
| 105 | |||
| 106 | $lx_per_cpu("VAR"[, CPU]): Return the per-cpu variable called VAR for the | ||
| 107 | given CPU number. If CPU is omitted, the CPU of the current context is used. | ||
| 108 | Note that VAR has to be quoted as string.""" | ||
| 109 | |||
| 110 | def __init__(self): | ||
| 111 | super(PerCpu, self).__init__("lx_per_cpu") | ||
| 112 | |||
| 113 | def invoke(self, var_name, cpu=-1): | ||
| 114 | var_ptr = gdb.parse_and_eval("&" + var_name.string()) | ||
| 115 | return per_cpu(var_ptr, cpu) | ||
| 116 | |||
| 117 | |||
| 118 | PerCpu() | ||
| 119 | |||
| 120 | |||
| 121 | class LxCurrentFunc(gdb.Function): | ||
| 122 | """Return current task. | ||
| 123 | |||
| 124 | $lx_current([CPU]): Return the per-cpu task variable for the given CPU | ||
| 125 | number. If CPU is omitted, the CPU of the current context is used.""" | ||
| 126 | |||
| 127 | def __init__(self): | ||
| 128 | super(LxCurrentFunc, self).__init__("lx_current") | ||
| 129 | |||
| 130 | def invoke(self, cpu=-1): | ||
| 131 | var_ptr = gdb.parse_and_eval("¤t_task") | ||
| 132 | return per_cpu(var_ptr, cpu).dereference() | ||
| 133 | |||
| 134 | |||
| 135 | LxCurrentFunc() | ||
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py new file mode 100644 index 000000000000..3c947f0c5dad --- /dev/null +++ b/scripts/gdb/linux/dmesg.py | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | # | ||
| 2 | # gdb helper commands and functions for Linux kernel debugging | ||
| 3 | # | ||
| 4 | # kernel log buffer dump | ||
| 5 | # | ||
| 6 | # Copyright (c) Siemens AG, 2011, 2012 | ||
| 7 | # | ||
| 8 | # Authors: | ||
| 9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
| 10 | # | ||
| 11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
| 12 | # | ||
| 13 | |||
| 14 | import gdb | ||
| 15 | import string | ||
| 16 | |||
| 17 | from linux import utils | ||
| 18 | |||
| 19 | |||
| 20 | class LxDmesg(gdb.Command): | ||
| 21 | """Print Linux kernel log buffer.""" | ||
| 22 | |||
| 23 | def __init__(self): | ||
| 24 | super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA) | ||
| 25 | |||
| 26 | def invoke(self, arg, from_tty): | ||
| 27 | log_buf_addr = int(str(gdb.parse_and_eval("log_buf")).split()[0], 16) | ||
| 28 | log_first_idx = int(gdb.parse_and_eval("log_first_idx")) | ||
| 29 | log_next_idx = int(gdb.parse_and_eval("log_next_idx")) | ||
| 30 | log_buf_len = int(gdb.parse_and_eval("log_buf_len")) | ||
| 31 | |||
| 32 | inf = gdb.inferiors()[0] | ||
| 33 | start = log_buf_addr + log_first_idx | ||
| 34 | if log_first_idx < log_next_idx: | ||
| 35 | log_buf_2nd_half = -1 | ||
| 36 | length = log_next_idx - log_first_idx | ||
| 37 | log_buf = inf.read_memory(start, length) | ||
| 38 | else: | ||
| 39 | log_buf_2nd_half = log_buf_len - log_first_idx | ||
| 40 | log_buf = inf.read_memory(start, log_buf_2nd_half) + \ | ||
| 41 | inf.read_memory(log_buf_addr, log_next_idx) | ||
| 42 | |||
| 43 | pos = 0 | ||
| 44 | while pos < log_buf.__len__(): | ||
| 45 | length = utils.read_u16(log_buf[pos + 8:pos + 10]) | ||
| 46 | if length == 0: | ||
| 47 | if log_buf_2nd_half == -1: | ||
| 48 | gdb.write("Corrupted log buffer!\n") | ||
| 49 | break | ||
| 50 | pos = log_buf_2nd_half | ||
| 51 | continue | ||
| 52 | |||
| 53 | text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) | ||
| 54 | text = log_buf[pos + 16:pos + 16 + text_len] | ||
| 55 | time_stamp = utils.read_u64(log_buf[pos:pos + 8]) | ||
| 56 | |||
| 57 | for line in memoryview(text).tobytes().splitlines(): | ||
| 58 | gdb.write("[{time:12.6f}] {line}\n".format( | ||
| 59 | time=time_stamp / 1000000000.0, | ||
| 60 | line=line)) | ||
| 61 | |||
| 62 | pos += length | ||
| 63 | |||
| 64 | |||
| 65 | LxDmesg() | ||
diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py new file mode 100644 index 000000000000..a1504c4f1900 --- /dev/null +++ b/scripts/gdb/linux/modules.py | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | # | ||
| 2 | # gdb helper commands and functions for Linux kernel debugging | ||
| 3 | # | ||
| 4 | # module tools | ||
| 5 | # | ||
| 6 | # Copyright (c) Siemens AG, 2013 | ||
| 7 | # | ||
| 8 | # Authors: | ||
| 9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
| 10 | # | ||
| 11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
| 12 | # | ||
| 13 | |||
| 14 | import gdb | ||
| 15 | |||
| 16 | from linux import cpus, utils | ||
| 17 | |||
| 18 | |||
| 19 | module_type = utils.CachedType("struct module") | ||
| 20 | |||
| 21 | |||
| 22 | def module_list(): | ||
| 23 | global module_type | ||
| 24 | module_ptr_type = module_type.get_type().pointer() | ||
| 25 | modules = gdb.parse_and_eval("modules") | ||
| 26 | entry = modules['next'] | ||
| 27 | end_of_list = modules.address | ||
| 28 | |||
| 29 | while entry != end_of_list: | ||
| 30 | yield utils.container_of(entry, module_ptr_type, "list") | ||
| 31 | entry = entry['next'] | ||
| 32 | |||
| 33 | |||
| 34 | def find_module_by_name(name): | ||
| 35 | for module in module_list(): | ||
| 36 | if module['name'].string() == name: | ||
| 37 | return module | ||
| 38 | return None | ||
| 39 | |||
| 40 | |||
| 41 | class LxModule(gdb.Function): | ||
| 42 | """Find module by name and return the module variable. | ||
| 43 | |||
| 44 | $lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules | ||
| 45 | of the target and return that module variable which MODULE matches.""" | ||
| 46 | |||
| 47 | def __init__(self): | ||
| 48 | super(LxModule, self).__init__("lx_module") | ||
| 49 | |||
| 50 | def invoke(self, mod_name): | ||
| 51 | mod_name = mod_name.string() | ||
| 52 | module = find_module_by_name(mod_name) | ||
| 53 | if module: | ||
| 54 | return module.dereference() | ||
| 55 | else: | ||
| 56 | raise gdb.GdbError("Unable to find MODULE " + mod_name) | ||
| 57 | |||
| 58 | |||
| 59 | LxModule() | ||
| 60 | |||
| 61 | |||
| 62 | class LxLsmod(gdb.Command): | ||
| 63 | """List currently loaded modules.""" | ||
| 64 | |||
| 65 | _module_use_type = utils.CachedType("struct module_use") | ||
| 66 | |||
| 67 | def __init__(self): | ||
| 68 | super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA) | ||
| 69 | |||
| 70 | def invoke(self, arg, from_tty): | ||
| 71 | gdb.write( | ||
| 72 | "Address{0} Module Size Used by\n".format( | ||
| 73 | " " if utils.get_long_type().sizeof == 8 else "")) | ||
| 74 | |||
| 75 | for module in module_list(): | ||
| 76 | ref = 0 | ||
| 77 | module_refptr = module['refptr'] | ||
| 78 | for cpu in cpus.cpu_list("cpu_possible_mask"): | ||
| 79 | refptr = cpus.per_cpu(module_refptr, cpu) | ||
| 80 | ref += refptr['incs'] | ||
| 81 | ref -= refptr['decs'] | ||
| 82 | |||
| 83 | gdb.write("{address} {name:<19} {size:>8} {ref}".format( | ||
| 84 | address=str(module['module_core']).split()[0], | ||
| 85 | name=module['name'].string(), | ||
| 86 | size=str(module['core_size']), | ||
| 87 | ref=str(ref))) | ||
| 88 | |||
| 89 | source_list = module['source_list'] | ||
| 90 | t = self._module_use_type.get_type().pointer() | ||
| 91 | entry = source_list['next'] | ||
| 92 | first = True | ||
| 93 | while entry != source_list.address: | ||
| 94 | use = utils.container_of(entry, t, "source_list") | ||
| 95 | gdb.write("{separator}{name}".format( | ||
| 96 | separator=" " if first else ",", | ||
| 97 | name=use['source']['name'].string())) | ||
| 98 | first = False | ||
| 99 | entry = entry['next'] | ||
| 100 | gdb.write("\n") | ||
| 101 | |||
| 102 | |||
| 103 | LxLsmod() | ||
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py new file mode 100644 index 000000000000..cd5bea965d4e --- /dev/null +++ b/scripts/gdb/linux/symbols.py | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | # | ||
| 2 | # gdb helper commands and functions for Linux kernel debugging | ||
| 3 | # | ||
| 4 | # load kernel and module symbols | ||
| 5 | # | ||
| 6 | # Copyright (c) Siemens AG, 2011-2013 | ||
| 7 | # | ||
| 8 | # Authors: | ||
| 9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
| 10 | # | ||
| 11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
| 12 | # | ||
| 13 | |||
| 14 | import gdb | ||
| 15 | import os | ||
| 16 | import re | ||
| 17 | import string | ||
| 18 | |||
| 19 | from linux import modules, utils | ||
| 20 | |||
| 21 | |||
| 22 | if hasattr(gdb, 'Breakpoint'): | ||
| 23 | class LoadModuleBreakpoint(gdb.Breakpoint): | ||
| 24 | def __init__(self, spec, gdb_command): | ||
| 25 | super(LoadModuleBreakpoint, self).__init__(spec, internal=True) | ||
| 26 | self.silent = True | ||
| 27 | self.gdb_command = gdb_command | ||
| 28 | |||
| 29 | def stop(self): | ||
| 30 | module = gdb.parse_and_eval("mod") | ||
| 31 | module_name = module['name'].string() | ||
| 32 | cmd = self.gdb_command | ||
| 33 | |||
| 34 | # enforce update if object file is not found | ||
| 35 | cmd.module_files_updated = False | ||
| 36 | |||
| 37 | # Disable pagination while reporting symbol (re-)loading. | ||
| 38 | # The console input is blocked in this context so that we would | ||
| 39 | # get stuck waiting for the user to acknowledge paged output. | ||
| 40 | show_pagination = gdb.execute("show pagination", to_string=True) | ||
| 41 | pagination = show_pagination.endswith("on.\n") | ||
| 42 | gdb.execute("set pagination off") | ||
| 43 | |||
| 44 | if module_name in cmd.loaded_modules: | ||
| 45 | gdb.write("refreshing all symbols to reload module " | ||
| 46 | "'{0}'\n".format(module_name)) | ||
| 47 | cmd.load_all_symbols() | ||
| 48 | else: | ||
| 49 | cmd.load_module_symbols(module) | ||
| 50 | |||
| 51 | # restore pagination state | ||
| 52 | gdb.execute("set pagination %s" % ("on" if pagination else "off")) | ||
| 53 | |||
| 54 | return False | ||
| 55 | |||
| 56 | |||
| 57 | class LxSymbols(gdb.Command): | ||
| 58 | """(Re-)load symbols of Linux kernel and currently loaded modules. | ||
| 59 | |||
| 60 | The kernel (vmlinux) is taken from the current working directly. Modules (.ko) | ||
| 61 | are scanned recursively, starting in the same directory. Optionally, the module | ||
| 62 | search path can be extended by a space separated list of paths passed to the | ||
| 63 | lx-symbols command.""" | ||
| 64 | |||
| 65 | module_paths = [] | ||
| 66 | module_files = [] | ||
| 67 | module_files_updated = False | ||
| 68 | loaded_modules = [] | ||
| 69 | breakpoint = None | ||
| 70 | |||
| 71 | def __init__(self): | ||
| 72 | super(LxSymbols, self).__init__("lx-symbols", gdb.COMMAND_FILES, | ||
| 73 | gdb.COMPLETE_FILENAME) | ||
| 74 | |||
| 75 | def _update_module_files(self): | ||
| 76 | self.module_files = [] | ||
| 77 | for path in self.module_paths: | ||
| 78 | gdb.write("scanning for modules in {0}\n".format(path)) | ||
| 79 | for root, dirs, files in os.walk(path): | ||
| 80 | for name in files: | ||
| 81 | if name.endswith(".ko"): | ||
| 82 | self.module_files.append(root + "/" + name) | ||
| 83 | self.module_files_updated = True | ||
| 84 | |||
| 85 | def _get_module_file(self, module_name): | ||
| 86 | module_pattern = ".*/{0}\.ko$".format( | ||
| 87 | module_name.replace("_", r"[_\-]")) | ||
| 88 | for name in self.module_files: | ||
| 89 | if re.match(module_pattern, name) and os.path.exists(name): | ||
| 90 | return name | ||
| 91 | return None | ||
| 92 | |||
| 93 | def _section_arguments(self, module): | ||
| 94 | try: | ||
| 95 | sect_attrs = module['sect_attrs'].dereference() | ||
| 96 | except gdb.error: | ||
| 97 | return "" | ||
| 98 | attrs = sect_attrs['attrs'] | ||
| 99 | section_name_to_address = { | ||
| 100 | attrs[n]['name'].string() : attrs[n]['address'] | ||
| 101 | for n in range(int(sect_attrs['nsections']))} | ||
| 102 | args = [] | ||
| 103 | for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]: | ||
| 104 | address = section_name_to_address.get(section_name) | ||
| 105 | if address: | ||
| 106 | args.append(" -s {name} {addr}".format( | ||
| 107 | name=section_name, addr=str(address))) | ||
| 108 | return "".join(args) | ||
| 109 | |||
| 110 | def load_module_symbols(self, module): | ||
| 111 | module_name = module['name'].string() | ||
| 112 | module_addr = str(module['module_core']).split()[0] | ||
| 113 | |||
| 114 | module_file = self._get_module_file(module_name) | ||
| 115 | if not module_file and not self.module_files_updated: | ||
| 116 | self._update_module_files() | ||
| 117 | module_file = self._get_module_file(module_name) | ||
| 118 | |||
| 119 | if module_file: | ||
| 120 | gdb.write("loading @{addr}: {filename}\n".format( | ||
| 121 | addr=module_addr, filename=module_file)) | ||
| 122 | cmdline = "add-symbol-file {filename} {addr}{sections}".format( | ||
| 123 | filename=module_file, | ||
| 124 | addr=module_addr, | ||
| 125 | sections=self._section_arguments(module)) | ||
| 126 | gdb.execute(cmdline, to_string=True) | ||
| 127 | if not module_name in self.loaded_modules: | ||
| 128 | self.loaded_modules.append(module_name) | ||
| 129 | else: | ||
| 130 | gdb.write("no module object found for '{0}'\n".format(module_name)) | ||
| 131 | |||
| 132 | def load_all_symbols(self): | ||
| 133 | gdb.write("loading vmlinux\n") | ||
| 134 | |||
| 135 | # Dropping symbols will disable all breakpoints. So save their states | ||
| 136 | # and restore them afterward. | ||
| 137 | saved_states = [] | ||
| 138 | if hasattr(gdb, 'breakpoints') and not gdb.breakpoints() is None: | ||
| 139 | for bp in gdb.breakpoints(): | ||
| 140 | saved_states.append({'breakpoint': bp, 'enabled': bp.enabled}) | ||
| 141 | |||
| 142 | # drop all current symbols and reload vmlinux | ||
| 143 | gdb.execute("symbol-file", to_string=True) | ||
| 144 | gdb.execute("symbol-file vmlinux") | ||
| 145 | |||
| 146 | self.loaded_modules = [] | ||
| 147 | module_list = modules.module_list() | ||
| 148 | if not module_list: | ||
| 149 | gdb.write("no modules found\n") | ||
| 150 | else: | ||
| 151 | [self.load_module_symbols(module) for module in module_list] | ||
| 152 | |||
| 153 | for saved_state in saved_states: | ||
| 154 | saved_state['breakpoint'].enabled = saved_state['enabled'] | ||
| 155 | |||
| 156 | def invoke(self, arg, from_tty): | ||
| 157 | self.module_paths = arg.split() | ||
| 158 | self.module_paths.append(os.getcwd()) | ||
| 159 | |||
| 160 | # enforce update | ||
| 161 | self.module_files = [] | ||
| 162 | self.module_files_updated = False | ||
| 163 | |||
| 164 | self.load_all_symbols() | ||
| 165 | |||
| 166 | if hasattr(gdb, 'Breakpoint'): | ||
| 167 | if not self.breakpoint is None: | ||
| 168 | self.breakpoint.delete() | ||
| 169 | self.breakpoint = None | ||
| 170 | self.breakpoint = LoadModuleBreakpoint( | ||
| 171 | "kernel/module.c:do_init_module", self) | ||
| 172 | else: | ||
| 173 | gdb.write("Note: symbol update on module loading not supported " | ||
| 174 | "with this gdb version\n") | ||
| 175 | |||
| 176 | |||
| 177 | LxSymbols() | ||
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py new file mode 100644 index 000000000000..e2037d9bb7eb --- /dev/null +++ b/scripts/gdb/linux/tasks.py | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | # | ||
| 2 | # gdb helper commands and functions for Linux kernel debugging | ||
| 3 | # | ||
| 4 | # task & thread tools | ||
| 5 | # | ||
| 6 | # Copyright (c) Siemens AG, 2011-2013 | ||
| 7 | # | ||
| 8 | # Authors: | ||
| 9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
| 10 | # | ||
| 11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
| 12 | # | ||
| 13 | |||
| 14 | import gdb | ||
| 15 | |||
| 16 | from linux import utils | ||
| 17 | |||
| 18 | |||
| 19 | task_type = utils.CachedType("struct task_struct") | ||
| 20 | |||
| 21 | def task_lists(): | ||
| 22 | global task_type | ||
| 23 | task_ptr_type = task_type.get_type().pointer() | ||
| 24 | init_task = gdb.parse_and_eval("init_task").address | ||
| 25 | t = g = init_task | ||
| 26 | |||
| 27 | while True: | ||
| 28 | while True: | ||
| 29 | yield t | ||
| 30 | |||
| 31 | t = utils.container_of(t['thread_group']['next'], | ||
| 32 | task_ptr_type, "thread_group") | ||
| 33 | if t == g: | ||
| 34 | break | ||
| 35 | |||
| 36 | t = g = utils.container_of(g['tasks']['next'], | ||
| 37 | task_ptr_type, "tasks") | ||
| 38 | if t == init_task: | ||
| 39 | return | ||
| 40 | |||
| 41 | def get_task_by_pid(pid): | ||
| 42 | for task in task_lists(): | ||
| 43 | if int(task['pid']) == pid: | ||
| 44 | return task | ||
| 45 | return None | ||
| 46 | |||
| 47 | |||
| 48 | class LxTaskByPidFunc(gdb.Function): | ||
| 49 | """Find Linux task by PID and return the task_struct variable. | ||
| 50 | |||
| 51 | $lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and | ||
| 52 | return that task_struct variable which PID matches.""" | ||
| 53 | |||
| 54 | def __init__(self): | ||
| 55 | super(LxTaskByPidFunc, self).__init__("lx_task_by_pid") | ||
| 56 | |||
| 57 | def invoke(self, pid): | ||
| 58 | task = get_task_by_pid(pid) | ||
| 59 | if task: | ||
| 60 | return task.dereference() | ||
| 61 | else: | ||
| 62 | raise gdb.GdbError("No task of PID " + str(pid)) | ||
| 63 | |||
| 64 | |||
| 65 | LxTaskByPidFunc() | ||
| 66 | |||
| 67 | |||
| 68 | thread_info_type = utils.CachedType("struct thread_info") | ||
| 69 | |||
| 70 | ia64_task_size = None | ||
| 71 | |||
| 72 | |||
| 73 | def get_thread_info(task): | ||
| 74 | global thread_info_type | ||
| 75 | thread_info_ptr_type = thread_info_type.get_type().pointer() | ||
| 76 | if utils.is_target_arch("ia64"): | ||
| 77 | global ia64_task_size | ||
| 78 | if ia64_task_size is None: | ||
| 79 | ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)") | ||
| 80 | thread_info_addr = task.address + ia64_task_size | ||
| 81 | thread_info = thread_info_addr.cast(thread_info_ptr_type) | ||
| 82 | else: | ||
| 83 | thread_info = task['stack'].cast(thread_info_ptr_type) | ||
| 84 | return thread_info.dereference() | ||
| 85 | |||
| 86 | |||
| 87 | class LxThreadInfoFunc (gdb.Function): | ||
| 88 | """Calculate Linux thread_info from task variable. | ||
| 89 | |||
| 90 | $lx_thread_info(TASK): Given TASK, return the corresponding thread_info | ||
| 91 | variable.""" | ||
| 92 | |||
| 93 | def __init__(self): | ||
| 94 | super(LxThreadInfoFunc, self).__init__("lx_thread_info") | ||
| 95 | |||
| 96 | def invoke(self, task): | ||
| 97 | return get_thread_info(task) | ||
| 98 | |||
| 99 | |||
| 100 | LxThreadInfoFunc() | ||
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py new file mode 100644 index 000000000000..128c306db3ee --- /dev/null +++ b/scripts/gdb/linux/utils.py | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | # | ||
| 2 | # gdb helper commands and functions for Linux kernel debugging | ||
| 3 | # | ||
| 4 | # common utilities | ||
| 5 | # | ||
| 6 | # Copyright (c) Siemens AG, 2011-2013 | ||
| 7 | # | ||
| 8 | # Authors: | ||
| 9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
| 10 | # | ||
| 11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
| 12 | # | ||
| 13 | |||
| 14 | import gdb | ||
| 15 | |||
| 16 | |||
| 17 | class CachedType: | ||
| 18 | def __init__(self, name): | ||
| 19 | self._type = None | ||
| 20 | self._name = name | ||
| 21 | |||
| 22 | def _new_objfile_handler(self, event): | ||
| 23 | self._type = None | ||
| 24 | gdb.events.new_objfile.disconnect(self._new_objfile_handler) | ||
| 25 | |||
| 26 | def get_type(self): | ||
| 27 | if self._type is None: | ||
| 28 | self._type = gdb.lookup_type(self._name) | ||
| 29 | if self._type is None: | ||
| 30 | raise gdb.GdbError( | ||
| 31 | "cannot resolve type '{0}'".format(self._name)) | ||
| 32 | if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'): | ||
| 33 | gdb.events.new_objfile.connect(self._new_objfile_handler) | ||
| 34 | return self._type | ||
| 35 | |||
| 36 | |||
| 37 | long_type = CachedType("long") | ||
| 38 | |||
| 39 | |||
| 40 | def get_long_type(): | ||
| 41 | global long_type | ||
| 42 | return long_type.get_type() | ||
| 43 | |||
| 44 | |||
| 45 | def offset_of(typeobj, field): | ||
| 46 | element = gdb.Value(0).cast(typeobj) | ||
| 47 | return int(str(element[field].address).split()[0], 16) | ||
| 48 | |||
| 49 | |||
| 50 | def container_of(ptr, typeobj, member): | ||
| 51 | return (ptr.cast(get_long_type()) - | ||
| 52 | offset_of(typeobj, member)).cast(typeobj) | ||
| 53 | |||
| 54 | |||
| 55 | class ContainerOf(gdb.Function): | ||
| 56 | """Return pointer to containing data structure. | ||
| 57 | |||
| 58 | $container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the | ||
| 59 | data structure of the type TYPE in which PTR is the address of ELEMENT. | ||
| 60 | Note that TYPE and ELEMENT have to be quoted as strings.""" | ||
| 61 | |||
| 62 | def __init__(self): | ||
| 63 | super(ContainerOf, self).__init__("container_of") | ||
| 64 | |||
| 65 | def invoke(self, ptr, typename, elementname): | ||
| 66 | return container_of(ptr, gdb.lookup_type(typename.string()).pointer(), | ||
| 67 | elementname.string()) | ||
| 68 | |||
| 69 | ContainerOf() | ||
| 70 | |||
| 71 | |||
| 72 | BIG_ENDIAN = 0 | ||
| 73 | LITTLE_ENDIAN = 1 | ||
| 74 | target_endianness = None | ||
| 75 | |||
| 76 | |||
| 77 | def get_target_endianness(): | ||
| 78 | global target_endianness | ||
| 79 | if target_endianness is None: | ||
| 80 | endian = gdb.execute("show endian", to_string=True) | ||
| 81 | if "little endian" in endian: | ||
| 82 | target_endianness = LITTLE_ENDIAN | ||
| 83 | elif "big endian" in endian: | ||
| 84 | target_endianness = BIG_ENDIAN | ||
| 85 | else: | ||
| 86 | raise gdb.GdgError("unknown endianness '{0}'".format(str(endian))) | ||
| 87 | return target_endianness | ||
| 88 | |||
| 89 | |||
| 90 | def read_u16(buffer): | ||
| 91 | if get_target_endianness() == LITTLE_ENDIAN: | ||
| 92 | return ord(buffer[0]) + (ord(buffer[1]) << 8) | ||
| 93 | else: | ||
| 94 | return ord(buffer[1]) + (ord(buffer[0]) << 8) | ||
| 95 | |||
| 96 | |||
| 97 | def read_u32(buffer): | ||
| 98 | if get_target_endianness() == LITTLE_ENDIAN: | ||
| 99 | return read_u16(buffer[0:2]) + (read_u16(buffer[2:4]) << 16) | ||
| 100 | else: | ||
| 101 | return read_u16(buffer[2:4]) + (read_u16(buffer[0:2]) << 16) | ||
| 102 | |||
| 103 | |||
| 104 | def read_u64(buffer): | ||
| 105 | if get_target_endianness() == LITTLE_ENDIAN: | ||
| 106 | return read_u32(buffer[0:4]) + (read_u32(buffer[4:8]) << 32) | ||
| 107 | else: | ||
| 108 | return read_u32(buffer[4:8]) + (read_u32(buffer[0:4]) << 32) | ||
| 109 | |||
| 110 | |||
| 111 | target_arch = None | ||
| 112 | |||
| 113 | |||
| 114 | def is_target_arch(arch): | ||
| 115 | if hasattr(gdb.Frame, 'architecture'): | ||
| 116 | return arch in gdb.newest_frame().architecture().name() | ||
| 117 | else: | ||
| 118 | global target_arch | ||
| 119 | if target_arch is None: | ||
| 120 | target_arch = gdb.execute("show architecture", to_string=True) | ||
| 121 | return arch in target_arch | ||
| 122 | |||
| 123 | |||
| 124 | GDBSERVER_QEMU = 0 | ||
| 125 | GDBSERVER_KGDB = 1 | ||
| 126 | gdbserver_type = None | ||
| 127 | |||
| 128 | |||
| 129 | def get_gdbserver_type(): | ||
| 130 | def exit_handler(event): | ||
| 131 | global gdbserver_type | ||
| 132 | gdbserver_type = None | ||
| 133 | gdb.events.exited.disconnect(exit_handler) | ||
| 134 | |||
| 135 | def probe_qemu(): | ||
| 136 | try: | ||
| 137 | return gdb.execute("monitor info version", to_string=True) != "" | ||
| 138 | except: | ||
| 139 | return False | ||
| 140 | |||
| 141 | def probe_kgdb(): | ||
| 142 | try: | ||
| 143 | thread_info = gdb.execute("info thread 2", to_string=True) | ||
| 144 | return "shadowCPU0" in thread_info | ||
| 145 | except: | ||
| 146 | return False | ||
| 147 | |||
| 148 | global gdbserver_type | ||
| 149 | if gdbserver_type is None: | ||
| 150 | if probe_qemu(): | ||
| 151 | gdbserver_type = GDBSERVER_QEMU | ||
| 152 | elif probe_kgdb(): | ||
| 153 | gdbserver_type = GDBSERVER_KGDB | ||
| 154 | if not gdbserver_type is None and hasattr(gdb, 'events'): | ||
| 155 | gdb.events.exited.connect(exit_handler) | ||
| 156 | return gdbserver_type | ||
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py new file mode 100644 index 000000000000..48489285f119 --- /dev/null +++ b/scripts/gdb/vmlinux-gdb.py | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | # | ||
| 2 | # gdb helper commands and functions for Linux kernel debugging | ||
| 3 | # | ||
| 4 | # loader module | ||
| 5 | # | ||
| 6 | # Copyright (c) Siemens AG, 2012, 2013 | ||
| 7 | # | ||
| 8 | # Authors: | ||
| 9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
| 10 | # | ||
| 11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
| 12 | # | ||
| 13 | |||
| 14 | import os | ||
| 15 | |||
| 16 | sys.path.insert(0, os.path.dirname(__file__) + "/scripts/gdb") | ||
| 17 | |||
| 18 | try: | ||
| 19 | gdb.parse_and_eval("0") | ||
| 20 | gdb.execute("", to_string=True) | ||
| 21 | except: | ||
| 22 | gdb.write("NOTE: gdb 7.2 or later required for Linux helper scripts to " | ||
| 23 | "work.\n") | ||
| 24 | else: | ||
| 25 | import linux.utils | ||
| 26 | import linux.symbols | ||
| 27 | import linux.modules | ||
| 28 | import linux.dmesg | ||
| 29 | import linux.tasks | ||
| 30 | import linux.cpus | ||
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index f88d90f20228..28df18dd1147 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
| @@ -59,6 +59,7 @@ static void conf_message(const char *fmt, ...) | |||
| 59 | va_start(ap, fmt); | 59 | va_start(ap, fmt); |
| 60 | if (conf_message_callback) | 60 | if (conf_message_callback) |
| 61 | conf_message_callback(fmt, ap); | 61 | conf_message_callback(fmt, ap); |
| 62 | va_end(ap); | ||
| 62 | } | 63 | } |
| 63 | 64 | ||
| 64 | const char *conf_get_configname(void) | 65 | const char *conf_get_configname(void) |
diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 81b0c61bb9e2..2ab91b9b100d 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh | |||
| @@ -77,6 +77,11 @@ while true; do | |||
| 77 | esac | 77 | esac |
| 78 | done | 78 | done |
| 79 | 79 | ||
| 80 | if [ "$#" -lt 2 ] ; then | ||
| 81 | usage | ||
| 82 | exit | ||
| 83 | fi | ||
| 84 | |||
| 80 | INITFILE=$1 | 85 | INITFILE=$1 |
| 81 | shift; | 86 | shift; |
| 82 | 87 | ||
diff --git a/scripts/module-common.lds b/scripts/module-common.lds index 0865b3e752be..73a2c7da0e55 100644 --- a/scripts/module-common.lds +++ b/scripts/module-common.lds | |||
| @@ -6,14 +6,17 @@ | |||
| 6 | SECTIONS { | 6 | SECTIONS { |
| 7 | /DISCARD/ : { *(.discard) } | 7 | /DISCARD/ : { *(.discard) } |
| 8 | 8 | ||
| 9 | __ksymtab : { *(SORT(___ksymtab+*)) } | 9 | __ksymtab 0 : { *(SORT(___ksymtab+*)) } |
| 10 | __ksymtab_gpl : { *(SORT(___ksymtab_gpl+*)) } | 10 | __ksymtab_gpl 0 : { *(SORT(___ksymtab_gpl+*)) } |
| 11 | __ksymtab_unused : { *(SORT(___ksymtab_unused+*)) } | 11 | __ksymtab_unused 0 : { *(SORT(___ksymtab_unused+*)) } |
| 12 | __ksymtab_unused_gpl : { *(SORT(___ksymtab_unused_gpl+*)) } | 12 | __ksymtab_unused_gpl 0 : { *(SORT(___ksymtab_unused_gpl+*)) } |
| 13 | __ksymtab_gpl_future : { *(SORT(___ksymtab_gpl_future+*)) } | 13 | __ksymtab_gpl_future 0 : { *(SORT(___ksymtab_gpl_future+*)) } |
| 14 | __kcrctab : { *(SORT(___kcrctab+*)) } | 14 | __kcrctab 0 : { *(SORT(___kcrctab+*)) } |
| 15 | __kcrctab_gpl : { *(SORT(___kcrctab_gpl+*)) } | 15 | __kcrctab_gpl 0 : { *(SORT(___kcrctab_gpl+*)) } |
| 16 | __kcrctab_unused : { *(SORT(___kcrctab_unused+*)) } | 16 | __kcrctab_unused 0 : { *(SORT(___kcrctab_unused+*)) } |
| 17 | __kcrctab_unused_gpl : { *(SORT(___kcrctab_unused_gpl+*)) } | 17 | __kcrctab_unused_gpl 0 : { *(SORT(___kcrctab_unused_gpl+*)) } |
| 18 | __kcrctab_gpl_future : { *(SORT(___kcrctab_gpl_future+*)) } | 18 | __kcrctab_gpl_future 0 : { *(SORT(___kcrctab_gpl_future+*)) } |
| 19 | |||
| 20 | . = ALIGN(8); | ||
| 21 | .init_array 0 : { *(SORT(.init_array.*)) *(.init_array) } | ||
| 19 | } | 22 | } |
diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 59726243c2eb..88dbf23b6970 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb | |||
| @@ -217,9 +217,20 @@ else | |||
| 217 | fi | 217 | fi |
| 218 | maintainer="$name <$email>" | 218 | maintainer="$name <$email>" |
| 219 | 219 | ||
| 220 | # Try to determine distribution | ||
| 221 | if [ -n "$KDEB_CHANGELOG_DIST" ]; then | ||
| 222 | distribution=$KDEB_CHANGELOG_DIST | ||
| 223 | elif distribution=$(lsb_release -cs 2>/dev/null) && [ -n "$distribution" ]; then | ||
| 224 | : # nothing to do in this case | ||
| 225 | else | ||
| 226 | distribution="unstable" | ||
| 227 | echo >&2 "Using default distribution of 'unstable' in the changelog" | ||
| 228 | echo >&2 "Install lsb-release or set \$KDEB_CHANGELOG_DIST explicitly" | ||
| 229 | fi | ||
| 230 | |||
| 220 | # Generate a simple changelog template | 231 | # Generate a simple changelog template |
| 221 | cat <<EOF > debian/changelog | 232 | cat <<EOF > debian/changelog |
| 222 | linux-upstream ($packageversion) unstable; urgency=low | 233 | linux-upstream ($packageversion) $distribution; urgency=low |
| 223 | 234 | ||
| 224 | * Custom built Linux kernel. | 235 | * Custom built Linux kernel. |
| 225 | 236 | ||
| @@ -233,10 +244,10 @@ This is a packacked upstream version of the Linux kernel. | |||
| 233 | The sources may be found at most Linux ftp sites, including: | 244 | The sources may be found at most Linux ftp sites, including: |
| 234 | ftp://ftp.kernel.org/pub/linux/kernel | 245 | ftp://ftp.kernel.org/pub/linux/kernel |
| 235 | 246 | ||
| 236 | Copyright: 1991 - 2009 Linus Torvalds and others. | 247 | Copyright: 1991 - 2015 Linus Torvalds and others. |
| 237 | 248 | ||
| 238 | The git repository for mainline kernel development is at: | 249 | The git repository for mainline kernel development is at: |
| 239 | git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git | 250 | git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git |
| 240 | 251 | ||
| 241 | This program is free software; you can redistribute it and/or modify | 252 | This program is free software; you can redistribute it and/or modify |
| 242 | it under the terms of the GNU General Public License as published by | 253 | it under the terms of the GNU General Public License as published by |
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 537c38ca2e1c..826470d7f000 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl | |||
| @@ -242,8 +242,13 @@ if ($arch eq "x86_64") { | |||
| 242 | $cc .= " -m32"; | 242 | $cc .= " -m32"; |
| 243 | 243 | ||
| 244 | } elsif ($arch eq "s390" && $bits == 64) { | 244 | } elsif ($arch eq "s390" && $bits == 64) { |
| 245 | $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$"; | 245 | if ($cc =~ /-DCC_USING_HOTPATCH/) { |
| 246 | $mcount_adjust = -14; | 246 | $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*brcl\\s*0,[0-9a-f]+ <([^\+]*)>\$"; |
| 247 | $mcount_adjust = 0; | ||
| 248 | } else { | ||
| 249 | $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$"; | ||
| 250 | $mcount_adjust = -14; | ||
| 251 | } | ||
| 247 | $alignment = 8; | 252 | $alignment = 8; |
| 248 | $type = ".quad"; | 253 | $type = ".quad"; |
| 249 | $ld .= " -m elf64_s390"; | 254 | $ld .= " -m elf64_s390"; |
