diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | kexec/Makefile | 1 | ||||
-rw-r--r-- | kexec/arch/i386/crashdump-x86.c | 76 | ||||
-rw-r--r-- | kexec/arch/i386/kexec-bzImage.c | 12 | ||||
-rw-r--r-- | kexec/arch/mips/crashdump-mips.c | 85 | ||||
-rw-r--r-- | kexec/arch/ppc/fixup_dtb.c | 3 | ||||
-rw-r--r-- | kexec/arch/x86_64/kexec-x86_64.c | 9 | ||||
-rw-r--r-- | kexec/crashdump.h | 11 | ||||
-rw-r--r-- | kexec/ifdown.c | 42 | ||||
-rw-r--r-- | kexec/kexec.h | 2 | ||||
-rw-r--r-- | purgatory/arch/i386/crashdump_backup.c | 13 | ||||
-rw-r--r-- | purgatory/arch/ppc/misc.S | 229 | ||||
-rw-r--r-- | vmcore-dmesg/vmcore-dmesg.c | 8 |
13 files changed, 406 insertions, 87 deletions
diff --git a/configure.ac b/configure.ac index 2960c25..172a52a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ dnl -dnl configure.ac for mkelfImage +dnl configure.ac for kexec-tools dnl dnl diff --git a/kexec/Makefile b/kexec/Makefile index 2137cab..7b8e909 100644 --- a/kexec/Makefile +++ b/kexec/Makefile @@ -24,6 +24,7 @@ KEXEC_SRCS += kexec/crashdump-xen.c KEXEC_SRCS += kexec/phys_arch.c KEXEC_SRCS += kexec/kernel_version.c KEXEC_SRCS += kexec/lzma.c +KEXEC_SRCS += kexec/virt_to_phys.c KEXEC_SRCS += kexec/zlib.c KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C) diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c index 9eb574f..01f470d 100644 --- a/kexec/arch/i386/crashdump-x86.c +++ b/kexec/arch/i386/crashdump-x86.c @@ -37,7 +37,7 @@ extern struct arch_options_t arch_options; -static int get_kernel_page_offset(struct kexec_info *info, +static int get_kernel_page_offset(struct kexec_info *UNUSED(info), struct crash_elf_info *elf_info) { int kv; @@ -63,7 +63,7 @@ static int get_kernel_page_offset(struct kexec_info *info, /* Read kernel physical load addr from the file returned by proc_iomem() * (Kernel Code) and store in kexec_info */ -static int get_kernel_paddr(struct kexec_info *info, +static int get_kernel_paddr(struct kexec_info *UNUSED(info), struct crash_elf_info *elf_info) { uint64_t start; @@ -93,7 +93,7 @@ static int get_kernel_paddr(struct kexec_info *info, * hard codes the values to remain backward compatible. Once things stablize * we should get rid of backward compatible code. */ -static int get_kernel_vaddr_and_size(struct kexec_info *info, +static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info), struct crash_elf_info *elf_info) { int result; @@ -200,15 +200,6 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges, return -1; } - /* First entry is for first 640K region. Different bios report first - * 640K in different manner hence hardcoding it */ - if (!(kexec_flags & KEXEC_PRESERVE_CONTEXT)) { - crash_memory_range[0].start = 0x00000000; - crash_memory_range[0].end = 0x0009ffff; - crash_memory_range[0].type = RANGE_RAM; - memory_ranges++; - } - while(fgets(line, sizeof(line), fp) != 0) { char *str; int type, consumed, count; @@ -254,10 +245,6 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges, continue; } - /* First 640K already registered */ - if (end <= 0x0009ffff) - continue; - crash_memory_range[memory_ranges].start = start; crash_memory_range[memory_ranges].end = end; crash_memory_range[memory_ranges].type = type; @@ -678,6 +665,49 @@ static int cmdline_add_memmap_acpi(char *cmdline, unsigned long start, return 0; } +static void get_backup_area(unsigned long *start, unsigned long *end) +{ + const char *iomem = proc_iomem(); + char line[MAX_LINE]; + FILE *fp; + + fp = fopen(iomem, "r"); + if (!fp) { + fprintf(stderr, "Cannot open %s: %s\n", + iomem, strerror(errno)); + return; + } + + while(fgets(line, sizeof(line), fp) != 0) { + char *str; + int count, consumed; + unsigned long mstart, mend; + + count = sscanf(line, "%lx-%lx : %n", + &mstart, &mend, &consumed); + if (count != 2) + continue; + str = line + consumed; +#ifdef DEBUG + printf("%016lx-%016lx : %s", + mstart, mend, str); +#endif + /* Hopefully there is only one RAM region in the first 640K */ + if (memcmp(str, "System RAM\n", 11) == 0 && mend <= 0xa0000 ) { +#ifdef DEBUG + printf("%s: %016lx-%016lx : %s", __func__, mstart, mend, str); +#endif + *start = mstart; + *end = mend; + fclose(fp); + return; + } + } + *start = BACKUP_SRC_START; + *end = BACKUP_SRC_END; + fclose(fp); +} + /* Loads additional segments in case of a panic kernel is being loaded. * One segment for backup region, another segment for storing elf headers * for crash memory image. @@ -692,11 +722,15 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, struct crash_elf_info elf_info; unsigned kexec_arch; + memset(&elf_info, 0x0, sizeof(elf_info)); + /* Constant parts of the elf_info */ memset(&elf_info, 0, sizeof(elf_info)); elf_info.data = ELFDATA2LSB; - elf_info.backup_src_start = BACKUP_SRC_START; - elf_info.backup_src_end = BACKUP_SRC_END; + get_backup_area(&elf_info.backup_src_start, &elf_info.backup_src_end); + info->backup_src_start = elf_info.backup_src_start; + info->backup_src_size = elf_info.backup_src_end + - elf_info.backup_src_start + 1; /* Get the architecture of the running kernel */ kexec_arch = info->kexec_flags & KEXEC_ARCH_MASK; @@ -751,13 +785,15 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, sz = (sizeof(struct memory_range) * (KEXEC_MAX_SEGMENTS + 1)); memmap_p = xmalloc(sz); memset(memmap_p, 0, sz); - add_memmap(memmap_p, BACKUP_SRC_START, BACKUP_SRC_SIZE); + add_memmap(memmap_p, elf_info.backup_src_start, + elf_info.backup_src_end - elf_info.backup_src_start + 1); sz = crash_reserved_mem.end - crash_reserved_mem.start +1; add_memmap(memmap_p, crash_reserved_mem.start, sz); /* Create a backup region segment to store backup data*/ if (!(info->kexec_flags & KEXEC_PRESERVE_CONTEXT)) { - sz = (BACKUP_SRC_SIZE + align - 1) & ~(align - 1); + sz = (elf_info.backup_src_end - elf_info.backup_src_start + align) + & ~(align - 1); tmp = xmalloc(sz); memset(tmp, 0, sz); info->backup_start = add_buffer(info, tmp, sz, sz, align, diff --git a/kexec/arch/i386/kexec-bzImage.c b/kexec/arch/i386/kexec-bzImage.c index 83d3a69..29e9165 100644 --- a/kexec/arch/i386/kexec-bzImage.c +++ b/kexec/arch/i386/kexec-bzImage.c @@ -43,32 +43,32 @@ static const int probe_debug = 0; int bzImage_probe(const char *buf, off_t len) { - struct x86_linux_header header; + const struct x86_linux_header *header; if ((uintmax_t)len < (uintmax_t)sizeof(header)) { return -1; } - memcpy(&header, buf, sizeof(header)); - if (memcmp(header.header_magic, "HdrS", 4) != 0) { + header = (const struct x86_linux_header *)buf; + if (memcmp(header->header_magic, "HdrS", 4) != 0) { if (probe_debug) { fprintf(stderr, "Not a bzImage\n"); } return -1; } - if (header.boot_sector_magic != 0xAA55) { + if (header->boot_sector_magic != 0xAA55) { if (probe_debug) { fprintf(stderr, "No x86 boot sector present\n"); } /* No x86 boot sector present */ return -1; } - if (header.protocol_version < 0x0200) { + if (header->protocol_version < 0x0200) { if (probe_debug) { fprintf(stderr, "Must be at least protocol version 2.00\n"); } /* Must be at least protocol version 2.00 */ return -1; } - if ((header.loadflags & 1) == 0) { + if ((header->loadflags & 1) == 0) { if (probe_debug) { fprintf(stderr, "zImage not a bzImage\n"); } diff --git a/kexec/arch/mips/crashdump-mips.c b/kexec/arch/mips/crashdump-mips.c index 17cf52d..aa50109 100644 --- a/kexec/arch/mips/crashdump-mips.c +++ b/kexec/arch/mips/crashdump-mips.c @@ -49,6 +49,51 @@ static struct memory_range crash_reserved_mem; */ unsigned long long saved_max_mem; +/* Read kernel physical load addr from the file returned by proc_iomem() + * (Kernel Code) and store in kexec_info */ +static int get_kernel_paddr(struct crash_elf_info *elf_info) +{ + uint64_t start; + + if (xen_present()) /* Kernel not entity mapped under Xen */ + return 0; + + if (parse_iomem_single("Kernel code\n", &start, NULL) == 0) { + elf_info->kern_paddr_start = start; +#ifdef DEBUG + printf("kernel load physical addr start = 0x%lx\n", start); +#endif + return 0; + } + + fprintf(stderr, "Cannot determine kernel physical load addr\n"); + return -1; +} + +static int get_kernel_vaddr_and_size(struct crash_elf_info *elf_info, + unsigned long start_offset) +{ + uint64_t end; + + if (!elf_info->kern_paddr_start) + return -1; + + elf_info->kern_vaddr_start = elf_info->kern_paddr_start | + start_offset; + if (parse_iomem_single("Kernel data\n", NULL, &end) == 0) { + elf_info->kern_size = end - elf_info->kern_paddr_start; +#ifdef DEBUG + printf("kernel_vaddr= 0x%llx paddr %llx\n", + elf_info->kern_vaddr_start, + elf_info->kern_paddr_start); + printf("kernel size = 0x%llx\n", elf_info->kern_size); +#endif + return 0; + } + fprintf(stderr, "Cannot determine kernel virtual load addr and size\n"); + return -1; +} + /* Removes crash reserve region from list of memory chunks for whom elf program * headers have to be created. Assuming crash reserve region to be a single * continuous area fully contained inside one of the memory chunks */ @@ -312,6 +357,23 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, unsigned long sz, elfcorehdr; int nr_ranges, align = 1024; struct memory_range *mem_range; + crash_create_elf_headers_func crash_create = crash_create_elf32_headers; + struct crash_elf_info *elf_info = &elf_info32; + unsigned long start_offset = 0x80000000UL; + +#ifdef __mips64 + if (arch_options.core_header_type == CORE_TYPE_ELF64) { + elf_info = &elf_info64; + crash_create = crash_create_elf64; + start_offset = 0xffffffff80000000UL; + } +#endif + + if (get_kernel_paddr(elf_info)) + return -1; + + if (get_kernel_vaddr_and_size(elf_info, start_offset)) + return -1; if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0) return -1; @@ -324,28 +386,9 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, crash_reserved_mem.start, crash_reserved_mem.end, -1); -#ifdef __mips64 - /* Create elf header segment and store crash image data. */ - if (arch_options.core_header_type == CORE_TYPE_ELF64) { - if (crash_create_elf64_headers(info, &elf_info64, - crash_memory_range, nr_ranges, - &tmp, &sz, - ELF_CORE_HEADER_ALIGN) < 0) - return -1; - } else { - if (crash_create_elf32_headers(info, &elf_info32, - crash_memory_range, nr_ranges, - &tmp, &sz, - ELF_CORE_HEADER_ALIGN) < 0) - return -1; - } -#else - if (crash_create_elf32_headers(info, &elf_info32, - crash_memory_range, nr_ranges, - &tmp, &sz, - ELF_CORE_HEADER_ALIGN) < 0) + if (crash_create(info, elf_info, crash_memory_range, nr_ranges, + &tmp, &sz, ELF_CORE_HEADER_ALIGN) < 0) return -1; -#endif elfcorehdr = add_buffer(info, tmp, sz, sz, align, crash_reserved_mem.start, crash_reserved_mem.end, -1); diff --git a/kexec/arch/ppc/fixup_dtb.c b/kexec/arch/ppc/fixup_dtb.c index 205fd77..29e428c 100644 --- a/kexec/arch/ppc/fixup_dtb.c +++ b/kexec/arch/ppc/fixup_dtb.c @@ -354,7 +354,8 @@ char *fixup_dtb_init(struct kexec_info *info, char *blob_buf, off_t *blob_size, printf("%s: Unable to pack flat device tree\n", fdt_strerror(ret)); /* info->nr_segments just a guide, will grow by at least EXPAND_GRANULARITY */ - blob_buf = expand_buf(info->nr_segments, blob_buf, blob_size); + blob_buf = expand_buf(info->nr_segments * sizeof(struct fdt_reserve_entry), + blob_buf, blob_size); /* add reserve region for *THIS* fdt */ *dtb_addr = locate_hole(info, *blob_size, 0, diff --git a/kexec/arch/x86_64/kexec-x86_64.c b/kexec/arch/x86_64/kexec-x86_64.c index 3092643..6c42c32 100644 --- a/kexec/arch/x86_64/kexec-x86_64.c +++ b/kexec/arch/x86_64/kexec-x86_64.c @@ -134,10 +134,7 @@ int arch_process_options(int argc, char **argv) } const struct arch_map_entry arches[] = { - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_X86_64 here. - */ - { "x86_64", KEXEC_ARCH_DEFAULT }, + { "x86_64", KEXEC_ARCH_X86_64 }, { NULL, 0 }, }; @@ -160,6 +157,10 @@ void arch_update_purgatory(struct kexec_info *info) &arch_options.console_vga, sizeof(arch_options.console_vga)); elf_rel_set_symbol(&info->rhdr, "console_serial", &arch_options.console_serial, sizeof(arch_options.console_serial)); + elf_rel_set_symbol(&info->rhdr, "backup_src_start", + &info->backup_src_start, sizeof(info->backup_src_start)); + elf_rel_set_symbol(&info->rhdr, "backup_src_size", + &info->backup_src_size, sizeof(info->backup_src_size)); if (info->kexec_flags & KEXEC_ON_CRASH) { panic_kernel = 1; diff --git a/kexec/crashdump.h b/kexec/crashdump.h index eccdb9f..5a597eb 100644 --- a/kexec/crashdump.h +++ b/kexec/crashdump.h @@ -7,8 +7,8 @@ extern int get_xen_vmcoreinfo(uint64_t *addr, uint64_t *len); /* Need to find a better way to determine per cpu notes section size. */ #define MAX_NOTE_BYTES 1024 -/* Expecting ELF headers to fit in 16K. Increase it if you need more. */ -#define KCORE_ELF_HEADERS_SIZE 16384 +/* Expecting ELF headers to fit in 32K. Increase it if you need more. */ +#define KCORE_ELF_HEADERS_SIZE 32768 /* The address of the ELF header is passed to the secondary kernel * using the kernel command line option memmap=nnn. * The smallest unit the kernel accepts is in kilobytes, @@ -35,6 +35,13 @@ struct crash_elf_info { int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len); }; +typedef int(*crash_create_elf_headers_func)(struct kexec_info *info, + struct crash_elf_info *elf_info, + struct memory_range *range, + int ranges, + void **buf, unsigned long *size, + unsigned long align); + int crash_create_elf32_headers(struct kexec_info *info, struct crash_elf_info *elf_info, struct memory_range *range, int ranges, diff --git a/kexec/ifdown.c b/kexec/ifdown.c index d480b3b..bc7f12f 100644 --- a/kexec/ifdown.c +++ b/kexec/ifdown.c @@ -19,8 +19,6 @@ char *v_ifdown = "@(#)ifdown.c 1.11 02-Jun-1998 miquels@cistron.nl"; #include <net/if.h> #include <netinet/in.h> -#define MAX_IFS 64 - /* * First, we find all shaper devices and down them. Then we * down all real interfaces. This is because the comment in the @@ -29,43 +27,45 @@ char *v_ifdown = "@(#)ifdown.c 1.11 02-Jun-1998 miquels@cistron.nl"; */ int ifdown(void) { - struct ifreq ifr[MAX_IFS]; - struct ifconf ifc; - int i, fd; - int numif; - int shaper; + struct if_nameindex *ifa, *ifp; + struct ifreq ifr; + int fd, shaper; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { fprintf(stderr, "ifdown: "); perror("socket"); return -1; } - ifc.ifc_len = sizeof(ifr); - ifc.ifc_req = ifr; - if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { + if ((ifa = if_nameindex()) == NULL) { fprintf(stderr, "ifdown: "); - perror("SIOCGIFCONF"); - close(fd); + perror("if_nameindex"); return -1; } - numif = ifc.ifc_len / sizeof(struct ifreq); for (shaper = 1; shaper >= 0; shaper--) { - for (i = 0; i < numif; i++) { + for (ifp = ifa; ifp->if_index; ifp++) { - if ((strncmp(ifr[i].ifr_name, "shaper", 6) == 0) + if ((strncmp(ifp->if_name, "shaper", 6) == 0) != shaper) continue; - - if (strcmp(ifr[i].ifr_name, "lo") == 0) + if (strcmp(ifp->if_name, "lo") == 0) continue; - if (strchr(ifr[i].ifr_name, ':') != NULL) + if (strchr(ifp->if_name, ':') != NULL) continue; - ifr[i].ifr_flags &= ~(IFF_UP); - if (ioctl(fd, SIOCSIFFLAGS, &ifr[i]) < 0) { + + strncpy(ifr.ifr_name, ifp->if_name, IFNAMSIZ); + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { fprintf(stderr, "ifdown: shutdown "); - perror(ifr[i].ifr_name); + perror(ifp->if_name); + return -1; } + ifr.ifr_flags &= ~(IFF_UP); + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + fprintf(stderr, "ifdown: shutdown "); + perror(ifp->if_name); + return -1; + } + } } close(fd); diff --git a/kexec/kexec.h b/kexec/kexec.h index 9a70224..9b59890 100644 --- a/kexec/kexec.h +++ b/kexec/kexec.h @@ -122,6 +122,8 @@ struct kexec_info { struct mem_ehdr rhdr; unsigned long backup_start; unsigned long kexec_flags; + unsigned long backup_src_start; + unsigned long backup_src_size; }; struct arch_map_entry { diff --git a/purgatory/arch/i386/crashdump_backup.c b/purgatory/arch/i386/crashdump_backup.c index c619446..365eb5d 100644 --- a/purgatory/arch/i386/crashdump_backup.c +++ b/purgatory/arch/i386/crashdump_backup.c @@ -20,13 +20,15 @@ #include <stdint.h> #include <string.h> -#include "../../../kexec/arch/i386/crashdump-x86.h" /* Backup region start gets set after /proc/iomem has been parsed. */ /* We reuse the same code for x86_64 also so changing backup_start to unsigned long */ unsigned long backup_start = 0; +unsigned long backup_src_start = 0; +unsigned long backup_src_size = 0; + /* Backup first 640K of memory to backup region as reserved by kexec. * Assuming first 640K has to be present on i386 machines and no address * validity checks have to be performed. */ @@ -34,11 +36,16 @@ unsigned long backup_start = 0; void crashdump_backup_memory(void) { void *dest, *src; + size_t size; + + src = (void *) backup_src_start; + size = (size_t) backup_src_size; - src = (void *) BACKUP_SRC_START; + if (!size) + return; if (backup_start) { dest = (void *)(backup_start); - memcpy(dest, src, BACKUP_SRC_SIZE); + memcpy(dest, src, size); } } diff --git a/purgatory/arch/ppc/misc.S b/purgatory/arch/ppc/misc.S index b0a5486..bc6a18d 100644 --- a/purgatory/arch/ppc/misc.S +++ b/purgatory/arch/ppc/misc.S @@ -16,6 +16,235 @@ #include "ppc_asm.h" +/* This is from linux-2.6/arch/powerpc/lib/crtsavres.S: + * + * Special support for eabi and SVR4 + * + * Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc. + * Copyright 2008 Freescale Semiconductor, Inc. + * Written By Michael Meissner + * + * Based on gcc/config/rs6000/crtsavres.asm from gcc + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * In addition to the permissions in the GNU General Public License, the + * Free Software Foundation gives you unlimited permission to link the + * compiled version of this file with other programs, and to distribute + * those programs without any restriction coming from the use of this + * file. (The General Public License restrictions do apply in other + * respects; for example, they cover modification of the file, and + * distribution when not linked into another program.) + * + * This file 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; see the file COPYING. If not, write to + * the Free Software Foundation, 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, if you link this library with files + * compiled with GCC to produce an executable, this does not cause + * the resulting executable to be covered by the GNU General Public License. + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + */ +#include "config.h" + +#define _GLOBAL(name) \ + .type name,@function; \ + .globl name; \ +name: + +/* Routines for saving integer registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the integer save area. */ + +_GLOBAL(_savegpr_14) +_GLOBAL(_save32gpr_14) + stw 14,-72(11) /* save gp registers */ +_GLOBAL(_savegpr_15) +_GLOBAL(_save32gpr_15) + stw 15,-68(11) +_GLOBAL(_savegpr_16) +_GLOBAL(_save32gpr_16) + stw 16,-64(11) +_GLOBAL(_savegpr_17) +_GLOBAL(_save32gpr_17) + stw 17,-60(11) +_GLOBAL(_savegpr_18) +_GLOBAL(_save32gpr_18) + stw 18,-56(11) +_GLOBAL(_savegpr_19) +_GLOBAL(_save32gpr_19) + stw 19,-52(11) +_GLOBAL(_savegpr_20) +_GLOBAL(_save32gpr_20) + stw 20,-48(11) +_GLOBAL(_savegpr_21) +_GLOBAL(_save32gpr_21) + stw 21,-44(11) +_GLOBAL(_savegpr_22) +_GLOBAL(_save32gpr_22) + stw 22,-40(11) +_GLOBAL(_savegpr_23) +_GLOBAL(_save32gpr_23) + stw 23,-36(11) +_GLOBAL(_savegpr_24) +_GLOBAL(_save32gpr_24) + stw 24,-32(11) +_GLOBAL(_savegpr_25) +_GLOBAL(_save32gpr_25) + stw 25,-28(11) +_GLOBAL(_savegpr_26) +_GLOBAL(_save32gpr_26) + stw 26,-24(11) +_GLOBAL(_savegpr_27) +_GLOBAL(_save32gpr_27) + stw 27,-20(11) +_GLOBAL(_savegpr_28) +_GLOBAL(_save32gpr_28) + stw 28,-16(11) +_GLOBAL(_savegpr_29) +_GLOBAL(_save32gpr_29) + stw 29,-12(11) +_GLOBAL(_savegpr_30) +_GLOBAL(_save32gpr_30) + stw 30,-8(11) +_GLOBAL(_savegpr_31) +_GLOBAL(_save32gpr_31) + stw 31,-4(11) + blr + +/* Routines for restoring integer registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the integer restore area. */ + +_GLOBAL(_restgpr_14) +_GLOBAL(_rest32gpr_14) + lwz 14,-72(11) /* restore gp registers */ +_GLOBAL(_restgpr_15) +_GLOBAL(_rest32gpr_15) + lwz 15,-68(11) +_GLOBAL(_restgpr_16) +_GLOBAL(_rest32gpr_16) + lwz 16,-64(11) +_GLOBAL(_restgpr_17) +_GLOBAL(_rest32gpr_17) + lwz 17,-60(11) +_GLOBAL(_restgpr_18) +_GLOBAL(_rest32gpr_18) + lwz 18,-56(11) +_GLOBAL(_restgpr_19) +_GLOBAL(_rest32gpr_19) + lwz 19,-52(11) +_GLOBAL(_restgpr_20) +_GLOBAL(_rest32gpr_20) + lwz 20,-48(11) +_GLOBAL(_restgpr_21) +_GLOBAL(_rest32gpr_21) + lwz 21,-44(11) +_GLOBAL(_restgpr_22) +_GLOBAL(_rest32gpr_22) + lwz 22,-40(11) +_GLOBAL(_restgpr_23) +_GLOBAL(_rest32gpr_23) + lwz 23,-36(11) +_GLOBAL(_restgpr_24) +_GLOBAL(_rest32gpr_24) + lwz 24,-32(11) +_GLOBAL(_restgpr_25) +_GLOBAL(_rest32gpr_25) + lwz 25,-28(11) +_GLOBAL(_restgpr_26) +_GLOBAL(_rest32gpr_26) + lwz 26,-24(11) +_GLOBAL(_restgpr_27) +_GLOBAL(_rest32gpr_27) + lwz 27,-20(11) +_GLOBAL(_restgpr_28) +_GLOBAL(_rest32gpr_28) + lwz 28,-16(11) +_GLOBAL(_restgpr_29) +_GLOBAL(_rest32gpr_29) + lwz 29,-12(11) +_GLOBAL(_restgpr_30) +_GLOBAL(_rest32gpr_30) + lwz 30,-8(11) +_GLOBAL(_restgpr_31) +_GLOBAL(_rest32gpr_31) + lwz 31,-4(11) + blr + +/* Routines for restoring integer registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the integer restore area. */ + +_GLOBAL(_restgpr_14_x) +_GLOBAL(_rest32gpr_14_x) + lwz 14,-72(11) /* restore gp registers */ +_GLOBAL(_restgpr_15_x) +_GLOBAL(_rest32gpr_15_x) + lwz 15,-68(11) +_GLOBAL(_restgpr_16_x) +_GLOBAL(_rest32gpr_16_x) + lwz 16,-64(11) +_GLOBAL(_restgpr_17_x) +_GLOBAL(_rest32gpr_17_x) + lwz 17,-60(11) +_GLOBAL(_restgpr_18_x) +_GLOBAL(_rest32gpr_18_x) + lwz 18,-56(11) +_GLOBAL(_restgpr_19_x) +_GLOBAL(_rest32gpr_19_x) + lwz 19,-52(11) +_GLOBAL(_restgpr_20_x) +_GLOBAL(_rest32gpr_20_x) + lwz 20,-48(11) +_GLOBAL(_restgpr_21_x) +_GLOBAL(_rest32gpr_21_x) + lwz 21,-44(11) +_GLOBAL(_restgpr_22_x) +_GLOBAL(_rest32gpr_22_x) + lwz 22,-40(11) +_GLOBAL(_restgpr_23_x) +_GLOBAL(_rest32gpr_23_x) + lwz 23,-36(11) +_GLOBAL(_restgpr_24_x) +_GLOBAL(_rest32gpr_24_x) + lwz 24,-32(11) +_GLOBAL(_restgpr_25_x) +_GLOBAL(_rest32gpr_25_x) + lwz 25,-28(11) +_GLOBAL(_restgpr_26_x) +_GLOBAL(_rest32gpr_26_x) + lwz 26,-24(11) +_GLOBAL(_restgpr_27_x) +_GLOBAL(_rest32gpr_27_x) + lwz 27,-20(11) +_GLOBAL(_restgpr_28_x) +_GLOBAL(_rest32gpr_28_x) + lwz 28,-16(11) +_GLOBAL(_restgpr_29_x) +_GLOBAL(_rest32gpr_29_x) + lwz 29,-12(11) +_GLOBAL(_restgpr_30_x) +_GLOBAL(_rest32gpr_30_x) + lwz 30,-8(11) +_GLOBAL(_restgpr_31_x) +_GLOBAL(_rest32gpr_31_x) + lwz 0,4(11) + lwz 31,-4(11) + mtlr 0 + mr 1,11 + blr + .text /* diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c index 7015894..365e293 100644 --- a/vmcore-dmesg/vmcore-dmesg.c +++ b/vmcore-dmesg/vmcore-dmesg.c @@ -113,10 +113,6 @@ static void read_elf32(int fd) ehdr.e_phentsize, sizeof(Elf32_Phdr)); exit(12); } - if (ehdr.e_phnum > ULONG_MAX/sizeof(Elf64_Phdr)) { - fprintf(stderr, "Too many elf program header entries\n"); - exit(13); - } phdrs32_size = ehdr.e_phnum * sizeof(Elf32_Phdr); phdrs_size = ehdr.e_phnum * sizeof(Elf64_Phdr); phdr32 = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr)); @@ -189,10 +185,6 @@ static void read_elf64(int fd) ehdr.e_phentsize, sizeof(Elf64_Phdr)); exit(12); } - if (ehdr.e_phnum > ULONG_MAX/sizeof(Elf64_Phdr)) { - fprintf(stderr, "Too many program header entries\n"); - exit(13); - } phdrs_size = ehdr.e_phnum * sizeof(Elf64_Phdr); phdr64 = calloc(ehdr.e_phnum, sizeof(Elf64_Phdr)); if (!phdr64) { |