Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package makedumpfile for openSUSE:Factory checked in at 2021-07-22 22:42:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/makedumpfile (Old) and /work/SRC/openSUSE:Factory/.makedumpfile.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "makedumpfile" Thu Jul 22 22:42:56 2021 rev:81 rq:907436 version:1.6.9 Changes: -------- --- /work/SRC/openSUSE:Factory/makedumpfile/makedumpfile.changes 2021-04-22 18:04:06.110519327 +0200 +++ /work/SRC/openSUSE:Factory/.makedumpfile.new.1899/makedumpfile.changes 2021-07-22 22:43:22.207199048 +0200 @@ -1,0 +2,21 @@ +Sat Jul 10 13:15:50 UTC 2021 - Ferdinand Thiessen <r...@fthiessen.de> + +- Update to 1.6.9 + * Add initial mips64 support + * Support newer kernels up to v5.12 + * x86_64: fix a use-after-free bug in -e option + * arm64: support flipped VA and 52-bit kernel VA + * Add shorthand --show-stats option to show report stats + * Add --dry-run option to prevent writing the dumpfile + * printk: add support for lockless ringbuffer +- Fix rpmlintrc to not be version agnostic +- Refresh makedumpfile-override-libtinfo.patch +- Drop upstream merged + * makedumpfile-printk-add-support-for-lockless-ringbuffer.patch + * makedumpfile-printk-use-committed-finalized-state-value.patch + * makedumpfile-use-uts_namespace.name-offset-VMCOREINFO.patch + * makedumpfile-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch + * makedumpfile-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch + * makedumpfile-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch + +------------------------------------------------------------------- Old: ---- makedumpfile-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch makedumpfile-1.6.8.tar.gz makedumpfile-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch makedumpfile-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch makedumpfile-printk-add-support-for-lockless-ringbuffer.patch makedumpfile-printk-use-committed-finalized-state-value.patch makedumpfile-use-uts_namespace.name-offset-VMCOREINFO.patch New: ---- makedumpfile-1.6.9.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ makedumpfile.spec ++++++ --- /var/tmp/diff_new_pack.QgvnNi/_old 2021-07-22 22:43:23.343197567 +0200 +++ /var/tmp/diff_new_pack.QgvnNi/_new 2021-07-22 22:43:23.343197567 +0200 @@ -25,14 +25,14 @@ %endif # Compatibility cruft -# there is no separate -ltinfo until openSUSE 13.1 +# there is no separate -ltinfo until openSUSE 13.1 / SLE 12 %if 0%{?suse_version} < 1310 && 0%{?sles_version} < 12 %define ncurses_make_opts TINFOLIB=-lncurses %endif # End of compatibility cruft Name: makedumpfile -Version: 1.6.8 +Version: 1.6.9 Release: 0 Summary: Partial kernel dump License: GPL-2.0-only @@ -40,15 +40,9 @@ URL: https://github.com/makedumpfile/makedumpfile Source: https://github.com/makedumpfile/makedumpfile/releases/download/%{version}/%{name}-%{version}.tar.gz Source99: %{name}-rpmlintrc -Patch1: %{name}-override-libtinfo.patch -Patch2: %{name}-ppc64-VA-range-SUSE.patch -Patch3: %{name}-PN_XNUM.patch -Patch4: %{name}-printk-add-support-for-lockless-ringbuffer.patch -Patch5: %{name}-printk-use-committed-finalized-state-value.patch -Patch6: %{name}-use-uts_namespace.name-offset-VMCOREINFO.patch -Patch7: %{name}-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch -Patch8: %{name}-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch -Patch9: %{name}-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch +Patch0: %{name}-override-libtinfo.patch +Patch1: %{name}-ppc64-VA-range-SUSE.patch +Patch2: %{name}-PN_XNUM.patch BuildRequires: libdw-devel BuildRequires: libelf-devel BuildRequires: libeppic-devel @@ -75,7 +69,9 @@ %prep %setup -q -%autopatch -p1 +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 %build export CFLAGS="%{optflags} -fcommon" @@ -97,7 +93,7 @@ install -m 0644 -t %{buildroot}%{_datadir}/%{name}-%{version}/eppic_scripts/ eppic_scripts/* # Compatibility cruft -# there is no %license prior to SLE12 +# there is no %%license prior to SLE12 %if %{undefined _defaultlicensedir} %define license %doc %else ++++++ makedumpfile-1.6.8.tar.gz -> makedumpfile-1.6.9.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/Makefile new/makedumpfile-1.6.9/Makefile --- old/makedumpfile-1.6.8/Makefile 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/Makefile 2021-05-12 07:43:37.000000000 +0200 @@ -1,7 +1,7 @@ # makedumpfile -VERSION=1.6.8 -DATE=16 Nov 2020 +VERSION=1.6.9 +DATE=13 May 2021 # Honour the environment variable CC ifeq ($(strip $CC),) @@ -45,9 +45,9 @@ endif SRC_BASE = makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h -SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c +SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c printk.c OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART)) -SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c +SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c arch/mips64.c OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH)) LIBS = -ldw -lbz2 -ldl -lelf -lz @@ -68,7 +68,7 @@ CFLAGS += -DUSESNAPPY endif -LIBS := -lpthread $(LIBS) +LIBS := $(LIBS) -lpthread try-run = $(shell set -e; \ TMP=".$$$$.tmp"; \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/README new/makedumpfile-1.6.9/README --- old/makedumpfile-1.6.8/README 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/README 2021-05-12 07:43:37.000000000 +0200 @@ -139,6 +139,9 @@ 5.7 | | ** | | | | ** | | -- | | OK | | | 5.8 | | ** | | | | ** | | -- | | OK | | | 5.9 | | ** | | | | ** | | -- | | OK | | | + 5.10 | | ** | | | | ** | | -- | | OK | | | + 5.11 | | ** | | | | ** | | -- | | OK | | | + 5.12 | | ** | | | | ** | | -- | | OK | | | OK : Support. -- : Not support. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/arch/arm64.c new/makedumpfile-1.6.9/arch/arm64.c --- old/makedumpfile-1.6.8/arch/arm64.c 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/arch/arm64.c 2021-05-12 07:43:37.000000000 +0200 @@ -47,6 +47,8 @@ static int lpa_52_bit_support_available; static int pgtable_level; static int va_bits; +static int vabits_actual; +static int flipped_va; static unsigned long kimage_voffset; #define SZ_4K 4096 @@ -58,7 +60,6 @@ #define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) #define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) #define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) -#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52) #define pgd_val(x) ((x).pgd) #define pud_val(x) (pgd_val((x).pgd)) @@ -218,12 +219,20 @@ #define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) #define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * sizeof(pte_t)) +/* + * The linear kernel range starts at the bottom of the virtual address + * space. Testing the top bit for the start of the region is a + * sufficient check and avoids having to worry about the tag. + */ +#define is_linear_addr(addr) (flipped_va ? \ + (!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \ + (!!((unsigned long)(addr) & (1UL << (vabits_actual - 1))))) + static unsigned long long __pa(unsigned long vaddr) { - if (kimage_voffset == NOT_FOUND_NUMBER || - (vaddr >= PAGE_OFFSET)) - return (vaddr - PAGE_OFFSET + info->phys_base); + if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr)) + return ((vaddr & ~PAGE_OFFSET) + info->phys_base); else return (vaddr - kimage_voffset); } @@ -253,6 +262,7 @@ (PAGESIZE() == SZ_64K && va_bits == 42)) { pgtable_level = 2; } else if ((PAGESIZE() == SZ_64K && va_bits == 48) || + (PAGESIZE() == SZ_64K && va_bits == 52) || (PAGESIZE() == SZ_4K && va_bits == 39) || (PAGESIZE() == SZ_16K && va_bits == 47)) { pgtable_level = 3; @@ -263,6 +273,7 @@ PAGESIZE(), va_bits); return FALSE; } + DEBUG_MSG("pgtable_level: %d\n", pgtable_level); return TRUE; } @@ -270,6 +281,9 @@ unsigned long get_kvbase_arm64(void) { + if (flipped_va) + return PAGE_OFFSET; + return (0xffffffffffffffffUL << va_bits); } @@ -345,22 +359,91 @@ return(found ? kallsym : FALSE); } +static int +get_va_bits_from_stext_arm64(void) +{ + ulong _stext; + + _stext = get_stext_symbol(); + if (!_stext) { + ERRMSG("Can't get the symbol of _stext.\n"); + return FALSE; + } + + /* + * Derive va_bits as per arch/arm64/Kconfig. Note that this is a + * best case approximation at the moment, as there can be + * inconsistencies in this calculation (for e.g., for 52-bit + * kernel VA case, the 48th bit is set in * the _stext symbol). + */ + if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) { + va_bits = 48; + } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) { + va_bits = 47; + } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) { + va_bits = 42; + } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) { + va_bits = 39; + } else if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) { + va_bits = 36; + } else { + ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n"); + return FALSE; + } + + DEBUG_MSG("va_bits : %d (guess from _stext)\n", va_bits); + + return TRUE; +} + +static void +get_page_offset_arm64(void) +{ + ulong page_end; + int vabits_min; + + /* + * See arch/arm64/include/asm/memory.h for more details of + * the PAGE_OFFSET calculation. + */ + vabits_min = (va_bits > 48) ? 48 : va_bits; + page_end = -(1UL << (vabits_min - 1)); + + if (SYMBOL(_stext) > page_end) { + flipped_va = TRUE; + info->page_offset = -(1UL << vabits_actual); + } else { + flipped_va = FALSE; + info->page_offset = -(1UL << (vabits_actual - 1)); + } + + DEBUG_MSG("page_offset : %lx (from page_end check)\n", + info->page_offset); +} + int get_machdep_info_arm64(void) { + /* Check if va_bits is still not initialized. If still 0, call + * get_versiondep_info() to initialize the same. + */ + if (!va_bits) + get_versiondep_info_arm64(); + /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */ if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) { info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); + DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits); if (info->max_physmem_bits == 52) lpa_52_bit_support_available = 1; - } else - info->max_physmem_bits = 48; + } else { + if (va_bits == 52) + info->max_physmem_bits = 52; /* just guess */ + else + info->max_physmem_bits = 48; - /* Check if va_bits is still not initialized. If still 0, call - * get_versiondep_info() to initialize the same. - */ - if (!va_bits) - get_versiondep_info_arm64(); + DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits); + } if (!calculate_plat_config()) { ERRMSG("Can't determine platform config values\n"); @@ -371,7 +454,6 @@ info->section_size_bits = SECTIONS_SIZE_BITS; DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); - DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits); DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits); return TRUE; @@ -398,34 +480,43 @@ int get_versiondep_info_arm64(void) { - ulong _stext; - - _stext = get_stext_symbol(); - if (!_stext) { - ERRMSG("Can't get the symbol of _stext.\n"); + if (NUMBER(VA_BITS) != NOT_FOUND_NUMBER) { + va_bits = NUMBER(VA_BITS); + DEBUG_MSG("va_bits : %d (vmcoreinfo)\n", va_bits); + } else if (get_va_bits_from_stext_arm64() == FALSE) { + ERRMSG("Can't determine va_bits.\n"); return FALSE; } - /* Derive va_bits as per arch/arm64/Kconfig */ - if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) { - va_bits = 36; - } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) { - va_bits = 39; - } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) { - va_bits = 42; - } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) { - va_bits = 47; - } else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) { - va_bits = 48; + /* + * See TCR_EL1, Translation Control Register (EL1) register + * description in the ARMv8 Architecture Reference Manual. + * Basically, we can use the TCR_EL1.T1SZ value to determine + * the virtual addressing range supported in the kernel-space + * (i.e. vabits_actual) since Linux 5.9. + */ + if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) { + vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ); + DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual); + } else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) { + /* + * Linux 5.4 through 5.10 have the following linear space: + * 48-bit: 0xffff000000000000 - 0xffff7fffffffffff + * 52-bit: 0xfff0000000000000 - 0xfff7ffffffffffff + * and SYMBOL(mem_section) should be in linear space if + * the kernel is configured with COMFIG_SPARSEMEM_EXTREME=y. + */ + if (SYMBOL(mem_section) & (1UL << (va_bits - 1))) + vabits_actual = 48; + else + vabits_actual = 52; + DEBUG_MSG("vabits_actual : %d (guess from mem_section)\n", vabits_actual); } else { - ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n"); - return FALSE; + vabits_actual = va_bits; + DEBUG_MSG("vabits_actual : %d (same as va_bits)\n", vabits_actual); } - info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); - - DEBUG_MSG("va_bits : %d\n", va_bits); - DEBUG_MSG("page_offset : %lx\n", info->page_offset); + get_page_offset_arm64(); return TRUE; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/arch/mips64.c new/makedumpfile-1.6.9/arch/mips64.c --- old/makedumpfile-1.6.8/arch/mips64.c 1970-01-01 01:00:00.000000000 +0100 +++ new/makedumpfile-1.6.9/arch/mips64.c 2021-05-12 07:43:37.000000000 +0200 @@ -0,0 +1,126 @@ +/* + * mips64.c + * + * Copyright (C) 2021 Loongson Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation (version 2 of the License). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifdef __mips64__ + +#include "../print_info.h" +#include "../elf_info.h" +#include "../makedumpfile.h" + +int +get_phys_base_mips64(void) +{ + info->phys_base = 0ULL; + + DEBUG_MSG("phys_base : %lx\n", info->phys_base); + + return TRUE; +} + +int +get_machdep_info_mips64(void) +{ + info->section_size_bits = _SECTION_SIZE_BITS; + + /* Check if we can get MAX_PHYSMEM_BITS from vmcoreinfo */ + if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) + info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); + else + info->max_physmem_bits = _MAX_PHYSMEM_BITS; + + DEBUG_MSG("max_physmem_bits : %lx\n", info->max_physmem_bits); + DEBUG_MSG("section_size_bits: %lx\n", info->section_size_bits); + + return TRUE; +} + +int +get_versiondep_info_mips64(void) +{ + info->page_offset = 0x9800000000000000ULL; + + DEBUG_MSG("page_offset : %lx\n", info->page_offset); + + return TRUE; +} + +/* + * Translate a virtual address to a physical address by using 3 levels paging. + */ +unsigned long long +vaddr_to_paddr_mips64(unsigned long vaddr) +{ + unsigned long long paddr = NOT_PADDR; + pgd_t *pgda, pgdv; + pmd_t *pmda, pmdv; + pte_t *ptea, ptev; + + /* + * CKSEG0/CKSEG1 + */ + if (vaddr >= 0xffffffff80000000ULL && vaddr < 0xffffffffc0000000ULL) + return vaddr & 0x1fffffffULL; + + /* + * XKPHYS + */ + if (vaddr >= 0x9000000000000000ULL && vaddr < 0xc000000000000000ULL) + return vaddr & ((1ULL << MAX_PHYSMEM_BITS()) - 1); + + if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) { + ERRMSG("Can't get the symbol of swapper_pg_dir.\n"); + return NOT_PADDR; + } + + pgda = pgd_offset(SYMBOL(swapper_pg_dir), vaddr); + if (!readmem(PADDR, (unsigned long long)pgda, &pgdv, sizeof(pgdv))) { + ERRMSG("Can't read pgd\n"); + return NOT_PADDR; + } + + pmda = pmd_offset(&pgdv, vaddr); + if (!readmem(PADDR, (unsigned long long)pmda, &pmdv, sizeof(pmdv))) { + ERRMSG("Can't read pmd\n"); + return NOT_PADDR; + } + + switch (pmdv & (_PAGE_PRESENT|_PAGE_HUGE)) { + case _PAGE_PRESENT: + ptea = pte_offset(&pmdv, vaddr); + /* 64k page */ + if (!readmem(PADDR, (unsigned long long)ptea, &ptev, sizeof(ptev))) { + ERRMSG("Can't read pte\n"); + return NOT_PADDR; + } + + if (!(ptev & _PAGE_PRESENT)) { + ERRMSG("Can't get a valid pte.\n"); + return NOT_PADDR; + } else { + paddr = PAGEBASE(ptev) + (vaddr & (PAGESIZE() - 1)); + } + break; + case _PAGE_PRESENT|_PAGE_HUGE: + paddr = (pmdv & PMD_MASK) + (vaddr & (PMD_SIZE - 1)); + break; + } + + return paddr; +} + +#endif /* mips64 */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/arch/x86_64.c new/makedumpfile-1.6.9/arch/x86_64.c --- old/makedumpfile-1.6.8/arch/x86_64.c 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/arch/x86_64.c 2021-05-12 07:43:37.000000000 +0200 @@ -943,9 +943,11 @@ vmapp->rep_pfn_start = cur->rep_pfn_start; vmapp->rep_pfn_end = cur->rep_pfn_end; cur = cur->next; - free(cur->prev); + if (cur->prev != vmaphead) + free(cur->prev); i++; } while (cur != vmaphead); + free(vmaphead); nr_gvmem_pfns = i; return TRUE; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/dwarf_info.c new/makedumpfile-1.6.9/dwarf_info.c --- old/makedumpfile-1.6.8/dwarf_info.c 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/dwarf_info.c 2021-05-12 07:43:37.000000000 +0200 @@ -614,6 +614,7 @@ { int tag; const char *name; + Dwarf_Die die_type; /* * If we get to here then we don't have any more @@ -622,9 +623,31 @@ do { tag = dwarf_tag(die); name = dwarf_diename(die); - if ((tag != DW_TAG_structure_type) || (!name) - || strcmp(name, dwarf_info.struct_name)) + if ((!name) || strcmp(name, dwarf_info.struct_name)) continue; + + if (tag == DW_TAG_typedef) { + if (!get_die_type(die, &die_type)) { + ERRMSG("Can't get CU die of DW_AT_type.\n"); + break; + } + + /* Resolve typedefs of typedefs. */ + while ((tag = dwarf_tag(&die_type)) == DW_TAG_typedef) { + if (!get_die_type(&die_type, &die_type)) { + ERRMSG("Can't get CU die of DW_AT_type.\n"); + return; + } + } + + if (tag != DW_TAG_structure_type) + continue; + die = &die_type; + + } else if (tag != DW_TAG_structure_type) { + continue; + } + /* * Skip if DW_AT_byte_size is not included. */ @@ -740,6 +763,15 @@ ERRMSG("Can't get CU die of DW_AT_type.\n"); break; } + + /* Resolve typedefs of typedefs. */ + while ((tag = dwarf_tag(&die_type)) == DW_TAG_typedef) { + if (!get_die_type(&die_type, &die_type)) { + ERRMSG("Can't get CU die of DW_AT_type.\n"); + return; + } + } + dwarf_info.struct_size = dwarf_bytesize(&die_type); if (dwarf_info.struct_size <= 0) continue; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/elf_info.c new/makedumpfile-1.6.9/elf_info.c --- old/makedumpfile-1.6.8/elf_info.c 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/elf_info.c 2021-05-12 07:43:37.000000000 +0200 @@ -698,55 +698,6 @@ return TRUE; } -int -get_elf_loads(int fd, char *filename) -{ - int i, j, phnum, elf_format; - Elf64_Phdr phdr; - - /* - * Check ELF64 or ELF32. - */ - elf_format = check_elf_format(fd, filename, &phnum, &num_pt_loads); - if (elf_format == ELF64) - flags_memory |= MEMORY_ELF64; - else if (elf_format != ELF32) - return FALSE; - - if (!num_pt_loads) { - ERRMSG("Can't get the number of PT_LOAD.\n"); - return FALSE; - } - - /* - * The below file information will be used as /proc/vmcore. - */ - fd_memory = fd; - name_memory = filename; - - pt_loads = calloc(sizeof(struct pt_load_segment), num_pt_loads); - if (pt_loads == NULL) { - ERRMSG("Can't allocate memory for the PT_LOAD. %s\n", - strerror(errno)); - return FALSE; - } - for (i = 0, j = 0; i < phnum; i++) { - if (!get_phdr_memory(i, &phdr)) - return FALSE; - - if (phdr.p_type != PT_LOAD) - continue; - - if (j >= num_pt_loads) - return FALSE; - if (!dump_Elf_load(&phdr, j)) - return FALSE; - j++; - } - - return TRUE; -} - static int exclude_segment(struct pt_load_segment **pt_loads, unsigned int *num_pt_loads, uint64_t start, uint64_t end) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/elf_info.h new/makedumpfile-1.6.9/elf_info.h --- old/makedumpfile-1.6.8/elf_info.h 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/elf_info.h 2021-05-12 07:43:37.000000000 +0200 @@ -44,7 +44,6 @@ int get_elf32_ehdr(int fd, char *filename, Elf32_Ehdr *ehdr); int get_elf_info(int fd, char *filename); void free_elf_info(void); -int get_elf_loads(int fd, char *filename); int set_kcore_vmcoreinfo(uint64_t vmcoreinfo_addr, uint64_t vmcoreinfo_len); int get_kcore_dump_loads(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/makedumpfile.8 new/makedumpfile-1.6.9/makedumpfile.8 --- old/makedumpfile-1.6.8/makedumpfile.8 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/makedumpfile.8 2021-05-12 07:43:37.000000000 +0200 @@ -1,4 +1,4 @@ -.TH MAKEDUMPFILE 8 "16 Nov 2020" "makedumpfile v1.6.8" "Linux System Administrator's Manual" +.TH MAKEDUMPFILE 8 "13 May 2021" "makedumpfile v1.6.9" "Linux System Administrator's Manual" .SH NAME makedumpfile \- make a small dumpfile of kdump .SH SYNOPSIS @@ -637,6 +637,17 @@ Only check whether the command-line parameters are valid or not, and exit. Preferable to be given as the first parameter. +.TP +\fB\-\-dry-run\fR +Do not write the output dump file while still performing operations specified +by other options. +This option cannot be used with the --dump-dmesg, --reassemble and -g options. + +.TP +\fB\-\-show-stats\fR +Display report messages. This is an alternative to enabling bit 4 in the level +provided to --message-level. + .SH ENVIRONMENT VARIABLES .TP 8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/makedumpfile.c new/makedumpfile-1.6.9/makedumpfile.c --- old/makedumpfile-1.6.8/makedumpfile.c 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/makedumpfile.c 2021-05-12 07:43:37.000000000 +0200 @@ -48,6 +48,8 @@ static unsigned long long cache_hit; static unsigned long long cache_miss; +static unsigned long long write_bytes; + static void first_cycle(mdf_pfn_t start, mdf_pfn_t max, struct cycle *cycle) { cycle->start_pfn = round(start, info->pfn_cyclic); @@ -1159,7 +1161,10 @@ if (SYMBOL(system_utsname) != NOT_FOUND_SYMBOL) { utsname = SYMBOL(system_utsname); } else if (SYMBOL(init_uts_ns) != NOT_FOUND_SYMBOL) { - utsname = SYMBOL(init_uts_ns) + sizeof(int); + if (OFFSET(uts_namespace.name) != NOT_FOUND_STRUCTURE) + utsname = SYMBOL(init_uts_ns) + OFFSET(uts_namespace.name); + else + utsname = SYMBOL(init_uts_ns) + sizeof(int); } else { ERRMSG("Can't get the symbol of system_utsname.\n"); return FALSE; @@ -1369,6 +1374,8 @@ if (info->flag_flatten) { fd = STDOUT_FILENO; info->name_dumpfile = filename_stdout; + } else if (info->flag_dry_run) { + fd = -1; } else if ((fd = open(info->name_dumpfile, open_flags, S_IRUSR|S_IWUSR)) < 0) { ERRMSG("Can't open the dump file(%s). %s\n", @@ -1555,6 +1562,7 @@ SYMBOL_INIT(node_data, "node_data"); SYMBOL_INIT(pgdat_list, "pgdat_list"); SYMBOL_INIT(contig_page_data, "contig_page_data"); + SYMBOL_INIT(prb, "prb"); SYMBOL_INIT(log_buf, "log_buf"); SYMBOL_INIT(log_buf_len, "log_buf_len"); SYMBOL_INIT(log_end, "log_end"); @@ -1971,16 +1979,47 @@ OFFSET_INIT(elf64_phdr.p_memsz, "elf64_phdr", "p_memsz"); SIZE_INIT(printk_log, "printk_log"); - if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { + SIZE_INIT(printk_ringbuffer, "printk_ringbuffer"); + if ((SIZE(printk_ringbuffer) != NOT_FOUND_STRUCTURE)) { + info->flag_use_printk_ringbuffer = TRUE; + info->flag_use_printk_log = FALSE; + + OFFSET_INIT(printk_ringbuffer.desc_ring, "printk_ringbuffer", "desc_ring"); + OFFSET_INIT(printk_ringbuffer.text_data_ring, "printk_ringbuffer", "text_data_ring"); + + OFFSET_INIT(prb_desc_ring.count_bits, "prb_desc_ring", "count_bits"); + OFFSET_INIT(prb_desc_ring.descs, "prb_desc_ring", "descs"); + OFFSET_INIT(prb_desc_ring.infos, "prb_desc_ring", "infos"); + OFFSET_INIT(prb_desc_ring.head_id, "prb_desc_ring", "head_id"); + OFFSET_INIT(prb_desc_ring.tail_id, "prb_desc_ring", "tail_id"); + + SIZE_INIT(prb_desc, "prb_desc"); + OFFSET_INIT(prb_desc.state_var, "prb_desc", "state_var"); + OFFSET_INIT(prb_desc.text_blk_lpos, "prb_desc", "text_blk_lpos"); + + OFFSET_INIT(prb_data_blk_lpos.begin, "prb_data_blk_lpos", "begin"); + OFFSET_INIT(prb_data_blk_lpos.next, "prb_data_blk_lpos", "next"); + + OFFSET_INIT(prb_data_ring.size_bits, "prb_data_ring", "size_bits"); + OFFSET_INIT(prb_data_ring.data, "prb_data_ring", "data"); + + SIZE_INIT(printk_info, "printk_info"); + OFFSET_INIT(printk_info.ts_nsec, "printk_info", "ts_nsec"); + OFFSET_INIT(printk_info.text_len, "printk_info", "text_len"); + + OFFSET_INIT(atomic_long_t.counter, "atomic_long_t", "counter"); + } else if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { /* * In kernel 3.11-rc4 the log structure name was renamed * to "printk_log". */ + info->flag_use_printk_ringbuffer = FALSE; info->flag_use_printk_log = TRUE; OFFSET_INIT(printk_log.ts_nsec, "printk_log", "ts_nsec"); OFFSET_INIT(printk_log.len, "printk_log", "len"); OFFSET_INIT(printk_log.text_len, "printk_log", "text_len"); } else { + info->flag_use_printk_ringbuffer = FALSE; info->flag_use_printk_log = FALSE; SIZE_INIT(printk_log, "log"); OFFSET_INIT(printk_log.ts_nsec, "log", "ts_nsec"); @@ -2008,6 +2047,11 @@ SIZE_INIT(cpu_spec, "cpu_spec"); OFFSET_INIT(cpu_spec.mmu_features, "cpu_spec", "mmu_features"); + /* + * Get offsets of the uts_namespace's members. + */ + OFFSET_INIT(uts_namespace.name, "uts_namespace", "name"); + return TRUE; } @@ -2077,7 +2121,10 @@ if (SYMBOL(system_utsname) != NOT_FOUND_SYMBOL) { utsname = SYMBOL(system_utsname); } else if (SYMBOL(init_uts_ns) != NOT_FOUND_SYMBOL) { - utsname = SYMBOL(init_uts_ns) + sizeof(int); + if (OFFSET(uts_namespace.name) != NOT_FOUND_STRUCTURE) + utsname = SYMBOL(init_uts_ns) + OFFSET(uts_namespace.name); + else + utsname = SYMBOL(init_uts_ns) + sizeof(int); } else { ERRMSG("Can't get the symbol of system_utsname.\n"); return FALSE; @@ -2191,6 +2238,7 @@ WRITE_SYMBOL("node_data", node_data); WRITE_SYMBOL("pgdat_list", pgdat_list); WRITE_SYMBOL("contig_page_data", contig_page_data); + WRITE_SYMBOL("prb", prb); WRITE_SYMBOL("log_buf", log_buf); WRITE_SYMBOL("log_buf_len", log_buf_len); WRITE_SYMBOL("log_end", log_end); @@ -2222,7 +2270,11 @@ WRITE_STRUCTURE_SIZE("node_memblk_s", node_memblk_s); WRITE_STRUCTURE_SIZE("nodemask_t", nodemask_t); WRITE_STRUCTURE_SIZE("pageflags", pageflags); - if (info->flag_use_printk_log) + if (info->flag_use_printk_ringbuffer) { + WRITE_STRUCTURE_SIZE("printk_ringbuffer", printk_ringbuffer); + WRITE_STRUCTURE_SIZE("prb_desc", prb_desc); + WRITE_STRUCTURE_SIZE("printk_info", printk_info); + } else if (info->flag_use_printk_log) WRITE_STRUCTURE_SIZE("printk_log", printk_log); else WRITE_STRUCTURE_SIZE("log", printk_log); @@ -2268,7 +2320,30 @@ WRITE_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr); WRITE_MEMBER_OFFSET("vmap_area.va_start", vmap_area.va_start); WRITE_MEMBER_OFFSET("vmap_area.list", vmap_area.list); - if (info->flag_use_printk_log) { + if (info->flag_use_printk_ringbuffer) { + WRITE_MEMBER_OFFSET("printk_ringbuffer.desc_ring", printk_ringbuffer.desc_ring); + WRITE_MEMBER_OFFSET("printk_ringbuffer.text_data_ring", printk_ringbuffer.text_data_ring); + + WRITE_MEMBER_OFFSET("prb_desc_ring.count_bits", prb_desc_ring.count_bits); + WRITE_MEMBER_OFFSET("prb_desc_ring.descs", prb_desc_ring.descs); + WRITE_MEMBER_OFFSET("prb_desc_ring.infos", prb_desc_ring.infos); + WRITE_MEMBER_OFFSET("prb_desc_ring.head_id", prb_desc_ring.head_id); + WRITE_MEMBER_OFFSET("prb_desc_ring.tail_id", prb_desc_ring.tail_id); + + WRITE_MEMBER_OFFSET("prb_desc.state_var", prb_desc.state_var); + WRITE_MEMBER_OFFSET("prb_desc.text_blk_lpos", prb_desc.text_blk_lpos); + + WRITE_MEMBER_OFFSET("prb_data_blk_lpos.begin", prb_data_blk_lpos.begin); + WRITE_MEMBER_OFFSET("prb_data_blk_lpos.next", prb_data_blk_lpos.next); + + WRITE_MEMBER_OFFSET("prb_data_ring.size_bits", prb_data_ring.size_bits); + WRITE_MEMBER_OFFSET("prb_data_ring.data", prb_data_ring.data); + + WRITE_MEMBER_OFFSET("printk_info.ts_nsec", printk_info.ts_nsec); + WRITE_MEMBER_OFFSET("printk_info.text_len", printk_info.text_len); + + WRITE_MEMBER_OFFSET("atomic_long_t.counter", atomic_long_t.counter); + } else if (info->flag_use_printk_log) { WRITE_MEMBER_OFFSET("printk_log.ts_nsec", printk_log.ts_nsec); WRITE_MEMBER_OFFSET("printk_log.len", printk_log.len); WRITE_MEMBER_OFFSET("printk_log.text_len", printk_log.text_len); @@ -2284,6 +2359,7 @@ WRITE_MEMBER_OFFSET("vmemmap_backing.list", vmemmap_backing.list); WRITE_MEMBER_OFFSET("mmu_psize_def.shift", mmu_psize_def.shift); WRITE_MEMBER_OFFSET("cpu_spec.mmu_features", cpu_spec.mmu_features); + WRITE_MEMBER_OFFSET("uts_namespace.name", uts_namespace.name); if (SYMBOL(node_data) != NOT_FOUND_SYMBOL) WRITE_ARRAY_LENGTH("node_data", node_data); @@ -2323,6 +2399,7 @@ WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR); #ifdef __aarch64__ WRITE_NUMBER("VA_BITS", VA_BITS); + /* WRITE_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); should not exists */ WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); #endif @@ -2606,6 +2683,7 @@ READ_SYMBOL("node_data", node_data); READ_SYMBOL("pgdat_list", pgdat_list); READ_SYMBOL("contig_page_data", contig_page_data); + READ_SYMBOL("prb", prb); READ_SYMBOL("log_buf", log_buf); READ_SYMBOL("log_buf_len", log_buf_len); READ_SYMBOL("log_end", log_end); @@ -2682,14 +2760,46 @@ READ_MEMBER_OFFSET("vmemmap_backing.list", vmemmap_backing.list); READ_MEMBER_OFFSET("mmu_psize_def.shift", mmu_psize_def.shift); READ_MEMBER_OFFSET("cpu_spec.mmu_features", cpu_spec.mmu_features); + READ_MEMBER_OFFSET("uts_namespace.name", uts_namespace.name); READ_STRUCTURE_SIZE("printk_log", printk_log); - if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { + READ_STRUCTURE_SIZE("printk_ringbuffer", printk_ringbuffer); + if (SIZE(printk_ringbuffer) != NOT_FOUND_STRUCTURE) { + info->flag_use_printk_ringbuffer = TRUE; + info->flag_use_printk_log = FALSE; + + READ_MEMBER_OFFSET("printk_ringbuffer.desc_ring", printk_ringbuffer.desc_ring); + READ_MEMBER_OFFSET("printk_ringbuffer.text_data_ring", printk_ringbuffer.text_data_ring); + + READ_MEMBER_OFFSET("prb_desc_ring.count_bits", prb_desc_ring.count_bits); + READ_MEMBER_OFFSET("prb_desc_ring.descs", prb_desc_ring.descs); + READ_MEMBER_OFFSET("prb_desc_ring.infos", prb_desc_ring.infos); + READ_MEMBER_OFFSET("prb_desc_ring.head_id", prb_desc_ring.head_id); + READ_MEMBER_OFFSET("prb_desc_ring.tail_id", prb_desc_ring.tail_id); + + READ_STRUCTURE_SIZE("prb_desc", prb_desc); + READ_MEMBER_OFFSET("prb_desc.state_var", prb_desc.state_var); + READ_MEMBER_OFFSET("prb_desc.text_blk_lpos", prb_desc.text_blk_lpos); + + READ_MEMBER_OFFSET("prb_data_blk_lpos.begin", prb_data_blk_lpos.begin); + READ_MEMBER_OFFSET("prb_data_blk_lpos.next", prb_data_blk_lpos.next); + + READ_MEMBER_OFFSET("prb_data_ring.size_bits", prb_data_ring.size_bits); + READ_MEMBER_OFFSET("prb_data_ring.data", prb_data_ring.data); + + READ_STRUCTURE_SIZE("printk_info", printk_info); + READ_MEMBER_OFFSET("printk_info.ts_nsec", printk_info.ts_nsec); + READ_MEMBER_OFFSET("printk_info.text_len", printk_info.text_len); + + READ_MEMBER_OFFSET("atomic_long_t.counter", atomic_long_t.counter); + } else if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { + info->flag_use_printk_ringbuffer = FALSE; info->flag_use_printk_log = TRUE; READ_MEMBER_OFFSET("printk_log.ts_nsec", printk_log.ts_nsec); READ_MEMBER_OFFSET("printk_log.len", printk_log.len); READ_MEMBER_OFFSET("printk_log.text_len", printk_log.text_len); } else { + info->flag_use_printk_ringbuffer = FALSE; info->flag_use_printk_log = FALSE; READ_STRUCTURE_SIZE("log", printk_log); READ_MEMBER_OFFSET("log.ts_nsec", printk_log.ts_nsec); @@ -2729,6 +2839,7 @@ READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE); #ifdef __aarch64__ READ_NUMBER("VA_BITS", VA_BITS); + READ_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); #endif @@ -4606,6 +4717,11 @@ { int status, written_size = 0; + write_bytes += buf_size; + + if (info->flag_dry_run) + return TRUE; + while (written_size < buf_size) { status = write(fd, buf + written_size, buf_size - written_size); @@ -4643,13 +4759,12 @@ } if (!write_and_check_space(fd, &fdh, sizeof(fdh), file_name)) return FALSE; - } else { - if (lseek(fd, offset, SEEK_SET) == failed) { - ERRMSG("Can't seek the dump file(%s). %s\n", - file_name, strerror(errno)); - return FALSE; - } + } else if (!info->flag_dry_run && + lseek(fd, offset, SEEK_SET) == failed) { + ERRMSG("Can't seek the dump file(%s). %s\n", file_name, strerror(errno)); + return FALSE; } + if (!write_and_check_space(fd, buf, buf_size, file_name)) return FALSE; @@ -5286,6 +5401,9 @@ if (!initial()) return FALSE; + if ((SYMBOL(prb) != NOT_FOUND_SYMBOL)) + return dump_lockless_dmesg(); + if ((SYMBOL(log_buf) == NOT_FOUND_SYMBOL) || (SYMBOL(log_buf_len) == NOT_FOUND_SYMBOL)) { ERRMSG("Can't find some symbols for log_buf.\n"); @@ -9004,7 +9122,7 @@ void close_dump_file(void) { - if (info->flag_flatten) + if (info->flag_flatten || info->flag_dry_run) return; if (close(info->fd_dumpfile) < 0) @@ -9888,6 +10006,7 @@ REPORT_MSG("Memory Hole : 0x%016llx\n", pfn_memhole); REPORT_MSG("--------------------------------------------------\n"); REPORT_MSG("Total pages : 0x%016llx\n", info->max_mapnr); + REPORT_MSG("Write bytes : %llu\n", write_bytes); REPORT_MSG("\n"); REPORT_MSG("Cache hit: %lld, miss: %lld", cache_hit, cache_miss); if (cache_hit + cache_miss) @@ -10877,6 +10996,11 @@ return FALSE; + if (info->flag_dry_run) { + MSG("--dry-run cannot be used with -g.\n"); + return FALSE; + } + return TRUE; } @@ -10921,6 +11045,11 @@ || info->flag_exclude_xen_dom || info->flag_split) return FALSE; + if (info->flag_dry_run) { + MSG("--dry-run cannot be used with --reassemble.\n"); + return FALSE; + } + if ((info->splitting_info = malloc(sizeof(struct splitting_info) * info->num_dumpfile)) == NULL) { @@ -10949,6 +11078,11 @@ || (info->flag_read_vmcoreinfo && info->name_xen_syms)) return FALSE; + if (info->flag_dry_run && info->flag_dmesg) { + MSG("--dry-run cannot be used with --dump-dmesg.\n"); + return FALSE; + } + if (info->flag_flatten && info->flag_split) return FALSE; @@ -11318,6 +11452,7 @@ { uint64_t vmcoreinfo_addr, vmcoreinfo_len; struct cycle cycle = {0}; + int vmcoreinfo = FALSE; if (!is_crashkernel_mem_reserved()) { ERRMSG("No memory is reserved for crashkernel!\n"); @@ -11329,9 +11464,22 @@ if (!open_files_for_creating_dumpfile()) return FALSE; - if (!get_elf_loads(info->fd_memory, info->name_memory)) + if (!get_elf_info(info->fd_memory, info->name_memory)) return FALSE; + /* + * /proc/kcore on Linux 4.19 and later kernels have vmcoreinfo note in + * NOTE segment. See commit 23c85094fe18. + */ + if (has_vmcoreinfo()) { + off_t offset; + unsigned long size; + + get_vmcoreinfo(&offset, &size); + vmcoreinfo = read_vmcoreinfo_from_vmcore(offset, size, FALSE); + DEBUG_MSG("Read vmcoreinfo from NOTE segment: %d\n", vmcoreinfo); + } + if (!get_page_offset()) return FALSE; @@ -11339,11 +11487,13 @@ if (!get_phys_base()) return FALSE; - if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len)) - return FALSE; + if (!vmcoreinfo) { + if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len)) + return FALSE; - if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len)) - return FALSE; + if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len)) + return FALSE; + } if (!initial()) return FALSE; @@ -11412,13 +11562,15 @@ {"work-dir", required_argument, NULL, OPT_WORKING_DIR}, {"num-threads", required_argument, NULL, OPT_NUM_THREADS}, {"check-params", no_argument, NULL, OPT_CHECK_PARAMS}, + {"dry-run", no_argument, NULL, OPT_DRY_RUN}, + {"show-stats", no_argument, NULL, OPT_SHOW_STATS}, {0, 0, 0, 0} }; int main(int argc, char *argv[]) { - int i, opt, flag_debug = FALSE; + int i, opt, flag_debug = FALSE, flag_show_stats = FALSE; if ((info = calloc(1, sizeof(struct DumpInfo))) == NULL) { ERRMSG("Can't allocate memory for the pagedesc cache. %s.\n", @@ -11578,6 +11730,12 @@ info->flag_check_params = TRUE; message_level = DEFAULT_MSG_LEVEL; break; + case OPT_DRY_RUN: + info->flag_dry_run = TRUE; + break; + case OPT_SHOW_STATS: + flag_show_stats = TRUE; + break; case '?': MSG("Commandline parameter is invalid.\n"); MSG("Try `makedumpfile --help' for more information.\n"); @@ -11587,6 +11745,9 @@ if (flag_debug) message_level |= ML_PRINT_DEBUG_MSG; + if (flag_show_stats) + message_level |= ML_PRINT_REPORT_MSG; + if (info->flag_check_params) /* suppress debugging messages */ message_level = DEFAULT_MSG_LEVEL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/makedumpfile.conf.5 new/makedumpfile-1.6.9/makedumpfile.conf.5 --- old/makedumpfile-1.6.8/makedumpfile.conf.5 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/makedumpfile.conf.5 2021-05-12 07:43:37.000000000 +0200 @@ -1,4 +1,4 @@ -.TH MAKEDUMPFILE.CONF 5 "16 Nov 2020" "makedumpfile v1.6.8" "Linux System Administrator's Manual" +.TH MAKEDUMPFILE.CONF 5 "13 May 2021" "makedumpfile v1.6.9" "Linux System Administrator's Manual" .SH NAME makedumpfile.conf \- The filter configuration file for makedumpfile(8). .SH DESCRIPTION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/makedumpfile.h new/makedumpfile-1.6.9/makedumpfile.h --- old/makedumpfile-1.6.8/makedumpfile.h 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/makedumpfile.h 2021-05-12 07:43:37.000000000 +0200 @@ -495,7 +495,7 @@ #define KVER_MIN_SHIFT 16 #define KERNEL_VERSION(x,y,z) (((x) << KVER_MAJ_SHIFT) | ((y) << KVER_MIN_SHIFT) | (z)) #define OLDEST_VERSION KERNEL_VERSION(2, 6, 15) /* linux-2.6.15 */ -#define LATEST_VERSION KERNEL_VERSION(5, 9, 4) /* linux-5.9.4 */ +#define LATEST_VERSION KERNEL_VERSION(5, 12, 1) /* linux-5.12.1 */ /* * vmcoreinfo in /proc/vmcore @@ -958,6 +958,39 @@ #endif /* sparc64 */ +#ifdef __mips64__ /* mips64 */ +#define KVBASE PAGE_OFFSET +#define _SECTION_SIZE_BITS (28) +#define _MAX_PHYSMEM_BITS (48) +#define _PAGE_PRESENT (1 << 0) +#define _PAGE_HUGE (1 << 4) + +typedef unsigned long pte_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t; + +#define PAGE_MASK (~(PAGESIZE() - 1)) +#define PMD_MASK (~(PMD_SIZE - 1)) +#define PMD_SHIFT ((PAGESHIFT() - 3) * 2 + 3) +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PGDIR_SHIFT ((PAGESHIFT() - 3) * 3 + 3) +#define PTRS_PER_PTE (1 << (PAGESHIFT() - 3)) +#define PTRS_PER_PMD PTRS_PER_PTE +#define PTRS_PER_PGD PTRS_PER_PTE + +#define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) +#define pmd_page_paddr(pmd) (pmd & (int32_t)PAGE_MASK) +#define pte_offset(dir, vaddr) ((pte_t *)pmd_page_paddr((*dir)) + pte_index(vaddr)) + +#define pmd_index(vaddr) (((vaddr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) +#define pgd_page_paddr(pgd) (pgd & (int32_t)PAGE_MASK) +#define pmd_offset(pgd, vaddr) ((pmd_t *)pgd_page_paddr((*pgd)) + pmd_index(vaddr)) + +#define pgd_index(vaddr) (((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) +#define pgd_offset(pgdir, vaddr) ((pgd_t *)(pgdir) + pgd_index(vaddr)) + +#endif /* mips64 */ + /* * The function of dependence on machine */ @@ -1106,12 +1139,29 @@ #define get_machdep_info() TRUE #define get_phys_base() get_phys_base_sparc64() #define get_versiondep_info() get_versiondep_info_sparc64() +#define get_kaslr_offset(X) stub_false() #define vaddr_to_paddr(X) vaddr_to_paddr_sparc64(X) #define paddr_to_vaddr(X) paddr_to_vaddr_general(X) #define is_phys_addr(X) stub_true_ul(X) #define arch_crashkernel_mem_size() stub_false() #endif /* sparc64 */ +#ifdef __mips64__ /* mips64 */ +int get_phys_base_mips64(void); +int get_machdep_info_mips64(void); +int get_versiondep_info_mips64(void); +unsigned long long vaddr_to_paddr_mips64(unsigned long vaddr); +#define find_vmemmap() stub_false() +#define get_phys_base() get_phys_base_mips64() +#define get_machdep_info() get_machdep_info_mips64() +#define get_versiondep_info() get_versiondep_info_mips64() +#define get_kaslr_offset(X) stub_false() +#define vaddr_to_paddr(X) vaddr_to_paddr_mips64(X) +#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) +#define is_phys_addr(X) stub_true_ul(X) +#define arch_crashkernel_mem_size() stub_false() +#endif /* mips64 */ + typedef unsigned long long mdf_pfn_t; #ifndef ARCH_PFN_OFFSET @@ -1317,10 +1367,12 @@ int flag_partial_dmesg; /* dmesg dump only from the last cleared index*/ int flag_mem_usage; /*show the page number of memory in different use*/ int flag_use_printk_log; /* did we read printk_log symbol name? */ + int flag_use_printk_ringbuffer; /* using lockless printk ringbuffer? */ int flag_nospace; /* the flag of "No space on device" error */ int flag_vmemmap; /* kernel supports vmemmap address space */ int flag_excludevm; /* -e - excluding unused vmemmap pages */ int flag_use_count; /* _refcount is named _count in struct page */ + int flag_dry_run; /* do not create a vmcore file */ unsigned long vaddr_for_vtop; /* virtual address for debugging */ long page_size; /* size of page */ long page_shift; @@ -1602,6 +1654,7 @@ unsigned long long node_data; unsigned long long pgdat_list; unsigned long long contig_page_data; + unsigned long long prb; unsigned long long log_buf; unsigned long long log_buf_len; unsigned long long log_end; @@ -1690,6 +1743,13 @@ long printk_log; /* + * for lockless printk ringbuffer + */ + long printk_ringbuffer; + long prb_desc; + long printk_info; + + /* * for Xen extraction */ long page_info; @@ -1719,6 +1779,8 @@ long cpu_spec; long pageflags; + + long uts_namespace; }; struct offset_table { @@ -1865,6 +1927,52 @@ } printk_log; /* + * for lockless printk ringbuffer + */ + struct printk_ringbuffer_s { + long desc_ring; + long text_data_ring; + long fail; + } printk_ringbuffer; + + struct prb_desc_ring_s { + long count_bits; + long descs; + long infos; + long head_id; + long tail_id; + } prb_desc_ring; + + struct prb_desc_s { + long state_var; + long text_blk_lpos; + } prb_desc; + + struct prb_data_blk_lpos_s { + long begin; + long next; + } prb_data_blk_lpos; + + struct printk_info_s { + long seq; + long ts_nsec; + long text_len; + long caller_id; + long dev_info; + } printk_info; + + struct prb_data_ring_s { + long size_bits; + long data; + long head_lpos; + long tail_lpos; + } prb_data_ring; + + struct atomic_long_t_s { + long counter; + } atomic_long_t; + + /* * symbols on ppc64 arch */ struct mmu_psize_def_s { @@ -1880,6 +1988,10 @@ struct cpu_spec_s { long mmu_features; } cpu_spec; + + struct uts_namespace_s { + long name; + } uts_namespace; }; /* @@ -1938,6 +2050,7 @@ long KERNEL_IMAGE_SIZE; #ifdef __aarch64__ long VA_BITS; + long TCR_EL1_T1SZ; unsigned long PHYS_OFFSET; unsigned long kimage_voffset; #endif @@ -2167,6 +2280,12 @@ #define get_xen_info_arch(X) FALSE #endif /* sparc64 */ +#ifdef __mips64__ /* mips64 */ +#define kvtop_xen(X) FALSE +#define get_xen_basic_info_arch(X) FALSE +#define get_xen_info_arch(X) FALSE +#endif /* mips64 */ + struct cycle { mdf_pfn_t start_pfn; mdf_pfn_t end_pfn; @@ -2364,6 +2483,8 @@ #define OPT_NUM_THREADS OPT_START+16 #define OPT_PARTIAL_DMESG OPT_START+17 #define OPT_CHECK_PARAMS OPT_START+18 +#define OPT_DRY_RUN OPT_START+19 +#define OPT_SHOW_STATS OPT_START+20 /* * Function Prototype. @@ -2390,4 +2511,7 @@ int decimal(char *s, int count); int file_exists(char *file); +int open_dump_file(void); +int dump_lockless_dmesg(void); + #endif /* MAKEDUMPFILE_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/makedumpfile.spec new/makedumpfile-1.6.9/makedumpfile.spec --- old/makedumpfile-1.6.8/makedumpfile.spec 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/makedumpfile.spec 2021-05-12 07:43:37.000000000 +0200 @@ -1,6 +1,6 @@ Name: makedumpfile Summary: makedumpfile package -Version: 1.6.8 +Version: 1.6.9 Release: 1 Group: Applications/Text License: GPL diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/print_info.c new/makedumpfile-1.6.9/print_info.c --- old/makedumpfile-1.6.8/print_info.c 2020-11-16 01:29:37.000000000 +0100 +++ new/makedumpfile-1.6.9/print_info.c 2021-05-12 07:43:37.000000000 +0200 @@ -308,6 +308,14 @@ MSG(" the crashkernel range, then calculates the page number of different kind per\n"); MSG(" vmcoreinfo. So currently /proc/kcore need be specified explicitly.\n"); MSG("\n"); + MSG(" [--dry-run]:\n"); + MSG(" Do not write the output dump file while still performing operations specified\n"); + MSG(" by other options. This option cannot be used with --dump-dmesg, --reassemble\n"); + MSG(" and -g options.\n"); + MSG("\n"); + MSG(" [--show-stats]:\n"); + MSG(" Set message-level to print report messages\n"); + MSG("\n"); MSG(" [-D]:\n"); MSG(" Print debugging message.\n"); MSG("\n"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.8/printk.c new/makedumpfile-1.6.9/printk.c --- old/makedumpfile-1.6.8/printk.c 1970-01-01 01:00:00.000000000 +0100 +++ new/makedumpfile-1.6.9/printk.c 2021-05-12 07:43:37.000000000 +0200 @@ -0,0 +1,241 @@ +#include "makedumpfile.h" +#include <ctype.h> + +/* convenience struct for passing many values to helper functions */ +struct prb_map { + char *prb; + + char *desc_ring; + unsigned long desc_ring_count; + char *descs; + char *infos; + + char *text_data_ring; + unsigned long text_data_ring_size; + char *text_data; +}; + +/* + * desc_state and DESC_* definitions taken from kernel source: + * + * kernel/printk/printk_ringbuffer.h + */ + +/* The possible responses of a descriptor state-query. */ +enum desc_state { + desc_miss = -1, /* ID mismatch (pseudo state) */ + desc_reserved = 0x0, /* reserved, in use by writer */ + desc_committed = 0x1, /* committed by writer, could get reopened */ + desc_finalized = 0x2, /* committed, no further modification allowed */ + desc_reusable = 0x3, /* free, not yet used by any writer */ +}; + +#define DESC_SV_BITS (sizeof(unsigned long) * 8) +#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2) +#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT) +#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT)) +#define DESC_ID_MASK (~DESC_FLAGS_MASK) +#define DESC_ID(sv) ((sv) & DESC_ID_MASK) + +/* + * get_desc_state() taken from kernel source: + * + * kernel/printk/printk_ringbuffer.c + */ + +/* Query the state of a descriptor. */ +static enum desc_state get_desc_state(unsigned long id, + unsigned long state_val) +{ + if (id != DESC_ID(state_val)) + return desc_miss; + + return DESC_STATE(state_val); +} + +static void +dump_record(struct prb_map *m, unsigned long id) +{ + unsigned long long ts_nsec; + unsigned long state_var; + unsigned short text_len; + enum desc_state state; + unsigned long begin; + unsigned long next; + char buf[BUFSIZE]; + ulonglong nanos; + int indent_len; + int buf_need; + char *bufp; + char *text; + char *desc; + char *inf; + ulong rem; + char *p; + int i; + + desc = m->descs + ((id % m->desc_ring_count) * SIZE(prb_desc)); + + /* skip non-committed record */ + state_var = ULONG(desc + OFFSET(prb_desc.state_var) + OFFSET(atomic_long_t.counter)); + state = get_desc_state(id, state_var); + if (state != desc_committed && state != desc_finalized) + return; + + begin = ULONG(desc + OFFSET(prb_desc.text_blk_lpos) + OFFSET(prb_data_blk_lpos.begin)) % + m->text_data_ring_size; + next = ULONG(desc + OFFSET(prb_desc.text_blk_lpos) + OFFSET(prb_data_blk_lpos.next)) % + m->text_data_ring_size; + + /* skip data-less text blocks */ + if (begin == next) + return; + + inf = m->infos + ((id % m->desc_ring_count) * SIZE(printk_info)); + + text_len = USHORT(inf + OFFSET(printk_info.text_len)); + + /* handle wrapping data block */ + if (begin > next) + begin = 0; + + /* skip over descriptor ID */ + begin += sizeof(unsigned long); + + /* handle truncated messages */ + if (next - begin < text_len) + text_len = next - begin; + + text = m->text_data + begin; + + ts_nsec = ULONGLONG(inf + OFFSET(printk_info.ts_nsec)); + nanos = (ulonglong)ts_nsec / (ulonglong)1000000000; + rem = (ulonglong)ts_nsec % (ulonglong)1000000000; + + bufp = buf; + bufp += sprintf(buf, "[%5lld.%06ld] ", nanos, rem/1000); + indent_len = strlen(buf); + + /* How much buffer space is needed in the worst case */ + buf_need = MAX(sizeof("\\xXX\n"), sizeof("\n") + indent_len); + + for (i = 0, p = text; i < text_len; i++, p++) { + if (bufp - buf >= sizeof(buf) - buf_need) { + if (write(info->fd_dumpfile, buf, bufp - buf) < 0) + return; + bufp = buf; + } + + if (*p == '\n') + bufp += sprintf(bufp, "\n%-*s", indent_len, ""); + else if (isprint(*p) || isspace(*p)) + *bufp++ = *p; + else + bufp += sprintf(bufp, "\\x%02x", *p); + } + + *bufp++ = '\n'; + + write(info->fd_dumpfile, buf, bufp - buf); +} + +int +dump_lockless_dmesg(void) +{ + unsigned long head_id; + unsigned long tail_id; + unsigned long kaddr; + unsigned long id; + struct prb_map m; + int ret = FALSE; + + /* setup printk_ringbuffer */ + if (!readmem(VADDR, SYMBOL(prb), &kaddr, sizeof(kaddr))) { + ERRMSG("Can't get the prb address.\n"); + return ret; + } + + m.prb = malloc(SIZE(printk_ringbuffer)); + if (!m.prb) { + ERRMSG("Can't allocate memory for prb.\n"); + return ret; + } + if (!readmem(VADDR, kaddr, m.prb, SIZE(printk_ringbuffer))) { + ERRMSG("Can't get prb.\n"); + goto out_prb; + } + + /* setup descriptor ring */ + m.desc_ring = m.prb + OFFSET(printk_ringbuffer.desc_ring); + m.desc_ring_count = 1 << UINT(m.desc_ring + OFFSET(prb_desc_ring.count_bits)); + + kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring.descs)); + m.descs = malloc(SIZE(prb_desc) * m.desc_ring_count); + if (!m.descs) { + ERRMSG("Can't allocate memory for prb.desc_ring.descs.\n"); + goto out_prb; + } + if (!readmem(VADDR, kaddr, m.descs, + SIZE(prb_desc) * m.desc_ring_count)) { + ERRMSG("Can't get prb.desc_ring.descs.\n"); + goto out_descs; + } + + kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring.infos)); + m.infos = malloc(SIZE(printk_info) * m.desc_ring_count); + if (!m.infos) { + ERRMSG("Can't allocate memory for prb.desc_ring.infos.\n"); + goto out_descs; + } + if (!readmem(VADDR, kaddr, m.infos, SIZE(printk_info) * m.desc_ring_count)) { + ERRMSG("Can't get prb.desc_ring.infos.\n"); + goto out_infos; + } + + /* setup text data ring */ + m.text_data_ring = m.prb + OFFSET(printk_ringbuffer.text_data_ring); + m.text_data_ring_size = 1 << UINT(m.text_data_ring + OFFSET(prb_data_ring.size_bits)); + + kaddr = ULONG(m.text_data_ring + OFFSET(prb_data_ring.data)); + m.text_data = malloc(m.text_data_ring_size); + if (!m.text_data) { + ERRMSG("Can't allocate memory for prb.text_data_ring.data.\n"); + goto out_infos; + } + if (!readmem(VADDR, kaddr, m.text_data, m.text_data_ring_size)) { + ERRMSG("Can't get prb.text_data_ring.\n"); + goto out_text_data; + } + + /* ready to go */ + + tail_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring.tail_id) + + OFFSET(atomic_long_t.counter)); + head_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring.head_id) + + OFFSET(atomic_long_t.counter)); + + if (!open_dump_file()) { + ERRMSG("Can't open output file.\n"); + goto out_text_data; + } + + for (id = tail_id; id != head_id; id = (id + 1) & DESC_ID_MASK) + dump_record(&m, id); + + /* dump head record */ + dump_record(&m, id); + + if (!close_files_for_creating_dumpfile()) + goto out_text_data; + + ret = TRUE; +out_text_data: + free(m.text_data); +out_infos: + free(m.infos); +out_descs: + free(m.descs); +out_prb: + free(m.prb); + return ret; +} ++++++ makedumpfile-override-libtinfo.patch ++++++ --- /var/tmp/diff_new_pack.QgvnNi/_old 2021-07-22 22:43:23.439197442 +0200 +++ /var/tmp/diff_new_pack.QgvnNi/_new 2021-07-22 22:43:23.443197437 +0200 @@ -18,7 +18,7 @@ +TINFOLIB = -ltinfo + - LIBS := -lpthread $(LIBS) + LIBS := $(LIBS) -lpthread try-run = $(shell set -e; \ @@ -101,7 +103,7 @@ makedumpfile: $(SRC_BASE) $(OBJ_PART) $( ++++++ makedumpfile-rpmlintrc ++++++ --- /var/tmp/diff_new_pack.QgvnNi/_old 2021-07-22 22:43:23.463197410 +0200 +++ /var/tmp/diff_new_pack.QgvnNi/_new 2021-07-22 22:43:23.463197410 +0200 @@ -1 +1 @@ -addFilter("devel-file-in-non-devel-package .*/usr/share/makedumpfile-1\.6\.3/eppic_scripts/.*\.c") +addFilter("devel-file-in-non-devel-package .*/usr/share/makedumpfile-\d+\.\d+\.\d+/eppic_scripts/.*\.c")