summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--kexec/Makefile1
-rw-r--r--kexec/arch/i386/crashdump-x86.c76
-rw-r--r--kexec/arch/i386/kexec-bzImage.c12
-rw-r--r--kexec/arch/mips/crashdump-mips.c85
-rw-r--r--kexec/arch/ppc/fixup_dtb.c3
-rw-r--r--kexec/arch/x86_64/kexec-x86_64.c9
-rw-r--r--kexec/crashdump.h11
-rw-r--r--kexec/ifdown.c42
-rw-r--r--kexec/kexec.h2
-rw-r--r--purgatory/arch/i386/crashdump_backup.c13
-rw-r--r--purgatory/arch/ppc/misc.S229
-rw-r--r--vmcore-dmesg/vmcore-dmesg.c8
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) {