From f24b8df61ccf8621c40bac2576489794ec1f22af Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Fri, 10 Mar 2023 14:52:49 +0800 Subject: [PATCH] Update to the latest commit <489093c2183f> Release: crash-8.0.2-4 Signed-off-by: Lianbo Jiang --- ...nd-printing-bogus-exception-frame-wa.patch | 80 ++ ...-working-properly-on-RHEL8.6-and-lat.patch | 143 +++ ...tion-to-show-IPv6-addresses-on-Linux.patch | 106 ++ ...ption-to-not-print-invalid-values-fo.patch | 56 + ...nd-unnecessarily-printing-an-excepti.patch | 77 ++ ...and-to-correctly-display-the-offset-.patch | 62 + ...mmand-on-kernels-with-random_kstack_.patch | 299 +++++ ...-option-failing-in-maple-tree-kernel.patch | 168 +++ ...and-to-display-IPv6-address-of-netwo.patch | 258 ++++ ...ility-issues-in-embedded-copy-of-GDB.patch | 1071 +++++++++++++++++ ...tion-to-properly-deal-with-an-invali.patch | 44 + ...tion-failure-in-dw2_find_pc_sect_com.patch | 71 ++ ...n-to-display-memory-blocks-on-Linux-.patch | 159 +++ crash.spec | 52 +- 14 files changed, 2638 insertions(+), 8 deletions(-) create mode 100644 0029-Fix-for-bt-command-printing-bogus-exception-frame-wa.patch create mode 100644 0030-Fix-kmem-s-S-not-working-properly-on-RHEL8.6-and-lat.patch create mode 100644 0031-Fix-for-net-s-option-to-show-IPv6-addresses-on-Linux.patch create mode 100644 0032-Fix-for-kmem-i-option-to-not-print-invalid-values-fo.patch create mode 100644 0033-Fix-for-bt-command-unnecessarily-printing-an-excepti.patch create mode 100644 0034-Fix-for-dis-command-to-correctly-display-the-offset-.patch create mode 100644 0035-x86_64-Fix-bt-command-on-kernels-with-random_kstack_.patch create mode 100644 0036-Fix-for-search-u-option-failing-in-maple-tree-kernel.patch create mode 100644 0037-Enhance-net-command-to-display-IPv6-address-of-netwo.patch create mode 100644 0038-Fix-C99-compatibility-issues-in-embedded-copy-of-GDB.patch create mode 100644 0039-Fix-for-net-n-option-to-properly-deal-with-an-invali.patch create mode 100644 0040-gdb-Fix-an-assertion-failure-in-dw2_find_pc_sect_com.patch create mode 100644 0041-Fix-kmem-n-option-to-display-memory-blocks-on-Linux-.patch diff --git a/0029-Fix-for-bt-command-printing-bogus-exception-frame-wa.patch b/0029-Fix-for-bt-command-printing-bogus-exception-frame-wa.patch new file mode 100644 index 0000000..ac943fd --- /dev/null +++ b/0029-Fix-for-bt-command-printing-bogus-exception-frame-wa.patch @@ -0,0 +1,80 @@ +From 92de7c34b1f910abff4d77522f74454ea0263a90 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Mon, 13 Feb 2023 11:12:12 +0800 +Subject: [PATCH 01/12] Fix for "bt" command printing "bogus exception frame" + warning + +Currently, the "bt" command may print a bogus exception frame +and the remaining frame will be truncated on x86_64 when using the +"virsh send-key KEY_LEFTALT KEY_SYSRQ KEY_C" command +to trigger a panic from the KVM host. For example: + + crash> bt + PID: 0 TASK: ffff9e7a47e32f00 CPU: 3 COMMAND: "swapper/3" + #0 [ffffba7900118bb8] machine_kexec at ffffffff87e5c2c7 + #1 [ffffba7900118c08] __crash_kexec at ffffffff87f9500d + #2 [ffffba7900118cd0] panic at ffffffff87edfff9 + #3 [ffffba7900118d50] sysrq_handle_crash at ffffffff883ce2c1 + ... + #16 [ffffba7900118fd8] handle_edge_irq at ffffffff87f559f2 + #17 [ffffba7900118ff0] asm_call_on_stack at ffffffff88800fa2 + --- --- + #18 [ffffba790008bda0] asm_call_on_stack at ffffffff88800fa2 + RIP: ffffffffffffffff RSP: 0000000000000124 RFLAGS: 00000003 + RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000 + RDX: ffffffff88800c1e RSI: 0000000000000000 RDI: 0000000000000000 + RBP: 0000000000000001 R8: 0000000000000000 R9: 0000000000000000 + R10: 0000000000000000 R11: ffffffff88760555 R12: ffffba790008be08 + R13: ffffffff87f18002 R14: ffff9e7a47e32f00 R15: ffff9e7bb6198e00 + ORIG_RAX: 0000000000000000 CS: 0003 SS: 0000 + bt: WARNING: possibly bogus exception frame + crash> + +The following related kernel commits cause the current issue, crash +needs to adjust the value of irq_eframe_link. + +Related kernel commits: +[1] v5.8: 931b94145981 ("x86/entry: Provide helpers for executing on the irqstack") +[2] v5.8: fa5e5c409213 ("x86/entry: Use idtentry for interrupts") +[3] v5.12: 52d743f3b712 ("x86/softirq: Remove indirection in do_softirq_own_stack()") + +Signed-off-by: Lianbo Jiang +Signed-off-by: Kazuhito Hagio +--- + x86_64.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/x86_64.c b/x86_64.c +index 7a5d6f050c89..5b671bd97775 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -3938,6 +3938,11 @@ in_exception_stack: + if (irq_eframe) { + bt->flags |= BT_EXCEPTION_FRAME; + i = (irq_eframe - bt->stackbase)/sizeof(ulong); ++ if (symbol_exists("asm_common_interrupt")) { ++ i -= 1; ++ up = (ulong *)(&bt->stackbuf[i*sizeof(ulong)]); ++ bt->instptr = *up; ++ } + x86_64_print_stack_entry(bt, ofp, level, i, bt->instptr); + bt->flags &= ~(ulonglong)BT_EXCEPTION_FRAME; + cs = x86_64_exception_frame(EFRAME_PRINT|EFRAME_CS, 0, +@@ -6521,6 +6526,14 @@ x86_64_irq_eframe_link_init(void) + else + return; + ++ if (symbol_exists("asm_common_interrupt")) { ++ if (symbol_exists("asm_call_on_stack")) ++ machdep->machspec->irq_eframe_link = -64; ++ else ++ machdep->machspec->irq_eframe_link = -32; ++ return; ++ } ++ + if (THIS_KERNEL_VERSION < LINUX(2,6,9)) + return; + +-- +2.37.1 + diff --git a/0030-Fix-kmem-s-S-not-working-properly-on-RHEL8.6-and-lat.patch b/0030-Fix-kmem-s-S-not-working-properly-on-RHEL8.6-and-lat.patch new file mode 100644 index 0000000..e23607d --- /dev/null +++ b/0030-Fix-kmem-s-S-not-working-properly-on-RHEL8.6-and-lat.patch @@ -0,0 +1,143 @@ +From 9253b40a0ecb2d365f89f0a5ebc28a01735c1d24 Mon Sep 17 00:00:00 2001 +From: "Aureau, Georges (Kernel Tools ERT)" +Date: Wed, 8 Feb 2023 12:09:03 +0000 +Subject: [PATCH 02/12] Fix "kmem -s|-S" not working properly on RHEL8.6 and + later + +For CONFIG_SLAB_FREELIST_HARDENED, the crash memory.c:freelist_ptr() +code is checking for an additional bswap using a simple release test eg. +THIS_KERNEL_VERSION >= LINUX(5,7,0), basically checking for RHEL9 and +beyond. + +However, for RHEL8.6 and later, we have CONFIG_SLAB_FREELIST_HARDENED=y, +and we also have the additional bswap, but the current crash is not +handling this case, hence "kmem -s|-S" will not work properly, and free +objects will not be counted nor reported properly. + +An example from a RHEL8.6 x86_64 kdump, a kmem cache with a single slab +having 42 objects, only the freelist head is seen as free as crash can't +walk freelist next pointers, and crash is wrongly reporting 41 allocated +objects: + + crash> sys | grep RELEASE + RELEASE: 4.18.0-372.9.1.el8.x86_64 + crash> kmem -s nfs_commit_data + CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME + ffff9ad40c7cb2c0 728 41 42 1 32k nfs_commit_data + +When properly accounting for the additional bswap, we can walk the +freelist and find 38 free objects, and crash is now reporting only 4 +allocated objects: + + crash> kmem -s nfs_commit_data + CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME + ffff9ad40c7cb2c0 728 4 42 1 32k nfs_commit_data + +Signed-off-by: Georges Aureau +--- + defs.h | 1 + + memory.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 49 insertions(+), 1 deletion(-) + +diff --git a/defs.h b/defs.h +index 33a823b7b67c..56d6cf4489c9 100644 +--- a/defs.h ++++ b/defs.h +@@ -2638,6 +2638,7 @@ struct vm_table { /* kernel VM-related data */ + #define SLAB_OVERLOAD_PAGE (0x8000000) + #define SLAB_CPU_CACHE (0x10000000) + #define SLAB_ROOT_CACHES (0x20000000) ++#define FREELIST_PTR_BSWAP (0x40000000) + + #define IS_FLATMEM() (vt->flags & FLATMEM) + #define IS_DISCONTIGMEM() (vt->flags & DISCONTIGMEM) +diff --git a/memory.c b/memory.c +index 5141fbea4b40..e0742c1bd3a4 100644 +--- a/memory.c ++++ b/memory.c +@@ -320,6 +320,7 @@ static void dump_per_cpu_offsets(void); + static void dump_page_flags(ulonglong); + static ulong kmem_cache_nodelists(ulong); + static void dump_hstates(void); ++static void freelist_ptr_init(void); + static ulong freelist_ptr(struct meminfo *, ulong, ulong); + static ulong handle_each_vm_area(struct handle_each_vm_area_args *); + +@@ -789,6 +790,8 @@ vm_init(void) + MEMBER_OFFSET_INIT(kmem_cache_name, "kmem_cache", "name"); + MEMBER_OFFSET_INIT(kmem_cache_flags, "kmem_cache", "flags"); + MEMBER_OFFSET_INIT(kmem_cache_random, "kmem_cache", "random"); ++ if (VALID_MEMBER(kmem_cache_random)) ++ freelist_ptr_init(); + MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist, "kmem_cache_cpu", "freelist"); + MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu", "page"); + if (INVALID_MEMBER(kmem_cache_cpu_page)) +@@ -13932,6 +13935,8 @@ dump_vm_table(int verbose) + fprintf(fp, "%sSLAB_CPU_CACHE", others++ ? "|" : "");\ + if (vt->flags & SLAB_ROOT_CACHES) + fprintf(fp, "%sSLAB_ROOT_CACHES", others++ ? "|" : "");\ ++ if (vt->flags & FREELIST_PTR_BSWAP) ++ fprintf(fp, "%sFREELIST_PTR_BSWAP", others++ ? "|" : "");\ + if (vt->flags & USE_VMAP_AREA) + fprintf(fp, "%sUSE_VMAP_AREA", others++ ? "|" : "");\ + if (vt->flags & CONFIG_NUMA) +@@ -19519,13 +19524,55 @@ count_free_objects(struct meminfo *si, ulong freelist) + return c; + } + ++/* ++ * With CONFIG_SLAB_FREELIST_HARDENED, freelist_ptr's are crypted with xor's, ++ * and for recent release with an additionnal bswap. Some releases prio to 5.7.0 ++ * may be using the additionnal bswap. The only easy and reliable way to tell is ++ * to inspect assembly code (eg. "__slab_free") for a bswap instruction. ++ */ ++static int ++freelist_ptr_bswap_x86(void) ++{ ++ char buf1[BUFSIZE]; ++ char buf2[BUFSIZE]; ++ char *arglist[MAXARGS]; ++ int found; ++ ++ sprintf(buf1, "disassemble __slab_free"); ++ open_tmpfile(); ++ if (!gdb_pass_through(buf1, pc->tmpfile, GNU_RETURN_ON_ERROR)) { ++ close_tmpfile(); ++ return FALSE; ++ } ++ rewind(pc->tmpfile); ++ found = FALSE; ++ while (fgets(buf2, BUFSIZE, pc->tmpfile)) { ++ if (parse_line(buf2, arglist) < 3) ++ continue; ++ if (STREQ(arglist[2], "bswap")) { ++ found = TRUE; ++ break; ++ } ++ } ++ close_tmpfile(); ++ return found; ++} ++ ++static void ++freelist_ptr_init(void) ++{ ++ if (THIS_KERNEL_VERSION >= LINUX(5,7,0) || ++ ((machine_type("X86_64") || machine_type("X86")) && freelist_ptr_bswap_x86())) ++ vt->flags |= FREELIST_PTR_BSWAP; ++} ++ + static ulong + freelist_ptr(struct meminfo *si, ulong ptr, ulong ptr_addr) + { + if (VALID_MEMBER(kmem_cache_random)) { + /* CONFIG_SLAB_FREELIST_HARDENED */ + +- if (THIS_KERNEL_VERSION >= LINUX(5,7,0)) ++ if (vt->flags & FREELIST_PTR_BSWAP) + ptr_addr = (sizeof(long) == 8) ? bswap_64(ptr_addr) + : bswap_32(ptr_addr); + return (ptr ^ si->random ^ ptr_addr); +-- +2.37.1 + diff --git a/0031-Fix-for-net-s-option-to-show-IPv6-addresses-on-Linux.patch b/0031-Fix-for-net-s-option-to-show-IPv6-addresses-on-Linux.patch new file mode 100644 index 0000000..9042371 --- /dev/null +++ b/0031-Fix-for-net-s-option-to-show-IPv6-addresses-on-Linux.patch @@ -0,0 +1,106 @@ +From c64a827e0bcab15e86f8fbacec141c2bf4b776ea Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Thu, 9 Feb 2023 20:15:46 +0800 +Subject: [PATCH 03/12] Fix for "net -s" option to show IPv6 addresses on Linux + 3.13 and later + +Currently, the "net -s" option fails to show IPv6 addresses and ports +for the SOURCE-PORT and DESTINATION-PORT columns on Linux 3.13 and later +kernels, which have kernel commit efe4208f47f907 ("ipv6: make lookups +simpler and faster"). For example: + + crash> net -s + PID: 305524 TASK: ffff9bc449895580 CPU: 6 COMMAND: "sshd" + FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT + 3 ffff9bc446e9a680 ffff9bc4455b5940 UNIX:DGRAM + 4 ffff9bc446e9c600 ffff9bc3b2b24e00 INET6:STREAM + +With the patch: + + crash> net -s + PID: 305524 TASK: ffff9bc449895580 CPU: 6 COMMAND: "sshd" + FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT + 3 ffff9bc446e9a680 ffff9bc4455b5940 UNIX:DGRAM + 4 ffff9bc446e9c600 ffff9bc3b2b24e00 INET6:STREAM xxxx:xx:x:xxxx:xxxx:xxxx:xxxx:xxxx-22 yyyy:yy:y:yyyy:yyyy:yyyy:yyyy:yyyy-44870 + +Reported-by: Buland Kumar Singh +Signed-off-by: Lianbo Jiang +Signed-off-by: Kazuhito Hagio +--- + defs.h | 3 +++ + net.c | 20 +++++++++++++++----- + symbols.c | 3 +++ + 3 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/defs.h b/defs.h +index 56d6cf4489c9..ab4f02cc65cf 100644 +--- a/defs.h ++++ b/defs.h +@@ -2204,6 +2204,9 @@ struct offset_table { /* stash of commonly-used offsets */ + long maple_range_64_slot; + long maple_metadata_end; + long maple_metadata_gap; ++ long sock_sk_common; ++ long sock_common_skc_v6_daddr; ++ long sock_common_skc_v6_rcv_saddr; + }; + + struct size_table { /* stash of commonly-used sizes */ +diff --git a/net.c b/net.c +index 7c9c8bd9c98d..aa445ab7ee13 100644 +--- a/net.c ++++ b/net.c +@@ -199,6 +199,9 @@ net_init(void) + MEMBER_OFFSET_INIT(sock_common_skc_family, + "sock_common", "skc_family"); + MEMBER_OFFSET_INIT(sock_sk_type, "sock", "sk_type"); ++ MEMBER_OFFSET_INIT(sock_sk_common, "sock", "__sk_common"); ++ MEMBER_OFFSET_INIT(sock_common_skc_v6_daddr, "sock_common", "skc_v6_daddr"); ++ MEMBER_OFFSET_INIT(sock_common_skc_v6_rcv_saddr, "sock_common", "skc_v6_rcv_saddr"); + /* + * struct inet_sock { + * struct sock sk; +@@ -1104,12 +1107,19 @@ get_sock_info(ulong sock, char *buf) + break; + + case SOCK_V2: +- if (INVALID_MEMBER(ipv6_pinfo_rcv_saddr) || +- INVALID_MEMBER(ipv6_pinfo_daddr)) ++ if (VALID_MEMBER(ipv6_pinfo_rcv_saddr) && ++ VALID_MEMBER(ipv6_pinfo_daddr)) { ++ ipv6_rcv_saddr = ipv6_pinfo + OFFSET(ipv6_pinfo_rcv_saddr); ++ ipv6_daddr = ipv6_pinfo + OFFSET(ipv6_pinfo_daddr); ++ } else if (VALID_MEMBER(sock_sk_common) && ++ VALID_MEMBER(sock_common_skc_v6_daddr) && ++ VALID_MEMBER(sock_common_skc_v6_rcv_saddr)) { ++ ipv6_rcv_saddr = sock + OFFSET(sock_sk_common) + OFFSET(sock_common_skc_v6_rcv_saddr); ++ ipv6_daddr = sock + OFFSET(sock_sk_common) + OFFSET(sock_common_skc_v6_daddr); ++ } else { ++ sprintf(&buf[strlen(buf)], "%s", "(cannot get IPv6 addresses)"); + break; +- +- ipv6_rcv_saddr = ipv6_pinfo + OFFSET(ipv6_pinfo_rcv_saddr); +- ipv6_daddr = ipv6_pinfo + OFFSET(ipv6_pinfo_daddr); ++ } + + if (!readmem(ipv6_rcv_saddr, KVADDR, u6_addr16_src, SIZE(in6_addr), + "ipv6_rcv_saddr buffer", QUIET|RETURN_ON_ERROR)) +diff --git a/symbols.c b/symbols.c +index e38df8aad0f5..b702b9665ec1 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -9818,8 +9818,11 @@ dump_offset_table(char *spec, ulong makestruct) + + fprintf(fp, " sock_sk_type: %ld\n", + OFFSET(sock_sk_type)); ++ fprintf(fp, " sock_sk_common: %ld\n", OFFSET(sock_sk_common)); + fprintf(fp, " sock_common_skc_family: %ld\n", + OFFSET(sock_common_skc_family)); ++ fprintf(fp, " sock_common_skc_v6_daddr: %ld\n", OFFSET(sock_common_skc_v6_daddr)); ++ fprintf(fp, " sock_common_skc_v6_rcv_saddr: %ld\n", OFFSET(sock_common_skc_v6_rcv_saddr)); + fprintf(fp, " socket_alloc_vfs_inode: %ld\n", + OFFSET(socket_alloc_vfs_inode)); + fprintf(fp, " inet_sock_inet: %ld\n", +-- +2.37.1 + diff --git a/0032-Fix-for-kmem-i-option-to-not-print-invalid-values-fo.patch b/0032-Fix-for-kmem-i-option-to-not-print-invalid-values-fo.patch new file mode 100644 index 0000000..2c4eb2d --- /dev/null +++ b/0032-Fix-for-kmem-i-option-to-not-print-invalid-values-fo.patch @@ -0,0 +1,56 @@ +From 277da34dd5da8c1280d0d0fd7ce50499b31c3a58 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Tue, 14 Feb 2023 22:37:08 +0800 +Subject: [PATCH 04/12] Fix for "kmem -i" option to not print invalid values + for CACHED + +The "kmem -i" option may output a bogus statistics for CACHED, which +might be observed when some extreme situations occur in kernel, such as +OOM, disk IO errors, etc. + +The following result of calculation may be a negative value, refer to +the dump_kmeminfo(): + page_cache_size = nr_file_pages - swapper_space_nrpages - buffer_pages; + +As a result, the negative value will be converted to unsigned long +integer, eventually it overflows and is printed as big integers. + + crash> kmem -i + PAGES TOTAL PERCENTAGE + TOTAL MEM 255314511 973.9 GB ---- + FREE 533574 2 GB 0% of TOTAL MEM + USED 254780937 971.9 GB 99% of TOTAL MEM + SHARED 1713 6.7 MB 0% of TOTAL MEM + BUFFERS 374 1.5 MB 0% of TOTAL MEM + CACHED -114 70368744177664 GB 72251060080% of TOTAL MEM + ^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^ + ... + +Let's normalize it to zero with an info message to fix such cornor cases. + +Reported-by: Buland Kumar Singh +Signed-off-by: Lianbo Jiang +Signed-off-by: Kazuhito Hagio +--- + memory.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/memory.c b/memory.c +index e0742c1bd3a4..d9cd616f19de 100644 +--- a/memory.c ++++ b/memory.c +@@ -8615,6 +8615,11 @@ dump_kmeminfo(void) + page_cache_size = 0; + + ++ if (page_cache_size < 0) { ++ error(INFO, "page_cache_size went negative (%ld), setting to 0\n", ++ page_cache_size); ++ page_cache_size = 0; ++ } + pct = (page_cache_size * 100)/totalram_pages; + fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL MEM\n", + "CACHED", page_cache_size, +-- +2.37.1 + diff --git a/0033-Fix-for-bt-command-unnecessarily-printing-an-excepti.patch b/0033-Fix-for-bt-command-unnecessarily-printing-an-excepti.patch new file mode 100644 index 0000000..a946471 --- /dev/null +++ b/0033-Fix-for-bt-command-unnecessarily-printing-an-excepti.patch @@ -0,0 +1,77 @@ +From e0e6e4a7ee03b3d00b50a9e4db2f2ea6f7da0da3 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Wed, 15 Feb 2023 16:24:57 +0800 +Subject: [PATCH 05/12] Fix for "bt" command unnecessarily printing an + exception frame + +Kernel commit 7d65f4a65532 ("irq: Consolidate do_softirq() arch overriden +implementations") renamed the call_softirq to do_softirq_own_stack, and +there is no exception frame also when coming from do_softirq_own_stack. +Without the patch, crash may unnecessarily output an exception frame with +a warning as below: + + crash> foreach bt + ... + PID: 0 TASK: ffff914f820a8000 CPU: 25 COMMAND: "swapper/25" + #0 [fffffe0000504e48] crash_nmi_callback at ffffffffa665d763 + #1 [fffffe0000504e50] nmi_handle at ffffffffa662a423 + #2 [fffffe0000504ea8] default_do_nmi at ffffffffa6fe7dc9 + #3 [fffffe0000504ec8] do_nmi at ffffffffa662a97f + #4 [fffffe0000504ef0] end_repeat_nmi at ffffffffa70015e8 + [exception RIP: clone_endio+172] + RIP: ffffffffc005c1ec RSP: ffffa1d403d08e98 RFLAGS: 00000246 + RAX: 0000000000000000 RBX: ffff915326fba230 RCX: 0000000000000018 + RDX: ffffffffc0075400 RSI: 0000000000000000 RDI: ffff915326fba230 + RBP: ffff915326fba1c0 R8: 0000000000001000 R9: ffff915308d6d2a0 + R10: 000000a97dfe5e10 R11: ffffa1d40038fe98 R12: ffff915302babc40 + R13: ffff914f94360000 R14: 0000000000000000 R15: 0000000000000000 + ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 + --- --- + #5 [ffffa1d403d08e98] clone_endio at ffffffffc005c1ec [dm_mod] + #6 [ffffa1d403d08ed0] blk_update_request at ffffffffa6a96954 + #7 [ffffa1d403d08f10] scsi_end_request at ffffffffa6c9b968 + #8 [ffffa1d403d08f48] scsi_io_completion at ffffffffa6c9bb3e + #9 [ffffa1d403d08f90] blk_complete_reqs at ffffffffa6aa0e95 + #10 [ffffa1d403d08fa0] __softirqentry_text_start at ffffffffa72000dc + #11 [ffffa1d403d08ff0] do_softirq_own_stack at ffffffffa7000f9a + --- --- + #12 [ffffa1d40038fe70] do_softirq_own_stack at ffffffffa7000f9a + [exception RIP: unknown or invalid address] + RIP: 0000000000000000 RSP: 0000000000000000 RFLAGS: 00000000 + RAX: ffffffffa672eae5 RBX: ffffffffa83b34e0 RCX: ffffffffa672eb12 + RDX: 0000000000000010 RSI: 8b7d6c8869010c00 RDI: 0000000000000085 + RBP: 0000000000000286 R8: ffff914f820a8000 R9: ffffffffa67a94e0 + R10: 0000000000000286 R11: ffffffffa66fb4c5 R12: ffffffffa67a898b + R13: 0000000000000000 R14: fffffffffffffff8 R15: ffffffffa67a1e68 + ORIG_RAX: 0000000000000000 CS: 0000 SS: ffffffffa672edff + bt: WARNING: possibly bogus exception frame + #13 [ffffa1d40038ff30] start_secondary at ffffffffa665fa2c + #14 [ffffa1d40038ff50] secondary_startup_64_no_verify at ffffffffa6600116 + ... + +Reported-by: Marco Patalano +--- + x86_64.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/x86_64.c b/x86_64.c +index 5b671bd97775..6cac3936b33d 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -3825,10 +3825,11 @@ in_exception_stack: + up -= 1; + bt->instptr = *up; + /* +- * No exception frame when coming from call_softirq. ++ * No exception frame when coming from do_softirq_own_stack ++ * or call_softirq. + */ + if ((sp = value_search(bt->instptr, &offset)) && +- STREQ(sp->name, "call_softirq")) ++ (STREQ(sp->name, "do_softirq_own_stack") || STREQ(sp->name, "call_softirq"))) + irq_eframe = 0; + bt->frameptr = 0; + done = FALSE; +-- +2.37.1 + diff --git a/0034-Fix-for-dis-command-to-correctly-display-the-offset-.patch b/0034-Fix-for-dis-command-to-correctly-display-the-offset-.patch new file mode 100644 index 0000000..653e7de --- /dev/null +++ b/0034-Fix-for-dis-command-to-correctly-display-the-offset-.patch @@ -0,0 +1,62 @@ +From 59c19818190dd4b7ae0dc2221586a4ad6f4fe905 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Tue, 21 Feb 2023 11:03:26 +0800 +Subject: [PATCH 06/12] Fix for "dis" command to correctly display the offset + of disassembly code + +For gdb-10.2, the disassembly code may start with "=>", which needs to +be stripped when calculating the address. Otherwise, parsing the address +will fail because the current code always assumes that it starts with the +"0x". For example: + + crash> gdb disassemble 0xffffffffa2317add + Dump of assembler code for function native_queued_spin_lock_slowpath: + ... + 0xffffffffa2317ad3 <+35>: mov %edx,%eax + 0xffffffffa2317ad5 <+37>: lock cmpxchg %ecx,(%rdi) + => 0xffffffffa2317ad9 <+41>: cmp %eax,%edx + 0xffffffffa2317adb <+43>: jne 0xffffffffa2317ac0 ... + 0xffffffffa2317add <+45>: pop %rbp + ... + +Without the patch: + crash> dis 0xffffffffa2317add -r | tail -5 + 0xffffffffa2317ad3 : mov %edx,%eax + 0xffffffffa2317ad5 : lock cmpxchg %ecx,(%rdi) + 0xffffffffa2317ad5 : cmp %eax,%edx + ^^ + 0xffffffffa2317adb : jne 0xffffffffa2317ac0 ... + 0xffffffffa2317add : pop %rbp + +With the patch: + + crash> dis 0xffffffffa2317add -r | tail -5 + 0xffffffffa2317ad3 : mov %edx,%eax + 0xffffffffa2317ad5 : lock cmpxchg %ecx,(%rdi) + 0xffffffffa2317ad9 : cmp %eax,%edx + 0xffffffffa2317adb : jne 0xffffffffa2317ac0 ... + 0xffffffffa2317add : pop %rbp + +Reported-by: Vernon Lovejoy +--- + kernel.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/kernel.c b/kernel.c +index a42e6ad7d78c..6e98f5f6f6b1 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -2112,6 +2112,10 @@ cmd_dis(void) + rewind(pc->tmpfile); + + while (fgets(buf2, BUFSIZE, pc->tmpfile)) { ++ ++ if (STRNEQ(buf2, "=>")) ++ shift_string_left(buf2, 2); ++ + strip_beginning_whitespace(buf2); + + if (do_load_module_filter) +-- +2.37.1 + diff --git a/0035-x86_64-Fix-bt-command-on-kernels-with-random_kstack_.patch b/0035-x86_64-Fix-bt-command-on-kernels-with-random_kstack_.patch new file mode 100644 index 0000000..4b560bd --- /dev/null +++ b/0035-x86_64-Fix-bt-command-on-kernels-with-random_kstack_.patch @@ -0,0 +1,299 @@ +From daa43fa5324f2dd232ad72df2c6554646868f3b2 Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Mon, 20 Feb 2023 10:28:53 +0900 +Subject: [PATCH 07/12] x86_64: Fix "bt" command on kernels with + random_kstack_offset=on + +On kernels configured with CONFIG_RANDOMIZE_KSTACK_OFFSET=y and +random_kstack_offset=on, a random offset is added to task stacks with +__kstack_alloca() at the beginning of do_syscall_64() and other syscall +entry functions. This eventually does the following instruction. + + : sub %rax,%rsp + +On the other hand, crash uses only a part of data for ORC unwinder to +unwind stacks and if an ip value doesn't have a usable ORC data, it +caluculates the frame size with parsing the assembly of the function. + +However, crash cannot calculate the frame size correctly with the +instruction above, and prints stale return addresses like this: + + crash> bt 1 + PID: 1 TASK: ffff9c250023b880 CPU: 0 COMMAND: "systemd" + #0 [ffffb7e5c001fc80] __schedule at ffffffff91ae2b16 + #1 [ffffb7e5c001fd00] schedule at ffffffff91ae2ed3 + #2 [ffffb7e5c001fd18] schedule_hrtimeout_range_clock at ffffffff91ae7ed8 + #3 [ffffb7e5c001fda8] ep_poll at ffffffff913ef828 + #4 [ffffb7e5c001fe48] do_epoll_wait at ffffffff913ef943 + #5 [ffffb7e5c001fe80] __x64_sys_epoll_wait at ffffffff913f0130 + #6 [ffffb7e5c001fed0] do_syscall_64 at ffffffff91ad7169 + #7 [ffffb7e5c001fef0] do_syscall_64 at ffffffff91ad7179 << + #8 [ffffb7e5c001ff10] syscall_exit_to_user_mode at ffffffff91adaab2 << stale entries + #9 [ffffb7e5c001ff20] do_syscall_64 at ffffffff91ad7179 << + #10 [ffffb7e5c001ff50] entry_SYSCALL_64_after_hwframe at ffffffff91c0009b + RIP: 00007f258d9427ae RSP: 00007fffda631d60 RFLAGS: 00000293 + ... + +To fix this, enhance the use of ORC data. The ORC unwinder often uses +%rbp value, so keep it from exception frames and inactive task stacks. + +Signed-off-by: Kazuhito Hagio +--- + defs.h | 1 + + symbols.c | 1 + + x86_64.c | 118 ++++++++++++++++++++++++++++++++++++++---------------- + 3 files changed, 85 insertions(+), 35 deletions(-) + +diff --git a/defs.h b/defs.h +index ab4f02cc65cf..e76af3c78b69 100644 +--- a/defs.h ++++ b/defs.h +@@ -2207,6 +2207,7 @@ struct offset_table { /* stash of commonly-used offsets */ + long sock_sk_common; + long sock_common_skc_v6_daddr; + long sock_common_skc_v6_rcv_saddr; ++ long inactive_task_frame_bp; + }; + + struct size_table { /* stash of commonly-used sizes */ +diff --git a/symbols.c b/symbols.c +index b702b9665ec1..a974fc9141a0 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -8822,6 +8822,7 @@ dump_offset_table(char *spec, ulong makestruct) + OFFSET(task_struct_tss_ksp)); + fprintf(fp, " task_struct_thread_eip: %ld\n", + OFFSET(task_struct_thread_eip)); ++ fprintf(fp, " inactive_task_frame_bp: %ld\n", OFFSET(inactive_task_frame_bp)); + fprintf(fp, " inactive_task_frame_ret_addr: %ld\n", + OFFSET(inactive_task_frame_ret_addr)); + fprintf(fp, " task_struct_thread_esp: %ld\n", +diff --git a/x86_64.c b/x86_64.c +index 6cac3936b33d..8e3eb8957af1 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -122,7 +122,7 @@ static int x86_64_do_not_cache_framesize(struct syment *, ulong); + static int x86_64_framesize_cache_func(int, ulong, int *, int, struct syment *); + static ulong x86_64_get_framepointer(struct bt_info *, ulong); + int search_for_eframe_target_caller(struct bt_info *, ulong, int *); +-static int x86_64_get_framesize(struct bt_info *, ulong, ulong); ++static int x86_64_get_framesize(struct bt_info *, ulong, ulong, char *); + static void x86_64_framesize_debug(struct bt_info *); + static void x86_64_get_active_set(void); + static int x86_64_get_kvaddr_ranges(struct vaddr_range *); +@@ -3642,7 +3642,7 @@ in_exception_stack: + bt, ofp); + rsp += SIZE(pt_regs); /* guaranteed kernel mode */ + if (bt->eframe_ip && ((framesize = x86_64_get_framesize(bt, +- bt->eframe_ip, rsp)) >= 0)) ++ bt->eframe_ip, rsp, NULL)) >= 0)) + rsp += framesize; + level++; + irq_eframe = 0; +@@ -3674,7 +3674,7 @@ in_exception_stack: + case BACKTRACE_ENTRY_DISPLAYED: + level++; + if ((framesize = x86_64_get_framesize(bt, +- bt->eframe_ip ? bt->eframe_ip : *up, rsp)) >= 0) { ++ bt->eframe_ip ? bt->eframe_ip : *up, rsp, NULL)) >= 0) { + rsp += framesize; + i += framesize/sizeof(ulong); + } +@@ -3747,7 +3747,7 @@ in_exception_stack: + } + + level++; +- if ((framesize = x86_64_get_framesize(bt, bt->instptr, rsp)) >= 0) ++ if ((framesize = x86_64_get_framesize(bt, bt->instptr, rsp, NULL)) >= 0) + rsp += framesize; + } + } +@@ -3799,7 +3799,7 @@ in_exception_stack: + case BACKTRACE_ENTRY_DISPLAYED: + level++; + if ((framesize = x86_64_get_framesize(bt, +- bt->eframe_ip ? bt->eframe_ip : *up, rsp)) >= 0) { ++ bt->eframe_ip ? bt->eframe_ip : *up, rsp, NULL)) >= 0) { + rsp += framesize; + i += framesize/sizeof(ulong); + } +@@ -3909,24 +3909,34 @@ in_exception_stack: + (STREQ(rip_symbol, "thread_return") || + STREQ(rip_symbol, "schedule") || + STREQ(rip_symbol, "__schedule"))) { +- if (STREQ(rip_symbol, "__schedule")) { +- i = (rsp - bt->stackbase)/sizeof(ulong); +- x86_64_print_stack_entry(bt, ofp, level, +- i, bt->instptr); +- level++; +- rsp = __schedule_frame_adjust(rsp, bt); +- if (STREQ(closest_symbol(bt->instptr), "schedule")) ++ if ((machdep->flags & ORC) && VALID_MEMBER(inactive_task_frame_ret_addr)) { ++ /* ++ * %rsp should have the address of inactive_task_frame, so ++ * skip the registers before ret_addr to adjust rsp. ++ */ ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "rsp: %lx rbp: %lx\n", rsp, bt->bptr); ++ rsp += OFFSET(inactive_task_frame_ret_addr); ++ } else { ++ if (STREQ(rip_symbol, "__schedule")) { ++ i = (rsp - bt->stackbase)/sizeof(ulong); ++ x86_64_print_stack_entry(bt, ofp, level, ++ i, bt->instptr); ++ level++; ++ rsp = __schedule_frame_adjust(rsp, bt); ++ if (STREQ(closest_symbol(bt->instptr), "schedule")) ++ bt->flags |= BT_SCHEDULE; ++ } else + bt->flags |= BT_SCHEDULE; +- } else +- bt->flags |= BT_SCHEDULE; +- +- if (bt->flags & BT_SCHEDULE) { +- i = (rsp - bt->stackbase)/sizeof(ulong); +- x86_64_print_stack_entry(bt, ofp, level, +- i, bt->instptr); +- bt->flags &= ~(ulonglong)BT_SCHEDULE; +- rsp += sizeof(ulong); +- level++; ++ ++ if (bt->flags & BT_SCHEDULE) { ++ i = (rsp - bt->stackbase)/sizeof(ulong); ++ x86_64_print_stack_entry(bt, ofp, level, ++ i, bt->instptr); ++ bt->flags &= ~(ulonglong)BT_SCHEDULE; ++ rsp += sizeof(ulong); ++ level++; ++ } + } + } + +@@ -3957,7 +3967,7 @@ in_exception_stack: + irq_eframe = 0; + bt->flags |= BT_EFRAME_TARGET; + if (bt->eframe_ip && ((framesize = x86_64_get_framesize(bt, +- bt->eframe_ip, rsp)) >= 0)) ++ bt->eframe_ip, rsp, NULL)) >= 0)) + rsp += framesize; + bt->flags &= ~BT_EFRAME_TARGET; + } +@@ -4044,7 +4054,7 @@ in_exception_stack: + case BACKTRACE_ENTRY_DISPLAYED: + level++; + if ((framesize = x86_64_get_framesize(bt, +- bt->eframe_ip ? bt->eframe_ip : *up, rsp)) >= 0) { ++ bt->eframe_ip ? bt->eframe_ip : *up, rsp, (char *)up)) >= 0) { + rsp += framesize; + i += framesize/sizeof(ulong); + } +@@ -4755,7 +4765,8 @@ x86_64_exception_frame(ulong flags, ulong kvaddr, char *local, + bt->instptr = rip; + bt->stkptr = rsp; + bt->bptr = rbp; +- } ++ } else if (machdep->flags & ORC) ++ bt->bptr = rbp; + + if (kvaddr) + FREEBUF(pt_regs_buf); +@@ -5315,6 +5326,10 @@ x86_64_get_sp(struct bt_info *bt) + OFFSET(thread_struct_rsp), KVADDR, + &rsp, sizeof(void *), + "thread_struct rsp", FAULT_ON_ERROR); ++ if ((machdep->flags & ORC) && VALID_MEMBER(inactive_task_frame_bp)) { ++ readmem(rsp + OFFSET(inactive_task_frame_bp), KVADDR, &bt->bptr, ++ sizeof(void *), "inactive_task_frame.bp", FAULT_ON_ERROR); ++ } + return rsp; + } + +@@ -6421,6 +6436,9 @@ x86_64_ORC_init(void) + orc->__stop_orc_unwind = symbol_value("__stop_orc_unwind"); + orc->orc_lookup = symbol_value("orc_lookup"); + ++ MEMBER_OFFSET_INIT(inactive_task_frame_bp, "inactive_task_frame", "bp"); ++ MEMBER_OFFSET_INIT(inactive_task_frame_ret_addr, "inactive_task_frame", "ret_addr"); ++ + machdep->flags |= ORC; + } + +@@ -8489,7 +8507,7 @@ search_for_eframe_target_caller(struct bt_info *bt, ulong stkptr, int *framesize + (BT_OLD_BACK_TRACE|BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_ALL|BT_FRAMESIZE_DISABLE) + + static int +-x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp) ++x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp, char *stack_ptr) + { + int c, framesize, instr, arg, max; + struct syment *sp; +@@ -8590,19 +8608,49 @@ x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp) + if ((machdep->flags & ORC) && (korc = orc_find(textaddr))) { + if (CRASHDEBUG(1)) { + fprintf(fp, +- "rsp: %lx textaddr: %lx framesize: %d -> spo: %d bpo: %d spr: %d bpr: %d type: %d %s", +- rsp, textaddr, framesize, korc->sp_offset, korc->bp_offset, +- korc->sp_reg, korc->bp_reg, korc->type, +- (korc->type == ORC_TYPE_CALL) && (korc->sp_reg == ORC_REG_SP) ? "" : "(UNUSED)"); ++ "rsp: %lx textaddr: %lx -> spo: %d bpo: %d spr: %d bpr: %d type: %d", ++ rsp, textaddr, korc->sp_offset, korc->bp_offset, ++ korc->sp_reg, korc->bp_reg, korc->type); + if (MEMBER_EXISTS("orc_entry", "end")) + fprintf(fp, " end: %d", korc->end); + fprintf(fp, "\n"); + } + +- if ((korc->type == ORC_TYPE_CALL) && (korc->sp_reg == ORC_REG_SP)) { +- framesize = (korc->sp_offset - 8); +- return (x86_64_framesize_cache_func(FRAMESIZE_ENTER, textaddr, +- &framesize, exception, NULL)); ++ if (korc->type == ORC_TYPE_CALL) { ++ ulong prev_sp = 0, prev_bp = 0; ++ framesize = -1; ++ ++ if (korc->sp_reg == ORC_REG_SP) { ++ framesize = (korc->sp_offset - 8); ++ ++ /* rsp points to a return address, so +8 to use sp_offset */ ++ prev_sp = (rsp + 8) + korc->sp_offset; ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "rsp: %lx prev_sp: %lx framesize: %d\n", ++ rsp, prev_sp, framesize); ++ } else if ((korc->sp_reg == ORC_REG_BP) && bt->bptr) { ++ prev_sp = bt->bptr + korc->sp_offset; ++ framesize = (prev_sp - (rsp + 8) - 8); ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "rsp: %lx rbp: %lx prev_sp: %lx framesize: %d\n", ++ rsp, bt->bptr, prev_sp, framesize); ++ } ++ ++ if ((korc->bp_reg == ORC_REG_PREV_SP) && prev_sp) { ++ prev_bp = prev_sp + korc->bp_offset; ++ if (stack_ptr && INSTACK(prev_bp, bt)) { ++ bt->bptr = ULONG(stack_ptr + (prev_bp - rsp)); ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "rsp: %lx prev_sp: %lx prev_bp: %lx -> %lx\n", ++ rsp, prev_sp, prev_bp, bt->bptr); ++ } else ++ bt->bptr = 0; ++ } else if ((korc->bp_reg != ORC_REG_UNDEFINED)) ++ bt->bptr = 0; ++ ++ if (framesize >= 0) ++ /* Do not cache this, possibly it may be variable. */ ++ return framesize; + } + } + +@@ -8758,7 +8806,7 @@ x86_64_framesize_debug(struct bt_info *bt) + if (!bt->hp->eip) + error(INFO, "x86_64_framesize_debug: ignoring command\n"); + else +- x86_64_get_framesize(bt, bt->hp->eip, 0); ++ x86_64_get_framesize(bt, bt->hp->eip, 0, NULL); + break; + + case -3: +-- +2.37.1 + diff --git a/0036-Fix-for-search-u-option-failing-in-maple-tree-kernel.patch b/0036-Fix-for-search-u-option-failing-in-maple-tree-kernel.patch new file mode 100644 index 0000000..a3d88e4 --- /dev/null +++ b/0036-Fix-for-search-u-option-failing-in-maple-tree-kernel.patch @@ -0,0 +1,168 @@ +From d0d6cf868577fdca81c40633fa082dae1794294f Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Wed, 22 Feb 2023 14:32:09 +0800 +Subject: [PATCH 08/12] Fix for "search -u" option failing in maple tree kernel + +Kernel with maple tree enabled doesn't have mmap as a member of mm_struct[1], +so OFFSET(mm_struct_mmap) case needed to be handled differently for +maple tree kernel. + +Before: +crash> search -u a + +search: invalid structure member offset: mm_struct_mmap + FILE: memory.c LINE: 14255 FUNCTION: address_space_start() + +[crash] error trace: 549500 => 548fff => 5f1c91 => 5f1c13 + + 5f1c13: OFFSET_verify.part.36+51 + 5f1c91: OFFSET_verify+49 + 548fff: address_space_start+106 + 549500: cmd_search+855 + +search: invalid structure member offset: mm_struct_mmap + FILE: memory.c LINE: 14255 FUNCTION: address_space_start() + +After: +crash> search -u a +7ffea63e6440: a + +[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=763ecb035029f500d7e6dc99acd1ad299b7726a1 + +Signed-off-by: Tao Liu +--- + memory.c | 89 +++++++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 65 insertions(+), 24 deletions(-) + +diff --git a/memory.c b/memory.c +index d9cd616f19de..c4a6ecd18004 100644 +--- a/memory.c ++++ b/memory.c +@@ -14245,14 +14245,28 @@ vaddr_type(ulong vaddr, struct task_context *tc) + static int + address_space_start(struct task_context *tc, ulong *addr) + { +- ulong vma; ++ ulong mm_mt, entry_num, i, vma = 0; + char *vma_buf; ++ struct list_pair *entry_list; + + if (!tc->mm_struct) + return FALSE; + +- fill_mm_struct(tc->mm_struct); +- vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap)); ++ if (INVALID_MEMBER(mm_struct_mmap) && VALID_MEMBER(mm_struct_mm_mt)) { ++ mm_mt = tc->mm_struct + OFFSET(mm_struct_mm_mt); ++ entry_num = do_maple_tree(mm_mt, MAPLE_TREE_COUNT, NULL); ++ entry_list = (struct list_pair *)GETBUF(entry_num * sizeof(struct list_pair)); ++ do_maple_tree(mm_mt, MAPLE_TREE_GATHER, entry_list); ++ for (i = 0; i < entry_num; i++) { ++ if (!!(vma = (ulong)entry_list[i].value)) ++ break; ++ } ++ FREEBUF(entry_list); ++ } else { ++ fill_mm_struct(tc->mm_struct); ++ vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap)); ++ } ++ + if (!vma) + return FALSE; + vma_buf = fill_vma_cache(vma); +@@ -15491,6 +15505,30 @@ search_physical(struct searchinfo *si) + FREEBUF(pagebuf); + } + ++static bool ++check_vma(ulong vma, ulong vaddr, ulong *vm_next, ulong *nextvaddr) ++{ ++ char *vma_buf; ++ ulong vm_start, vm_end; ++ ++ vma_buf = fill_vma_cache(vma); ++ ++ vm_start = ULONG(vma_buf + OFFSET(vm_area_struct_vm_start)); ++ vm_end = ULONG(vma_buf + OFFSET(vm_area_struct_vm_end)); ++ if (vm_next) ++ *vm_next = ULONG(vma_buf + OFFSET(vm_area_struct_vm_next)); ++ ++ if (vaddr <= vm_start) { ++ *nextvaddr = vm_start; ++ return TRUE; ++ } ++ ++ if ((vaddr > vm_start) && (vaddr < vm_end)) { ++ *nextvaddr = vaddr; ++ return TRUE; ++ } ++ return FALSE; ++} + + /* + * Return the next mapped user virtual address page that comes after +@@ -15500,37 +15538,40 @@ static int + next_upage(struct task_context *tc, ulong vaddr, ulong *nextvaddr) + { + ulong vma, total_vm; +- char *vma_buf; +- ulong vm_start, vm_end; + ulong vm_next; ++ ulong mm_mt, entry_num, i; ++ struct list_pair *entry_list; + + if (!tc->mm_struct) + return FALSE; + +- fill_mm_struct(tc->mm_struct); +- vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap)); ++ fill_mm_struct(tc->mm_struct); ++ vaddr = VIRTPAGEBASE(vaddr) + PAGESIZE(); /* first possible page */ + total_vm = ULONG(tt->mm_struct + OFFSET(mm_struct_total_vm)); +- +- if (!vma || (total_vm == 0)) ++ if (!total_vm) + return FALSE; + +- vaddr = VIRTPAGEBASE(vaddr) + PAGESIZE(); /* first possible page */ +- +- for ( ; vma; vma = vm_next) { +- vma_buf = fill_vma_cache(vma); +- +- vm_start = ULONG(vma_buf + OFFSET(vm_area_struct_vm_start)); +- vm_end = ULONG(vma_buf + OFFSET(vm_area_struct_vm_end)); +- vm_next = ULONG(vma_buf + OFFSET(vm_area_struct_vm_next)); +- +- if (vaddr <= vm_start) { +- *nextvaddr = vm_start; +- return TRUE; ++ if (INVALID_MEMBER(mm_struct_mmap) && VALID_MEMBER(mm_struct_mm_mt)) { ++ mm_mt = tc->mm_struct + OFFSET(mm_struct_mm_mt); ++ entry_num = do_maple_tree(mm_mt, MAPLE_TREE_COUNT, NULL); ++ entry_list = (struct list_pair *)GETBUF(entry_num * sizeof(struct list_pair)); ++ do_maple_tree(mm_mt, MAPLE_TREE_GATHER, entry_list); ++ for (i = 0; i < entry_num; i++) { ++ if (!!(vma = (ulong)entry_list[i].value) && ++ check_vma(vma, vaddr, NULL, nextvaddr)) { ++ FREEBUF(entry_list); ++ return TRUE; ++ } + } ++ FREEBUF(entry_list); ++ } else { ++ vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap)); + +- if ((vaddr > vm_start) && (vaddr < vm_end)) { +- *nextvaddr = vaddr; +- return TRUE; ++ if (!vma) ++ return FALSE; ++ for ( ; vma; vma = vm_next) { ++ if (check_vma(vma, vaddr, &vm_next, nextvaddr)) ++ return TRUE; + } + } + +-- +2.37.1 + diff --git a/0037-Enhance-net-command-to-display-IPv6-address-of-netwo.patch b/0037-Enhance-net-command-to-display-IPv6-address-of-netwo.patch new file mode 100644 index 0000000..717ce96 --- /dev/null +++ b/0037-Enhance-net-command-to-display-IPv6-address-of-netwo.patch @@ -0,0 +1,258 @@ +From 38325fab533751a001b80481cec149213d125abb Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Tue, 7 Mar 2023 17:14:25 +0800 +Subject: [PATCH 09/12] Enhance "net" command to display IPv6 address of + network interface + +Currently, the "net" command displays only the IPv4 address of a network +interface. Support outputting IPv6 addresses. For example: + +Without the patch: + crash> net + NET_DEVICE NAME IP ADDRESS(ES) + ffff8d01b1205000 lo 127.0.0.1 + ffff8d0087e40000 eno1 192.168.122.2 + +With the patch: + crash> net + NET_DEVICE NAME IP ADDRESS(ES) + ffff8d01b1205000 lo 127.0.0.1, ::1 + ffff8d0087e40000 eno1 192.168.122.2, xxxx:xx:x:xxxx:xxxx:xxx:xxxx:xxxx, yyyy::yyyy:yyy:yyyy:yyyy + +Also align with longer device names. + +Related kernel commit: +502a2ffd7376 ("ipv6: convert idev_list to list macros") + +Reported-by: Buland Kumar Singh +Signed-off-by: Lianbo Jiang +Signed-off-by: Kazuhito Hagio +--- + defs.h | 6 +++ + net.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++----- + symbols.c | 6 +++ + 3 files changed, 112 insertions(+), 9 deletions(-) + +diff --git a/defs.h b/defs.h +index e76af3c78b69..1f2cf6e0ce01 100644 +--- a/defs.h ++++ b/defs.h +@@ -2208,6 +2208,12 @@ struct offset_table { /* stash of commonly-used offsets */ + long sock_common_skc_v6_daddr; + long sock_common_skc_v6_rcv_saddr; + long inactive_task_frame_bp; ++ long net_device_ip6_ptr; ++ long inet6_dev_addr_list; ++ long inet6_ifaddr_addr; ++ long inet6_ifaddr_if_list; ++ long inet6_ifaddr_if_next; ++ long in6_addr_in6_u; + }; + + struct size_table { /* stash of commonly-used sizes */ +diff --git a/net.c b/net.c +index aa445ab7ee13..987dc8934942 100644 +--- a/net.c ++++ b/net.c +@@ -71,6 +71,7 @@ static void print_neighbour_q(ulong, int); + static void get_netdev_info(ulong, struct devinfo *); + static void get_device_name(ulong, char *); + static long get_device_address(ulong, char **, long); ++static void get_device_ip6_address(ulong, char **, long); + static void get_sock_info(ulong, char *); + static void dump_arp(void); + static void arp_state_to_flags(unsigned char); +@@ -114,6 +115,13 @@ net_init(void) + net->dev_ip_ptr = MEMBER_OFFSET_INIT(net_device_ip_ptr, + "net_device", "ip_ptr"); + MEMBER_OFFSET_INIT(net_device_dev_list, "net_device", "dev_list"); ++ MEMBER_OFFSET_INIT(net_device_ip6_ptr, "net_device", "ip6_ptr"); ++ MEMBER_OFFSET_INIT(inet6_dev_addr_list, "inet6_dev", "addr_list"); ++ MEMBER_OFFSET_INIT(inet6_ifaddr_addr, "inet6_ifaddr", "addr"); ++ MEMBER_OFFSET_INIT(inet6_ifaddr_if_list, "inet6_ifaddr", "if_list"); ++ MEMBER_OFFSET_INIT(inet6_ifaddr_if_next, "inet6_ifaddr", "if_next"); ++ MEMBER_OFFSET_INIT(in6_addr_in6_u, "in6_addr", "in6_u"); ++ + MEMBER_OFFSET_INIT(net_dev_base_head, "net", "dev_base_head"); + ARRAY_LENGTH_INIT(net->net_device_name_index, + net_device_name, "net_device.name", NULL, sizeof(char)); +@@ -466,7 +474,7 @@ show_net_devices(ulong task) + buf = GETBUF(buflen); + flen = MAX(VADDR_PRLEN, strlen(net->netdevice)); + +- fprintf(fp, "%s NAME IP ADDRESS(ES)\n", ++ fprintf(fp, "%s NAME IP ADDRESS(ES)\n", + mkstring(upper_case(net->netdevice, buf), + flen, CENTER|LJUST, NULL)); + +@@ -475,9 +483,10 @@ show_net_devices(ulong task) + mkstring(buf, flen, CENTER|RJUST|LONG_HEX, MKSTR(next))); + + get_device_name(next, buf); +- fprintf(fp, "%-6s ", buf); ++ fprintf(fp, "%-10s ", buf); + +- buflen = get_device_address(next, &buf, buflen); ++ get_device_address(next, &buf, buflen); ++ get_device_ip6_address(next, &buf, buflen); + fprintf(fp, "%s\n", buf); + + readmem(next+net->dev_next, KVADDR, &next, +@@ -503,7 +512,7 @@ show_net_devices_v2(ulong task) + buf = GETBUF(buflen); + flen = MAX(VADDR_PRLEN, strlen(net->netdevice)); + +- fprintf(fp, "%s NAME IP ADDRESS(ES)\n", ++ fprintf(fp, "%s NAME IP ADDRESS(ES)\n", + mkstring(upper_case(net->netdevice, buf), + flen, CENTER|LJUST, NULL)); + +@@ -528,9 +537,10 @@ show_net_devices_v2(ulong task) + MKSTR(ld->list_ptr[i]))); + + get_device_name(ld->list_ptr[i], buf); +- fprintf(fp, "%-6s ", buf); ++ fprintf(fp, "%-10s ", buf); + +- buflen = get_device_address(ld->list_ptr[i], &buf, buflen); ++ get_device_address(ld->list_ptr[i], &buf, buflen); ++ get_device_ip6_address(ld->list_ptr[i], &buf, buflen); + fprintf(fp, "%s\n", buf); + } + +@@ -556,7 +566,7 @@ show_net_devices_v3(ulong task) + buf = GETBUF(buflen); + flen = MAX(VADDR_PRLEN, strlen(net->netdevice)); + +- fprintf(fp, "%s NAME IP ADDRESS(ES)\n", ++ fprintf(fp, "%s NAME IP ADDRESS(ES)\n", + mkstring(upper_case(net->netdevice, buf), + flen, CENTER|LJUST, NULL)); + +@@ -591,9 +601,10 @@ show_net_devices_v3(ulong task) + MKSTR(ld->list_ptr[i]))); + + get_device_name(ld->list_ptr[i], buf); +- fprintf(fp, "%-6s ", buf); ++ fprintf(fp, "%-10s ", buf); + +- buflen = get_device_address(ld->list_ptr[i], &buf, buflen); ++ get_device_address(ld->list_ptr[i], &buf, buflen); ++ get_device_ip6_address(ld->list_ptr[i], &buf, buflen); + fprintf(fp, "%s\n", buf); + } + +@@ -925,6 +936,86 @@ get_device_address(ulong devaddr, char **bufp, long buflen) + return buflen; + } + ++static void ++get_device_ip6_address(ulong devaddr, char **bufp, long buflen) ++{ ++ ulong ip6_ptr = 0, pos = 0, bufsize = buflen, addr = 0; ++ struct in6_addr ip6_addr; ++ char *buf; ++ char str[INET6_ADDRSTRLEN] = {0}; ++ char buffer[INET6_ADDRSTRLEN + 2] = {0}; ++ uint len = 0; ++ ++ buf = *bufp; ++ pos = strlen(buf); ++ ++ readmem(devaddr + OFFSET(net_device_ip6_ptr), KVADDR, ++ &ip6_ptr, sizeof(ulong), "ip6_ptr", FAULT_ON_ERROR); ++ ++ if (!ip6_ptr) ++ return; ++ ++ /* ++ * 502a2ffd7376 ("ipv6: convert idev_list to list macros") ++ * v2.6.35-rc1~473^2~733 ++ */ ++ if (VALID_MEMBER(inet6_ifaddr_if_list)) { ++ struct list_data list_data, *ld; ++ ulong cnt = 0, i; ++ ++ ld = &list_data; ++ BZERO(ld, sizeof(struct list_data)); ++ ld->flags |= LIST_ALLOCATE; ++ ld->start = ip6_ptr + OFFSET(inet6_dev_addr_list); ++ ld->list_head_offset = OFFSET(inet6_ifaddr_if_list); ++ cnt = do_list(ld); ++ ++ for (i = 1; i < cnt; i++) { ++ ++ addr = ld->list_ptr[i] + OFFSET(inet6_ifaddr_addr); ++ readmem(addr + OFFSET(in6_addr_in6_u), KVADDR, &ip6_addr, ++ sizeof(struct in6_addr), "in6_addr.in6_u", FAULT_ON_ERROR); ++ ++ inet_ntop(AF_INET6, (void*)&ip6_addr, str, INET6_ADDRSTRLEN); ++ sprintf(buffer, "%s%s", pos ? ", " : "", str); ++ len = strlen(buffer); ++ if (pos + len >= bufsize) { ++ RESIZEBUF(*bufp, bufsize, bufsize + buflen); ++ buf = *bufp; ++ BZERO(buf + bufsize, buflen); ++ bufsize += buflen; ++ } ++ BCOPY(buffer, &buf[pos], len); ++ pos += len; ++ } ++ ++ FREEBUF(ld->list_ptr); ++ return; ++ } ++ ++ readmem(ip6_ptr + OFFSET(inet6_dev_addr_list), KVADDR, ++ &addr, sizeof(void *), "inet6_dev.addr_list", FAULT_ON_ERROR); ++ ++ while (addr) { ++ readmem(addr + OFFSET(in6_addr_in6_u), KVADDR, &ip6_addr, ++ sizeof(struct in6_addr), "in6_addr.in6_u", FAULT_ON_ERROR); ++ inet_ntop(AF_INET6, (void*)&ip6_addr, str, INET6_ADDRSTRLEN); ++ sprintf(buffer, "%s%s", pos ? ", " : "", str); ++ len = strlen(buffer); ++ ++ if (pos + len >= bufsize) { ++ RESIZEBUF(*bufp, bufsize, bufsize + buflen); ++ buf = *bufp; ++ BZERO(buf + bufsize, buflen); ++ bufsize += buflen; ++ } ++ BCOPY(buffer, &buf[pos], len); ++ pos += len; ++ readmem(addr + OFFSET(inet6_ifaddr_if_next), KVADDR, &addr, ++ sizeof(void *), "inet6_ifaddr.if_next", FAULT_ON_ERROR); ++ } ++} ++ + /* + * Get the family, type, local and destination address/port pairs. + */ +diff --git a/symbols.c b/symbols.c +index a974fc9141a0..28846d06273c 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -9787,6 +9787,7 @@ dump_offset_table(char *spec, ulong makestruct) + OFFSET(net_device_addr_len)); + fprintf(fp, " net_device_ip_ptr: %ld\n", + OFFSET(net_device_ip_ptr)); ++ fprintf(fp, " net_device_ip6_ptr: %ld\n", OFFSET(net_device_ip6_ptr)); + fprintf(fp, " net_device_dev_list: %ld\n", + OFFSET(net_device_dev_list)); + fprintf(fp, " net_dev_base_head: %ld\n", +@@ -9839,6 +9840,11 @@ dump_offset_table(char *spec, ulong makestruct) + fprintf(fp, " inet_opt_num: %ld\n", + OFFSET(inet_opt_num)); + ++ fprintf(fp, " inet6_dev_addr_list: %ld\n", OFFSET(inet6_dev_addr_list)); ++ fprintf(fp, " inet6_ifaddr_addr: %ld\n", OFFSET(inet6_ifaddr_addr)); ++ fprintf(fp, " inet6_ifaddr_if_list: %ld\n", OFFSET(inet6_ifaddr_if_list)); ++ fprintf(fp, " inet6_ifaddr_if_next: %ld\n", OFFSET(inet6_ifaddr_if_next)); ++ fprintf(fp, " in6_addr_in6_u: %ld\n", OFFSET(in6_addr_in6_u)); + fprintf(fp, " ipv6_pinfo_rcv_saddr: %ld\n", + OFFSET(ipv6_pinfo_rcv_saddr)); + fprintf(fp, " ipv6_pinfo_daddr: %ld\n", +-- +2.37.1 + diff --git a/0038-Fix-C99-compatibility-issues-in-embedded-copy-of-GDB.patch b/0038-Fix-C99-compatibility-issues-in-embedded-copy-of-GDB.patch new file mode 100644 index 0000000..e83632f --- /dev/null +++ b/0038-Fix-C99-compatibility-issues-in-embedded-copy-of-GDB.patch @@ -0,0 +1,1071 @@ +From 57dda56af5c78da5e79cc4a83839e86d3ff6ab43 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Tue, 14 Feb 2023 08:06:39 +0100 +Subject: [PATCH 10/12] Fix C99 compatibility issues in embedded copy of GDB + +These issues have been fixed in upstream GDB already: + +In the file bfd/elf-bfd.h, startswith is now used in stead of +strncmp. libiberty was fixed via an import from GCC. Readline +8.1 has been imported and has these issues fixed upstream. + +While at it, also update the bundled copy of in +gnulib. This header file unfortunately shadows the glibc version, +causing build failures on ppc64le if it is too old. + +Related GDB commits: +0075c53724f7 Impport libiberty commit: 885b6660c17f from gcc mainline. +b4f26d541aa7 Import GNU Readline 8.1 +9c9d63b15ad5 gnulib: update to 776af40e0 +3f3328b816ee Use startswith more for strncmp function calls. + +Related glibc commit: +2337e04e21ba cdefs: Limit definition of fortification macros + +Related gnulib commit: +afeeb21058d1 libc-config: fix include problem on older Debian + +Signed-off-by: Florian Weimer +Signed-off-by: Kazuhito Hagio +--- + gdb-10.2.patch | 1027 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 1027 insertions(+) + +diff --git a/gdb-10.2.patch b/gdb-10.2.patch +index aa34743501ad..5089df9e72e1 100644 +--- a/gdb-10.2.patch ++++ b/gdb-10.2.patch +@@ -2078,3 +2078,1030 @@ exit 0 + + return new_type; + } ++--- gdb-10.2/bfd/elf-bfd.h.orig +++++ gdb-10.2/bfd/elf-bfd.h ++@@ -27,6 +27,8 @@ ++ #include "elf/internal.h" ++ #include "bfdlink.h" ++ +++#include +++ ++ #ifdef __cplusplus ++ extern "C" { ++ #endif ++--- gdb-10.2/gnulib/import/cdefs.h.orig +++++ gdb-10.2/gnulib/import/cdefs.h ++@@ -1,17 +1,18 @@ ++-/* Copyright (C) 1992-2020 Free Software Foundation, Inc. +++/* Copyright (C) 1992-2023 Free Software Foundation, Inc. +++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++- modify it under the terms of the GNU General Public +++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++- version 3 of the License, or (at your option) any later version. +++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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. +++ Lesser General Public License for more details. ++ ++- You should have received a copy of the GNU General Public +++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++@@ -25,16 +26,38 @@ ++ ++ /* The GNU libc does not support any K&R compilers or the traditional mode ++ of ISO C compilers anymore. Check for some of the combinations not ++- anymore supported. */ ++-#if defined __GNUC__ && !defined __STDC__ ++-# error "You need a ISO C conforming compiler to use the glibc headers" +++ supported anymore. */ +++#if defined __GNUC__ && !defined __STDC__ && !defined __cplusplus +++# error "You need a ISO C or C++ conforming compiler to use the glibc headers" ++ #endif ++ ++ /* Some user header file might have defined this before. */ ++ #undef __P ++ #undef __PMT ++ ++-#ifdef __GNUC__ +++/* Compilers that lack __has_attribute may object to +++ #if defined __has_attribute && __has_attribute (...) +++ even though they do not need to evaluate the right-hand side of the &&. +++ Similarly for __has_builtin, etc. */ +++#if (defined __has_attribute \ +++ && (!defined __clang_minor__ \ +++ || 3 < __clang_major__ + (5 <= __clang_minor__))) +++# define __glibc_has_attribute(attr) __has_attribute (attr) +++#else +++# define __glibc_has_attribute(attr) 0 +++#endif +++#ifdef __has_builtin +++# define __glibc_has_builtin(name) __has_builtin (name) +++#else +++# define __glibc_has_builtin(name) 0 +++#endif +++#ifdef __has_extension +++# define __glibc_has_extension(ext) __has_extension (ext) +++#else +++# define __glibc_has_extension(ext) 0 +++#endif +++ +++#if defined __GNUC__ || defined __clang__ ++ ++ /* All functions, except those with callbacks or those that ++ synchronize memory, are leaf functions. */ ++@@ -47,21 +70,26 @@ ++ # endif ++ ++ /* GCC can always grok prototypes. For C++ programs we add throw() ++- to help it optimize the function calls. But this works only with ++- gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions +++ to help it optimize the function calls. But this only works with +++ gcc 2.8.x and egcs. For gcc 3.4 and up we even mark C functions ++ as non-throwing using a function attribute since programs can use ++ the -fexceptions options for C code as well. */ ++-# if !defined __cplusplus && __GNUC_PREREQ (3, 3) +++# if !defined __cplusplus \ +++ && (__GNUC_PREREQ (3, 4) || __glibc_has_attribute (__nothrow__)) ++ # define __THROW __attribute__ ((__nothrow__ __LEAF)) ++ # define __THROWNL __attribute__ ((__nothrow__)) ++ # define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct ++ # define __NTHNL(fct) __attribute__ ((__nothrow__)) fct ++ # else ++-# if defined __cplusplus && __GNUC_PREREQ (2,8) ++-# define __THROW throw () ++-# define __THROWNL throw () ++-# define __NTH(fct) __LEAF_ATTR fct throw () ++-# define __NTHNL(fct) fct throw () +++# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4) +++# if __cplusplus >= 201103L +++# define __THROW noexcept (true) +++# else +++# define __THROW throw () +++# endif +++# define __THROWNL __THROW +++# define __NTH(fct) __LEAF_ATTR fct __THROW +++# define __NTHNL(fct) fct __THROW ++ # else ++ # define __THROW ++ # define __THROWNL ++@@ -70,7 +98,7 @@ ++ # endif ++ # endif ++ ++-#else /* Not GCC. */ +++#else /* Not GCC or clang. */ ++ ++ # if (defined __cplusplus \ ++ || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) ++@@ -83,16 +111,7 @@ ++ # define __THROWNL ++ # define __NTH(fct) fct ++ ++-#endif /* GCC. */ ++- ++-/* Compilers that are not clang may object to ++- #if defined __clang__ && __has_extension(...) ++- even though they do not need to evaluate the right-hand side of the &&. */ ++-#if defined __clang__ && defined __has_extension ++-# define __glibc_clang_has_extension(ext) __has_extension (ext) ++-#else ++-# define __glibc_clang_has_extension(ext) 0 ++-#endif +++#endif /* GCC || clang. */ ++ ++ /* These two macros are not used in glibc anymore. They are kept here ++ only because some other projects expect the macros to be defined. */ ++@@ -123,14 +142,70 @@ ++ #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) ++ #define __bos0(ptr) __builtin_object_size (ptr, 0) ++ +++/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */ +++#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \ +++ || __GNUC_PREREQ (12, 0)) +++# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) +++# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) +++#else +++# define __glibc_objsize0(__o) __bos0 (__o) +++# define __glibc_objsize(__o) __bos (__o) +++#endif +++ +++#if __USE_FORTIFY_LEVEL > 0 +++/* Compile time conditions to choose between the regular, _chk and _chk_warn +++ variants. These conditions should get evaluated to constant and optimized +++ away. */ +++ +++#define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s)) +++#define __glibc_unsigned_or_positive(__l) \ +++ ((__typeof (__l)) 0 < (__typeof (__l)) -1 \ +++ || (__builtin_constant_p (__l) && (__l) > 0)) +++ +++/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ +++ condition can be folded to a constant and if it is true, or unknown (-1) */ +++#define __glibc_safe_or_unknown_len(__l, __s, __osz) \ +++ ((__builtin_constant_p (__osz) && (__osz) == (__SIZE_TYPE__) -1) \ +++ || (__glibc_unsigned_or_positive (__l) \ +++ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ +++ (__s), (__osz))) \ +++ && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz)))) +++ +++/* Conversely, we know at compile time that the length is unsafe if the +++ __L * __S <= __OBJSZ condition can be folded to a constant and if it is +++ false. */ +++#define __glibc_unsafe_len(__l, __s, __osz) \ +++ (__glibc_unsigned_or_positive (__l) \ +++ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ +++ __s, __osz)) \ +++ && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) +++ +++/* Fortify function f. __f_alias, __f_chk and __f_chk_warn must be +++ declared. */ +++ +++#define __glibc_fortify(f, __l, __s, __osz, ...) \ +++ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ +++ ? __ ## f ## _alias (__VA_ARGS__) \ +++ : (__glibc_unsafe_len (__l, __s, __osz) \ +++ ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ +++ : __ ## f ## _chk (__VA_ARGS__, __osz))) +++ +++/* Fortify function f, where object size argument passed to f is the number of +++ elements and not total size. */ +++ +++#define __glibc_fortify_n(f, __l, __s, __osz, ...) \ +++ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ +++ ? __ ## f ## _alias (__VA_ARGS__) \ +++ : (__glibc_unsafe_len (__l, __s, __osz) \ +++ ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ +++ : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) +++#endif +++ ++ #if __GNUC_PREREQ (4,3) ++-# define __warndecl(name, msg) \ ++- extern void name (void) __attribute__((__warning__ (msg))) ++ # define __warnattr(msg) __attribute__((__warning__ (msg))) ++ # define __errordecl(name, msg) \ ++ extern void name (void) __attribute__((__error__ (msg))) ++ #else ++-# define __warndecl(name, msg) extern void name (void) ++ # define __warnattr(msg) ++ # define __errordecl(name, msg) extern void name (void) ++ #endif ++@@ -142,8 +217,8 @@ ++ #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __HP_cc ++ # define __flexarr [] ++ # define __glibc_c99_flexarr_available 1 ++-#elif __GNUC_PREREQ (2,97) ++-/* GCC 2.97 supports C99 flexible array members as an extension, +++#elif __GNUC_PREREQ (2,97) || defined __clang__ +++/* GCC 2.97 and clang support C99 flexible array members as an extension, ++ even when in C89 mode or compiling C++ (any version). */ ++ # define __flexarr [] ++ # define __glibc_c99_flexarr_available 1 ++@@ -169,7 +244,7 @@ ++ Example: ++ int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */ ++ ++-#if defined __GNUC__ && __GNUC__ >= 2 +++#if (defined __GNUC__ && __GNUC__ >= 2) || (__clang_major__ >= 4) ++ ++ # define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias)) ++ # ifdef __cplusplus ++@@ -194,17 +269,17 @@ ++ */ ++ #endif ++ ++-/* GCC has various useful declarations that can be made with the ++- `__attribute__' syntax. All of the ways we use this do fine if ++- they are omitted for compilers that don't understand it. */ ++-#if !defined __GNUC__ || __GNUC__ < 2 +++/* GCC and clang have various useful declarations that can be made with +++ the '__attribute__' syntax. All of the ways we use this do fine if +++ they are omitted for compilers that don't understand it. */ +++#if !(defined __GNUC__ || defined __clang__) ++ # define __attribute__(xyz) /* Ignore */ ++ #endif ++ ++ /* At some point during the gcc 2.96 development the `malloc' attribute ++ for functions was introduced. We don't want to use it unconditionally ++ (although this would be possible) since it generates warnings. */ ++-#if __GNUC_PREREQ (2,96) +++#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__malloc__) ++ # define __attribute_malloc__ __attribute__ ((__malloc__)) ++ #else ++ # define __attribute_malloc__ /* Ignore */ ++@@ -219,26 +294,41 @@ ++ # define __attribute_alloc_size__(params) /* Ignore. */ ++ #endif ++ +++/* Tell the compiler which argument to an allocation function +++ indicates the alignment of the allocation. */ +++#if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__alloc_align__) +++# define __attribute_alloc_align__(param) \ +++ __attribute__ ((__alloc_align__ param)) +++#else +++# define __attribute_alloc_align__(param) /* Ignore. */ +++#endif +++ ++ /* At some point during the gcc 2.96 development the `pure' attribute ++ for functions was introduced. We don't want to use it unconditionally ++ (although this would be possible) since it generates warnings. */ ++-#if __GNUC_PREREQ (2,96) +++#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__pure__) ++ # define __attribute_pure__ __attribute__ ((__pure__)) ++ #else ++ # define __attribute_pure__ /* Ignore */ ++ #endif ++ ++ /* This declaration tells the compiler that the value is constant. */ ++-#if __GNUC_PREREQ (2,5) +++#if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__) ++ # define __attribute_const__ __attribute__ ((__const__)) ++ #else ++ # define __attribute_const__ /* Ignore */ ++ #endif ++ +++#if __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__) +++# define __attribute_maybe_unused__ __attribute__ ((__unused__)) +++#else +++# define __attribute_maybe_unused__ /* Ignore */ +++#endif +++ ++ /* At some point during the gcc 3.1 development the `used' attribute ++ for functions was introduced. We don't want to use it unconditionally ++ (although this would be possible) since it generates warnings. */ ++-#if __GNUC_PREREQ (3,1) +++#if __GNUC_PREREQ (3,1) || __glibc_has_attribute (__used__) ++ # define __attribute_used__ __attribute__ ((__used__)) ++ # define __attribute_noinline__ __attribute__ ((__noinline__)) ++ #else ++@@ -247,7 +337,7 @@ ++ #endif ++ ++ /* Since version 3.2, gcc allows marking deprecated functions. */ ++-#if __GNUC_PREREQ (3,2) +++#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__) ++ # define __attribute_deprecated__ __attribute__ ((__deprecated__)) ++ #else ++ # define __attribute_deprecated__ /* Ignore */ ++@@ -256,8 +346,8 @@ ++ /* Since version 4.5, gcc also allows one to specify the message printed ++ when a deprecated function is used. clang claims to be gcc 4.2, but ++ may also support this feature. */ ++-#if __GNUC_PREREQ (4,5) || \ ++- __glibc_clang_has_extension (__attribute_deprecated_with_message__) +++#if __GNUC_PREREQ (4,5) \ +++ || __glibc_has_extension (__attribute_deprecated_with_message__) ++ # define __attribute_deprecated_msg__(msg) \ ++ __attribute__ ((__deprecated__ (msg))) ++ #else ++@@ -270,7 +360,7 @@ ++ If several `format_arg' attributes are given for the same function, in ++ gcc-3.0 and older, all but the last one are ignored. In newer gccs, ++ all designated arguments are considered. */ ++-#if __GNUC_PREREQ (2,8) +++#if __GNUC_PREREQ (2,8) || __glibc_has_attribute (__format_arg__) ++ # define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x))) ++ #else ++ # define __attribute_format_arg__(x) /* Ignore */ ++@@ -280,7 +370,7 @@ ++ attribute for functions was introduced. We don't want to use it ++ unconditionally (although this would be possible) since it ++ generates warnings. */ ++-#if __GNUC_PREREQ (2,97) +++#if __GNUC_PREREQ (2,97) || __glibc_has_attribute (__format__) ++ # define __attribute_format_strfmon__(a,b) \ ++ __attribute__ ((__format__ (__strfmon__, a, b))) ++ #else ++@@ -288,19 +378,33 @@ ++ #endif ++ ++ /* The nonnull function attribute marks pointer parameters that ++- must not be NULL. Do not define __nonnull if it is already defined, ++- for portability when this file is used in Gnulib. */ +++ must not be NULL. This has the name __nonnull in glibc, +++ and __attribute_nonnull__ in files shared with Gnulib to avoid +++ collision with a different __nonnull in DragonFlyBSD 5.9. */ +++#ifndef __attribute_nonnull__ +++# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__) +++# define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params)) +++# else +++# define __attribute_nonnull__(params) +++# endif +++#endif ++ #ifndef __nonnull ++-# if __GNUC_PREREQ (3,3) ++-# define __nonnull(params) __attribute__ ((__nonnull__ params)) +++# define __nonnull(params) __attribute_nonnull__ (params) +++#endif +++ +++/* The returns_nonnull function attribute marks the return type of the function +++ as always being non-null. */ +++#ifndef __returns_nonnull +++# if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__returns_nonnull__) +++# define __returns_nonnull __attribute__ ((__returns_nonnull__)) ++ # else ++-# define __nonnull(params) +++# define __returns_nonnull ++ # endif ++ #endif ++ ++ /* If fortification mode, we warn about unused results of certain ++ function calls which can lead to problems. */ ++-#if __GNUC_PREREQ (3,4) +++#if __GNUC_PREREQ (3,4) || __glibc_has_attribute (__warn_unused_result__) ++ # define __attribute_warn_unused_result__ \ ++ __attribute__ ((__warn_unused_result__)) ++ # if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0 ++@@ -314,7 +418,7 @@ ++ #endif ++ ++ /* Forces a function to be always inlined. */ ++-#if __GNUC_PREREQ (3,2) +++#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__always_inline__) ++ /* The Linux kernel defines __always_inline in stddef.h (283d7573), and ++ it conflicts with this definition. Therefore undefine it first to ++ allow either header to be included first. */ ++@@ -327,7 +431,7 @@ ++ ++ /* Associate error messages with the source location of the call site rather ++ than with the source location inside the function. */ ++-#if __GNUC_PREREQ (4,3) +++#if __GNUC_PREREQ (4,3) || __glibc_has_attribute (__artificial__) ++ # define __attribute_artificial__ __attribute__ ((__artificial__)) ++ #else ++ # define __attribute_artificial__ /* Ignore */ ++@@ -370,12 +474,14 @@ ++ run in pedantic mode if the uses are carefully marked using the ++ `__extension__' keyword. But this is not generally available before ++ version 2.8. */ ++-#if !__GNUC_PREREQ (2,8) +++#if !(__GNUC_PREREQ (2,8) || defined __clang__) ++ # define __extension__ /* Ignore */ ++ #endif ++ ++-/* __restrict is known in EGCS 1.2 and above. */ ++-#if !__GNUC_PREREQ (2,92) +++/* __restrict is known in EGCS 1.2 and above, and in clang. +++ It works also in C++ mode (outside of arrays), but only when spelled +++ as '__restrict', not 'restrict'. */ +++#if !(__GNUC_PREREQ (2,92) || __clang_major__ >= 3) ++ # if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L ++ # define __restrict restrict ++ # else ++@@ -385,8 +491,9 @@ ++ ++ /* ISO C99 also allows to declare arrays as non-overlapping. The syntax is ++ array_name[restrict] ++- GCC 3.1 supports this. */ ++-#if __GNUC_PREREQ (3,1) && !defined __GNUG__ +++ GCC 3.1 and clang support this. +++ This syntax is not usable in C++ mode. */ +++#if (__GNUC_PREREQ (3,1) || __clang_major__ >= 3) && !defined __cplusplus ++ # define __restrict_arr __restrict ++ #else ++ # ifdef __GNUC__ ++@@ -401,7 +508,7 @@ ++ # endif ++ #endif ++ ++-#if __GNUC__ >= 3 +++#if (__GNUC__ >= 3) || __glibc_has_builtin (__builtin_expect) ++ # define __glibc_unlikely(cond) __builtin_expect ((cond), 0) ++ # define __glibc_likely(cond) __builtin_expect ((cond), 1) ++ #else ++@@ -409,15 +516,10 @@ ++ # define __glibc_likely(cond) (cond) ++ #endif ++ ++-#ifdef __has_attribute ++-# define __glibc_has_attribute(attr) __has_attribute (attr) ++-#else ++-# define __glibc_has_attribute(attr) 0 ++-#endif ++- ++ #if (!defined _Noreturn \ ++ && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ ++- && !__GNUC_PREREQ (4,7)) +++ && !(__GNUC_PREREQ (4,7) \ +++ || (3 < __clang_major__ + (5 <= __clang_minor__)))) ++ # if __GNUC_PREREQ (2,8) ++ # define _Noreturn __attribute__ ((__noreturn__)) ++ # else ++@@ -434,22 +536,63 @@ ++ # define __attribute_nonstring__ ++ #endif ++ +++/* Undefine (also defined in libc-symbols.h). */ +++#undef __attribute_copy__ +++#if __GNUC_PREREQ (9, 0) +++/* Copies attributes from the declaration or type referenced by +++ the argument. */ +++# define __attribute_copy__(arg) __attribute__ ((__copy__ (arg))) +++#else +++# define __attribute_copy__(arg) +++#endif +++ ++ #if (!defined _Static_assert && !defined __cplusplus \ ++ && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ ++- && (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__)) +++ && (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \ +++ || defined __STRICT_ANSI__)) ++ # define _Static_assert(expr, diagnostic) \ ++ extern int (*__Static_assert_function (void)) \ ++ [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })] ++ #endif ++ ++-/* The #ifndef lets Gnulib avoid including these on non-glibc ++- platforms, where the includes typically do not exist. */ ++-#ifndef __WORDSIZE +++/* Gnulib avoids including these, as they don't work on non-glibc or +++ older glibc platforms. */ +++#ifndef __GNULIB_CDEFS ++ # include ++ # include ++ #endif ++ ++-#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH +++#if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 +++# ifdef __REDIRECT +++ +++/* Alias name defined automatically. */ +++# define __LDBL_REDIR(name, proto) ... unused__ldbl_redir +++# define __LDBL_REDIR_DECL(name) \ +++ extern __typeof (name) name __asm (__ASMNAME ("__" #name "ieee128")); +++ +++/* Alias name defined automatically, with leading underscores. */ +++# define __LDBL_REDIR2_DECL(name) \ +++ extern __typeof (__##name) __##name \ +++ __asm (__ASMNAME ("__" #name "ieee128")); +++ +++/* Alias name defined manually. */ +++# define __LDBL_REDIR1(name, proto, alias) ... unused__ldbl_redir1 +++# define __LDBL_REDIR1_DECL(name, alias) \ +++ extern __typeof (name) name __asm (__ASMNAME (#alias)); +++ +++# define __LDBL_REDIR1_NTH(name, proto, alias) \ +++ __REDIRECT_NTH (name, proto, alias) +++# define __REDIRECT_NTH_LDBL(name, proto, alias) \ +++ __LDBL_REDIR1_NTH (name, proto, __##alias##ieee128) +++ +++/* Unused. */ +++# define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl +++# define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth +++ +++# else +++_Static_assert (0, "IEEE 128-bits long double requires redirection on this platform"); +++# endif +++#elif defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH ++ # define __LDBL_COMPAT 1 ++ # ifdef __REDIRECT ++ # define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias) ++@@ -458,6 +601,8 @@ ++ # define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias) ++ # define __LDBL_REDIR_NTH(name, proto) \ ++ __LDBL_REDIR1_NTH (name, proto, __nldbl_##name) +++# define __LDBL_REDIR2_DECL(name) \ +++ extern __typeof (__##name) __##name __asm (__ASMNAME ("__nldbl___" #name)); ++ # define __LDBL_REDIR1_DECL(name, alias) \ ++ extern __typeof (name) name __asm (__ASMNAME (#alias)); ++ # define __LDBL_REDIR_DECL(name) \ ++@@ -468,11 +613,13 @@ ++ __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias) ++ # endif ++ #endif ++-#if !defined __LDBL_COMPAT || !defined __REDIRECT +++#if (!defined __LDBL_COMPAT && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0) \ +++ || !defined __REDIRECT ++ # define __LDBL_REDIR1(name, proto, alias) name proto ++ # define __LDBL_REDIR(name, proto) name proto ++ # define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW ++ # define __LDBL_REDIR_NTH(name, proto) name proto __THROW +++# define __LDBL_REDIR2_DECL(name) ++ # define __LDBL_REDIR_DECL(name) ++ # ifdef __REDIRECT ++ # define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias) ++@@ -503,7 +650,7 @@ ++ check is required to enable the use of generic selection. */ ++ #if !defined __cplusplus \ ++ && (__GNUC_PREREQ (4, 9) \ ++- || __glibc_clang_has_extension (c_generic_selections) \ +++ || __glibc_has_extension (c_generic_selections) \ ++ || (!defined __GNUC__ && defined __STDC_VERSION__ \ ++ && __STDC_VERSION__ >= 201112L)) ++ # define __HAVE_GENERIC_SELECTION 1 ++@@ -511,4 +658,50 @@ ++ # define __HAVE_GENERIC_SELECTION 0 ++ #endif ++ +++#if __GNUC_PREREQ (10, 0) +++/* Designates a 1-based positional argument ref-index of pointer type +++ that can be used to access size-index elements of the pointed-to +++ array according to access mode, or at least one element when +++ size-index is not provided: +++ access (access-mode, [, ]) */ +++# define __attr_access(x) __attribute__ ((__access__ x)) +++/* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may +++ use the access attribute to get object sizes from function definition +++ arguments, so we can't use them on functions we fortify. Drop the object +++ size hints for such functions. */ +++# if __USE_FORTIFY_LEVEL == 3 +++# define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, o))) +++# else +++# define __fortified_attr_access(a, o, s) __attr_access ((a, o, s)) +++# endif +++# if __GNUC_PREREQ (11, 0) +++# define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno))) +++# else +++# define __attr_access_none(argno) +++# endif +++#else +++# define __fortified_attr_access(a, o, s) +++# define __attr_access(x) +++# define __attr_access_none(argno) +++#endif +++ +++#if __GNUC_PREREQ (11, 0) +++/* Designates dealloc as a function to call to deallocate objects +++ allocated by the declared function. */ +++# define __attr_dealloc(dealloc, argno) \ +++ __attribute__ ((__malloc__ (dealloc, argno))) +++# define __attr_dealloc_free __attr_dealloc (__builtin_free, 1) +++#else +++# define __attr_dealloc(dealloc, argno) +++# define __attr_dealloc_free +++#endif +++ +++/* Specify that a function such as setjmp or vfork may return +++ twice. */ +++#if __GNUC_PREREQ (4, 1) +++# define __attribute_returns_twice__ __attribute__ ((__returns_twice__)) +++#else +++# define __attribute_returns_twice__ /* Ignore. */ +++#endif +++ ++ #endif /* sys/cdefs.h */ ++--- gdb-10.2/gnulib/import/libc-config.h.orig +++++ gdb-10.2/gnulib/import/libc-config.h ++@@ -79,13 +79,9 @@ ++ #ifndef _FEATURES_H ++ # define _FEATURES_H 1 ++ #endif ++-/* Define __WORDSIZE so that does not attempt to include ++- nonexistent files. Make it a syntax error, since Gnulib does not ++- use __WORDSIZE now, and if Gnulib uses it later the syntax error ++- will let us know that __WORDSIZE needs configuring. */ ++-#ifndef __WORDSIZE ++-# define __WORDSIZE %%% ++-#endif +++/* Define __GNULIB_CDEFS so that does not attempt to include +++ nonexistent files. */ +++# define __GNULIB_CDEFS ++ /* Undef the macros unconditionally defined by our copy of glibc ++ , so that they do not clash with any system-defined ++ versions. */ ++--- gdb-10.2/libiberty/aclocal.m4.orig +++++ gdb-10.2/libiberty/aclocal.m4 ++@@ -16,6 +16,8 @@ AC_CACHE_CHECK([for working strncmp], ac ++ [AC_TRY_RUN([ ++ /* Test by Jim Wilson and Kaveh Ghazi. ++ Check whether strncmp reads past the end of its string parameters. */ +++#include +++#include ++ #include ++ ++ #ifdef HAVE_FCNTL_H ++@@ -43,7 +45,8 @@ AC_CACHE_CHECK([for working strncmp], ac ++ ++ #define MAP_LEN 0x10000 ++ ++-main () +++int +++main (void) ++ { ++ #if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE) ++ char *p; ++@@ -149,7 +152,10 @@ if test $ac_cv_os_cray = yes; then ++ fi ++ ++ AC_CACHE_CHECK(stack direction for C alloca, ac_cv_c_stack_direction, ++-[AC_TRY_RUN([find_stack_direction () +++[AC_TRY_RUN([#include +++ +++int +++find_stack_direction (void) ++ { ++ static char *addr = 0; ++ auto char dummy; ++@@ -161,7 +167,9 @@ AC_CACHE_CHECK(stack direction for C all ++ else ++ return (&dummy > addr) ? 1 : -1; ++ } ++-main () +++ +++int +++main (void) ++ { ++ exit (find_stack_direction() < 0); ++ }], ++--- gdb-10.2/libiberty/configure.orig +++++ gdb-10.2/libiberty/configure ++@@ -6724,7 +6724,10 @@ else ++ else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ /* end confdefs.h. */ ++-find_stack_direction () +++#include +++ +++int +++find_stack_direction (void) ++ { ++ static char *addr = 0; ++ auto char dummy; ++@@ -6736,7 +6739,9 @@ find_stack_direction () ++ else ++ return (&dummy > addr) ? 1 : -1; ++ } ++-main () +++ +++int +++main (void) ++ { ++ exit (find_stack_direction() < 0); ++ } ++@@ -7557,6 +7562,8 @@ else ++ ++ /* Test by Jim Wilson and Kaveh Ghazi. ++ Check whether strncmp reads past the end of its string parameters. */ +++#include +++#include ++ #include ++ ++ #ifdef HAVE_FCNTL_H ++@@ -7584,7 +7591,8 @@ else ++ ++ #define MAP_LEN 0x10000 ++ ++-main () +++int +++main (void) ++ { ++ #if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE) ++ char *p; ++--- gdb-10.2/readline/readline/aclocal.m4.orig +++++ gdb-10.2/readline/readline/aclocal.m4 ++@@ -10,6 +10,7 @@ AC_DEFUN(BASH_C_LONG_LONG, ++ ac_cv_c_long_long=yes ++ else ++ AC_TRY_RUN([ +++#include ++ int ++ main() ++ { ++@@ -33,6 +34,7 @@ AC_DEFUN(BASH_C_LONG_DOUBLE, ++ ac_cv_c_long_double=yes ++ else ++ AC_TRY_RUN([ +++#include ++ int ++ main() ++ { ++@@ -134,6 +136,8 @@ typedef int (*_bashfunc)(const char *, . ++ #else ++ typedef int (*_bashfunc)(); ++ #endif +++#include +++int ++ main() ++ { ++ _bashfunc pf; ++@@ -191,9 +195,11 @@ AC_CACHE_VAL(bash_cv_under_sys_siglist, ++ #ifdef HAVE_UNISTD_H ++ #include ++ #endif +++#include ++ #ifndef UNDER_SYS_SIGLIST_DECLARED ++ extern char *_sys_siglist[]; ++ #endif +++int ++ main() ++ { ++ char *msg = (char *)_sys_siglist[2]; ++@@ -218,9 +224,11 @@ AC_CACHE_VAL(bash_cv_sys_siglist, ++ #ifdef HAVE_UNISTD_H ++ #include ++ #endif +++#include ++ #if !HAVE_DECL_SYS_SIGLIST ++ extern char *sys_siglist[]; ++ #endif +++int ++ main() ++ { ++ char *msg = sys_siglist[2]; ++@@ -273,6 +281,8 @@ AC_CACHE_VAL(bash_cv_dup2_broken, ++ [AC_TRY_RUN([ ++ #include ++ #include +++#include +++int ++ main() ++ { ++ int fd1, fd2, fl; ++@@ -335,6 +345,8 @@ AC_CACHE_VAL(bash_cv_opendir_not_robust, ++ # include ++ # endif ++ #endif /* HAVE_DIRENT_H */ +++#include +++int ++ main() ++ { ++ DIR *dir; ++@@ -514,6 +526,8 @@ AC_TRY_RUN([ ++ #include ++ #include ++ #include +++#include +++int ++ main() ++ { ++ #ifdef HAVE_QUAD_T ++@@ -583,6 +597,7 @@ AC_CACHE_VAL(bash_cv_getenv_redef, ++ #ifdef HAVE_UNISTD_H ++ # include ++ #endif +++#include ++ #ifndef __STDC__ ++ # ifndef const ++ # define const ++@@ -598,6 +613,7 @@ getenv (name) ++ { ++ return "42"; ++ } +++int ++ main() ++ { ++ char *s; ++@@ -786,7 +802,9 @@ AC_CACHE_VAL(bash_cv_func_sigsetjmp, ++ #include ++ #include ++ #include +++#include ++ +++int ++ main() ++ { ++ #if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS) ++@@ -835,7 +853,10 @@ AC_CACHE_VAL(bash_cv_func_strcoll_broken ++ #if defined (HAVE_LOCALE_H) ++ #include ++ #endif +++#include +++#include ++ +++int ++ main(c, v) ++ int c; ++ char *v[]; ++@@ -881,6 +902,7 @@ AC_CACHE_VAL(bash_cv_printf_a_format, ++ [AC_TRY_RUN([ ++ #include ++ #include +++#include ++ ++ int ++ main() ++@@ -1241,6 +1263,8 @@ AC_CACHE_VAL(bash_cv_pgrp_pipe, ++ #ifdef HAVE_UNISTD_H ++ # include ++ #endif +++#include +++int ++ main() ++ { ++ # ifdef GETPGRP_VOID ++@@ -1305,6 +1329,7 @@ AC_CACHE_VAL(bash_cv_must_reinstall_sigh ++ #ifdef HAVE_UNISTD_H ++ #include ++ #endif +++#include ++ ++ typedef RETSIGTYPE sigfunc(); ++ ++@@ -1335,6 +1360,7 @@ int s; ++ nsigint++; ++ } ++ +++int ++ main() ++ { ++ nsigint = 0; ++@@ -1418,8 +1444,11 @@ AC_CACHE_VAL(bash_cv_sys_named_pipes, ++ #ifdef HAVE_UNISTD_H ++ #include ++ #endif +++#include +++#include ++ ++ /* Add more tests in here as appropriate. */ +++int ++ main() ++ { ++ int fd, err; ++@@ -1651,11 +1680,13 @@ AC_CACHE_VAL(bash_cv_unusable_rtsigs, ++ [AC_TRY_RUN([ ++ #include ++ #include +++#include ++ ++ #ifndef NSIG ++ # define NSIG 64 ++ #endif ++ +++int ++ main () ++ { ++ int n_sigs = 2 * NSIG; ++@@ -1770,6 +1801,7 @@ bash_cv_wcwidth_broken, ++ #include ++ #include ++ +++int ++ main(c, v) ++ int c; ++ char **v; ++@@ -1834,9 +1866,11 @@ AC_CACHE_VAL(ac_cv_rl_version, ++ [AC_TRY_RUN([ ++ #include ++ #include +++#include ++ ++ extern int rl_gnu_readline_p; ++ +++int ++ main() ++ { ++ FILE *fp; ++@@ -1926,7 +1960,9 @@ AC_CACHE_VAL(bash_cv_func_ctype_nonascii ++ #endif ++ #include ++ #include +++#include ++ +++int ++ main(c, v) ++ int c; ++ char *v[]; ++@@ -4068,7 +4104,9 @@ AC_DEFUN([BASH_FUNC_SNPRINTF], ++ AC_CACHE_CHECK([for standard-conformant snprintf], [bash_cv_func_snprintf], ++ [AC_TRY_RUN([ ++ #include +++#include ++ +++int ++ main() ++ { ++ int n; ++@@ -4154,6 +4192,7 @@ AC_CACHE_VAL(bash_cv_wexitstatus_offset, ++ ++ #include ++ +++int ++ main(c, v) ++ int c; ++ char **v; ++--- gdb-10.2/readline/readline/configure.orig +++++ gdb-10.2/readline/readline/configure ++@@ -1,5 +1,5 @@ ++ #! /bin/sh ++-# From configure.ac for Readline 8.0, version 2.85. +++# From configure.ac for Readline 8.0, version 2.86. ++ # Guess values for system-dependent variables and create Makefiles. ++ # Generated by GNU Autoconf 2.69 for readline 8.0. ++ # ++@@ -5316,6 +5316,7 @@ else ++ #ifdef HAVE_UNISTD_H ++ #include ++ #endif +++#include ++ ++ typedef RETSIGTYPE sigfunc(); ++ ++@@ -5346,7 +5347,8 @@ int s; ++ nsigint++; ++ } ++ ++-main() +++int +++main(void) ++ { ++ nsigint = 0; ++ set_signal_handler(SIGINT, sigint); ++@@ -5396,8 +5398,10 @@ else ++ #include ++ #include ++ #include +++#include ++ ++-main() +++int +++main(void) ++ { ++ #if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS) ++ exit (1); ++@@ -5499,7 +5503,10 @@ else ++ #if defined (HAVE_LOCALE_H) ++ #include ++ #endif +++#include +++#include ++ +++int ++ main(c, v) ++ int c; ++ char *v[]; ++@@ -5569,7 +5576,9 @@ else ++ #endif ++ #include ++ #include +++#include ++ +++int ++ main(c, v) ++ int c; ++ char *v[]; ++@@ -6713,6 +6722,7 @@ else ++ #include ++ #include ++ +++int ++ main(c, v) ++ int c; ++ char **v; ++--- gdb-10.2/readline/readline/configure.ac.orig +++++ gdb-10.2/readline/readline/configure.ac ++@@ -5,7 +5,7 @@ dnl report bugs to chet@po.cwru.edu ++ dnl ++ dnl Process this file with autoconf to produce a configure script. ++ ++-# Copyright (C) 1987-2018 Free Software Foundation, Inc. +++# Copyright (C) 1987-2019 Free Software Foundation, Inc. ++ ++ # 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 ++@@ -20,7 +20,7 @@ dnl Process this file with autoconf to p ++ # You should have received a copy of the GNU General Public License ++ # along with this program. If not, see . ++ ++-AC_REVISION([for Readline 8.0, version 2.85]) +++AC_REVISION([for Readline 8.0, version 2.86]) ++ ++ m4_include([../../config/override.m4]) ++ +-- +2.37.1 + diff --git a/0039-Fix-for-net-n-option-to-properly-deal-with-an-invali.patch b/0039-Fix-for-net-n-option-to-properly-deal-with-an-invali.patch new file mode 100644 index 0000000..dec47aa --- /dev/null +++ b/0039-Fix-for-net-n-option-to-properly-deal-with-an-invali.patch @@ -0,0 +1,44 @@ +From 5a652ed0c8db8d4c5891091b747470431054c717 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Wed, 8 Mar 2023 20:22:02 +0800 +Subject: [PATCH 11/12] Fix for "net -n" option to properly deal with an + invalid argument + +The help/man page of the "net" command suggests that "-n" option can +accept two kinds of argument: PID or task_struct pointer. However, +the "net -n" command accepts an invalid argument and shows the +namespace of the current context silently. For example: + + crash> net -n 1000000000 + NET_DEVICE NAME IP ADDRESS(ES) + ffff949dc11d7000 lo 127.0.0.1 + ffff949dcc01c000 eno49 192.168.122.17 + +With the patch, emit an error expectedly. + + crash> net -n 1000000000 + net: invalid task or pid value: 1000000000 + +Reported-by: Buland Kumar Singh +Signed-off-by: Lianbo Jiang +--- + net.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net.c b/net.c +index 987dc8934942..18c238be346d 100644 +--- a/net.c ++++ b/net.c +@@ -420,6 +420,9 @@ cmd_net(void) + case STR_PID: + case STR_TASK: + task = tc->task; ++ break; ++ case STR_INVALID: ++ error(FATAL, "invalid task or pid value: %s\n", args[optind]); + } + } + break; +-- +2.37.1 + diff --git a/0040-gdb-Fix-an-assertion-failure-in-dw2_find_pc_sect_com.patch b/0040-gdb-Fix-an-assertion-failure-in-dw2_find_pc_sect_com.patch new file mode 100644 index 0000000..dad68e2 --- /dev/null +++ b/0040-gdb-Fix-an-assertion-failure-in-dw2_find_pc_sect_com.patch @@ -0,0 +1,71 @@ +From ade71c3ec1d28751c3d6ba1eec71781bdff093d3 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Tue, 7 Mar 2023 19:04:08 +0800 +Subject: [PATCH 12/12] gdb: Fix an assertion failure in + dw2_find_pc_sect_compunit_symtab() + +This is a partial backport patch from gdb commit 834eaf9201c1 ("Fix +crash in new DWARF indexer"). + +Without the patch, the "dis -rl" option may abort due to an assertion +failure in gdb's dw2_find_pc_sect_compunit_symtab(): + + crash> dis -rl ffffffff96ad716c + dwarf2/read.c:4928: internal-error: compunit_symtab* dw2_find_pc_sect_compunit_symtab(objfile*, bound_minimal_symbol, CORE_ADDR, obj_section*, int): Assertion `result != NULL' failed. + A problem internal to GDB has been detected, + further debugging may prove unreliable. + Quit this debugging session? (y or n) dwarf2/read.c:4928: internal-error: compunit_symtab* dw2_find_pc_sect_compunit_symtab(objfile*, bound_minimal_symbol, CORE_ADDR, obj_section*, int): Assertion `result != NULL' failed. + A problem internal to GDB has been detected, + further debugging may prove unreliable. + Aborted (core dumped) + +Reported-by: Buland Kumar Singh +Signed-off-by: Lianbo Jiang +--- + gdb-10.2.patch | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/gdb-10.2.patch b/gdb-10.2.patch +index 5089df9e72e1..835aae9859be 100644 +--- a/gdb-10.2.patch ++++ b/gdb-10.2.patch +@@ -4,7 +4,7 @@ + # that have already been applied. However, if a gdb file has been modified + # multiple times, the subsequent patching may fail to recognize that a + # given patch has been previously applied, and will attempt to re-apply it. +-# To prevent any uninintended consequences, this file also acts as a ++# To prevent any unintended consequences, this file also acts as a + # shell script that can restore any gdb file to its original state prior + # to all subsequent patch applications. + +@@ -12,7 +12,8 @@ tar xvzmf gdb-10.2.tar.gz \ + gdb-10.2/gdb/symtab.c \ + gdb-10.2/gdb/printcmd.c \ + gdb-10.2/gdb/symfile.c \ +- gdb-10.2/gdb/Makefile.in ++ gdb-10.2/gdb/Makefile.in \ ++ gdb-10.2/gdb/dwarf2/read.c + + exit 0 + +@@ -3105,3 +3106,17 @@ exit 0 + + m4_include([../../config/override.m4]) + ++--- gdb-10.2/gdb/dwarf2/read.c.orig +++++ gdb-10.2/gdb/dwarf2/read.c ++@@ -4925,7 +4925,10 @@ dw2_find_pc_sect_compunit_symtab (struct objfile *objfile, ++ result = recursively_find_pc_sect_compunit_symtab ++ (dw2_instantiate_symtab (data, per_objfile, false), pc); ++ ++- gdb_assert (result != NULL); +++ if (warn_if_readin && result == nullptr) +++ warning (_("(Error: pc %s in address map, but not in symtab.)"), +++ paddress (objfile->arch (), pc)); +++ ++ return result; ++ } ++ +-- +2.37.1 + diff --git a/0041-Fix-kmem-n-option-to-display-memory-blocks-on-Linux-.patch b/0041-Fix-kmem-n-option-to-display-memory-blocks-on-Linux-.patch new file mode 100644 index 0000000..f231256 --- /dev/null +++ b/0041-Fix-kmem-n-option-to-display-memory-blocks-on-Linux-.patch @@ -0,0 +1,159 @@ +From 489093c2183f4f0365d8957e7275cd88225942ce Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Fri, 10 Mar 2023 02:38:26 +0000 +Subject: [PATCH] Fix "kmem -n" option to display memory blocks on Linux + 6.3-rc1 and later + +Kernel commit d2bf38c088e0 ("driver core: remove private pointer from +struct bus_type") removed the bus_type.p member, and the "kmem -n" +option fails with the following error before displaying memory block +information on Linux 6.3-rc1 and later kernels. + + kmem: invalid structure member offset: bus_type_p + FILE: memory.c LINE: 17852 FUNCTION: init_memory_block() + +Search bus_kset.list instead for subsys_private of memory subsys. + +Signed-off-by: Kazuhito Hagio +--- + defs.h | 2 ++ + memory.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++------ + symbols.c | 2 ++ + 3 files changed, 61 insertions(+), 6 deletions(-) + +diff --git a/defs.h b/defs.h +index 1f2cf6e0ce01..12ad6aaa0998 100644 +--- a/defs.h ++++ b/defs.h +@@ -2214,6 +2214,8 @@ struct offset_table { /* stash of commonly-used offsets */ + long inet6_ifaddr_if_list; + long inet6_ifaddr_if_next; + long in6_addr_in6_u; ++ long kset_kobj; ++ long subsys_private_subsys; + }; + + struct size_table { /* stash of commonly-used sizes */ +diff --git a/memory.c b/memory.c +index c4a6ecd18004..592a5ef49d50 100644 +--- a/memory.c ++++ b/memory.c +@@ -17822,6 +17822,13 @@ static void + init_memory_block_offset(void) + { + MEMBER_OFFSET_INIT(bus_type_p, "bus_type", "p"); ++ if (INVALID_MEMBER(bus_type_p)) { ++ MEMBER_OFFSET_INIT(kset_list, "kset", "list"); ++ MEMBER_OFFSET_INIT(kset_kobj, "kset", "kobj"); ++ MEMBER_OFFSET_INIT(kobject_name, "kobject", "name"); ++ MEMBER_OFFSET_INIT(kobject_entry, "kobject", "entry"); ++ MEMBER_OFFSET_INIT(subsys_private_subsys, "subsys_private", "subsys"); ++ } + MEMBER_OFFSET_INIT(subsys_private_klist_devices, + "subsys_private", "klist_devices"); + MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list"); +@@ -17842,15 +17849,60 @@ init_memory_block_offset(void) + } + + static void +-init_memory_block(struct list_data *ld, int *klistcnt, ulong **klistbuf) ++init_memory_block(int *klistcnt, ulong **klistbuf) + { +- ulong memory_subsys = symbol_value("memory_subsys"); + ulong private, klist, start; ++ struct list_data list_data, *ld; ++ ++ ld = &list_data; ++ private = 0; + + init_memory_block_offset(); + +- readmem(memory_subsys + OFFSET(bus_type_p), KVADDR, &private, +- sizeof(void *), "memory_subsys.private", FAULT_ON_ERROR); ++ /* ++ * v6.3-rc1 ++ * d2bf38c088e0 driver core: remove private pointer from struct bus_type ++ */ ++ if (INVALID_MEMBER(bus_type_p)) { ++ int i, cnt; ++ char buf[32]; ++ ulong bus_kset, list, name; ++ ++ BZERO(ld, sizeof(struct list_data)); ++ ++ get_symbol_data("bus_kset", sizeof(ulong), &bus_kset); ++ readmem(bus_kset + OFFSET(kset_list), KVADDR, &list, ++ sizeof(ulong), "bus_kset.list", FAULT_ON_ERROR); ++ ++ ld->flags |= LIST_ALLOCATE; ++ ld->start = list; ++ ld->end = bus_kset + OFFSET(kset_list); ++ ld->list_head_offset = OFFSET(kobject_entry); ++ ++ cnt = do_list(ld); ++ for (i = 0; i < cnt; i++) { ++ readmem(ld->list_ptr[i] + OFFSET(kobject_name), KVADDR, &name, ++ sizeof(ulong), "kobject.name", FAULT_ON_ERROR); ++ read_string(name, buf, sizeof(buf)-1); ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "kobject: %lx name: %s\n", ld->list_ptr[i], buf); ++ if (STREQ(buf, "memory")) { ++ /* entry is subsys_private.subsys.kobj. See bus_to_subsys(). */ ++ private = ld->list_ptr[i] - OFFSET(kset_kobj) ++ - OFFSET(subsys_private_subsys); ++ break; ++ } ++ } ++ FREEBUF(ld->list_ptr); ++ } else { ++ ulong memory_subsys = symbol_value("memory_subsys"); ++ readmem(memory_subsys + OFFSET(bus_type_p), KVADDR, &private, ++ sizeof(void *), "memory_subsys.private", FAULT_ON_ERROR); ++ } ++ ++ if (!private) ++ error(FATAL, "cannot determine subsys_private for memory.\n"); ++ + klist = private + OFFSET(subsys_private_klist_devices) + + OFFSET(klist_k_list); + BZERO(ld, sizeof(struct list_data)); +@@ -17875,7 +17927,6 @@ dump_memory_blocks(int initialize) + ulong memory_block, device; + ulong *klistbuf; + int klistcnt, i; +- struct list_data list_data; + char mb_hdr[BUFSIZE]; + char paddr_hdr[BUFSIZE]; + char buf1[BUFSIZE]; +@@ -17892,7 +17943,7 @@ dump_memory_blocks(int initialize) + if (initialize) + return; + +- init_memory_block(&list_data, &klistcnt, &klistbuf); ++ init_memory_block(&klistcnt, &klistbuf); + + if ((symbol_exists("memory_block_size_probed")) || + (MEMBER_EXISTS("memory_block", "end_section_nr"))) +diff --git a/symbols.c b/symbols.c +index 28846d06273c..f0721023816d 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -10404,6 +10404,7 @@ dump_offset_table(char *spec, ulong makestruct) + OFFSET(kobject_entry)); + fprintf(fp, " kset_list: %ld\n", + OFFSET(kset_list)); ++ fprintf(fp, " kset_kobj: %ld\n", OFFSET(kset_kobj)); + fprintf(fp, " request_list_count: %ld\n", + OFFSET(request_list_count)); + fprintf(fp, " request_cmd_flags: %ld\n", +@@ -10441,6 +10442,7 @@ dump_offset_table(char *spec, ulong makestruct) + fprintf(fp, " blk_mq_tags_rqs: %ld\n", + OFFSET(blk_mq_tags_rqs)); + ++ fprintf(fp, " subsys_private_subsys: %ld\n", OFFSET(subsys_private_subsys)); + fprintf(fp, " subsys_private_klist_devices: %ld\n", + OFFSET(subsys_private_klist_devices)); + fprintf(fp, " subsystem_kset: %ld\n", +-- +2.37.1 + diff --git a/crash.spec b/crash.spec index 5732189..10d7d97 100644 --- a/crash.spec +++ b/crash.spec @@ -4,7 +4,7 @@ Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles Name: crash Version: 8.0.2 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3 Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz @@ -46,8 +46,20 @@ Patch25: 0025-Add-do_maple_tree-for-maple-tree-operations.patch Patch26: 0026-Introduce-maple-tree-vma-iteration-to-vm_area_dump.patch Patch27: 0027-Update-the-help-text-of-tree-command-for-maple-tree.patch Patch28: 0028-Dump-maple-tree-offset-variables-by-help-o.patch -Patch29: crash-8.0.2_build.patch -Patch30: crash-8.0.0-5-gdb-cdefs.patch +Patch29: 0029-Fix-for-bt-command-printing-bogus-exception-frame-wa.patch +Patch30: 0030-Fix-kmem-s-S-not-working-properly-on-RHEL8.6-and-lat.patch +Patch31: 0031-Fix-for-net-s-option-to-show-IPv6-addresses-on-Linux.patch +Patch32: 0032-Fix-for-kmem-i-option-to-not-print-invalid-values-fo.patch +Patch33: 0033-Fix-for-bt-command-unnecessarily-printing-an-excepti.patch +Patch34: 0034-Fix-for-dis-command-to-correctly-display-the-offset-.patch +Patch35: 0035-x86_64-Fix-bt-command-on-kernels-with-random_kstack_.patch +Patch36: 0036-Fix-for-search-u-option-failing-in-maple-tree-kernel.patch +Patch37: 0037-Enhance-net-command-to-display-IPv6-address-of-netwo.patch +Patch38: 0038-Fix-C99-compatibility-issues-in-embedded-copy-of-GDB.patch +Patch39: 0039-Fix-for-net-n-option-to-properly-deal-with-an-invali.patch +Patch40: 0040-gdb-Fix-an-assertion-failure-in-dw2_find_pc_sect_com.patch +Patch41: 0041-Fix-kmem-n-option-to-display-memory-blocks-on-Linux-.patch +Patch42: crash-8.0.2_build.patch %description The core analysis suite is a self-contained tool that can be used to @@ -96,11 +108,20 @@ offered by Mission Critical Linux, or the LKCD kernel patch. %patch26 -p1 %patch27 -p1 %patch28 -p1 -%patch29 -p1 -b crash-8.0.2_build.patch -%ifarch ppc64le -%patch30 -p1 -b crash-8.0.0-5-gdb-cdefs.patch -%endif - +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 %build @@ -126,6 +147,21 @@ cp -p defs.h %{buildroot}%{_includedir}/crash %{_includedir}/* %changelog +* Fri Mar 10 2023 Lianbo Jiang - 8.0.2-4 +- Fix "kmem -n" option to display memory blocks on Linux 6.3-rc1 and later +- gdb: Fix an assertion failure in dw2_find_pc_sect_compunit_symtab() +- Fix for "net -n" option to properly deal with an invalid argument +- Fix C99 compatibility issues in embedded copy of GDB +- Enhance "net" command to display IPv6 address of network interface +- Fix for "search -u" option failing in maple tree kernel +- x86_64: Fix "bt" command on kernels with random_kstack_offset=on +- Fix for "dis" command to correctly display the offset of disassembly code +- Fix for "bt" command unnecessarily printing an exception frame +- Fix for "kmem -i" option to not print invalid values for CACHED +- Fix for "net -s" option to show IPv6 addresses on Linux 3.13 and later +- Fix "kmem -s|-S" not working properly on RHEL8.6 and later +- Fix for "bt" command printing "bogus exception frame" warning + * Tue Feb 07 2023 Lianbo Jiang - 8.0.2-3 - Update to the latest upstream commit <46344aa2f92b>