From 9bcc5f1b276c115c5c3542b4767743ce3240355e Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 5 Jan 2007 17:47:37 +0000 Subject: [PATCH] Related: bz221272 --- kexec-tools-1.101-reloc-update.patch | 830 ++++++++++---------- kexec-tools-1.101-relocatable-bzimage.patch | 172 ++++ 2 files changed, 587 insertions(+), 415 deletions(-) create mode 100644 kexec-tools-1.101-relocatable-bzimage.patch diff --git a/kexec-tools-1.101-reloc-update.patch b/kexec-tools-1.101-reloc-update.patch index 39d8095..f8ce364 100644 --- a/kexec-tools-1.101-reloc-update.patch +++ b/kexec-tools-1.101-reloc-update.patch @@ -1,5 +1,16 @@ +--- kexec-tools-1.101/purgatory/arch/x86_64/include/arch/debug.h.orig 2004-12-20 18:05:40.000000000 -0500 ++++ kexec-tools-1.101/purgatory/arch/x86_64/include/arch/debug.h 2007-01-05 12:45:07.000000000 -0500 +@@ -311,7 +311,7 @@ + TTYS0_TX_AL + + +-#define DEBUG(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') ++#define DEBUG_CHAR(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') + #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') + #define DEBUG_TX_HEX64(x) TTYS0_TX_HEX64(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') + --- kexec-tools-1.101/purgatory/arch/i386/linux-entry16.S.orig 2004-12-20 05:48:45.000000000 -0500 -+++ kexec-tools-1.101/purgatory/arch/i386/linux-entry16.S 2006-12-01 15:05:42.000000000 -0500 ++++ kexec-tools-1.101/purgatory/arch/i386/linux-entry16.S 2007-01-05 12:45:07.000000000 -0500 @@ -127,10 +127,10 @@ TTYS0_TX_AL @@ -32,7 +43,7 @@ /* Note we don't disable the a20 line, (this shouldn't be required) * The code to do it is in kexec_test and it is a real pain. * I will worry about that when I need it. -@@ -164,26 +164,26 @@ +@@ -164,26 +164,26 @@ DEBUG('c') movl %eax, %fs movl %eax, %gs @@ -63,7 +74,7 @@ /* we are in real mode now * set up the real mode segment registers : %ds, $ss, %es */ -@@ -191,7 +191,7 @@ +@@ -191,7 +191,7 @@ DEBUG('g') movw %cs, %ax movw %ax, %ds @@ -72,7 +83,7 @@ /* Load the registers */ movl eax - entry16, %eax movl ebx - entry16, %ebx -@@ -386,10 +386,10 @@ +@@ -386,10 +386,10 @@ gdt_end: TTYS0_TX_AL @@ -85,7 +96,7 @@ #define DEBUG_TX_HEX32(x) #endif -@@ -403,7 +403,7 @@ +@@ -403,7 +403,7 @@ setup16_debug_start: _reloc = . .balign 16 .code32 @@ -94,7 +105,7 @@ /* Compute where I am running at */ call 1f 1: popl %ebx -@@ -412,13 +412,13 @@ +@@ -412,13 +412,13 @@ DEBUG('a') /* Remember where I am running at */ movl %ebx, location - _reloc(%ebx) @@ -110,7 +121,7 @@ /* Fixup the gdt */ movl %ebx, %eax shll $16, %eax -@@ -440,7 +440,7 @@ +@@ -440,7 +440,7 @@ DEBUG('c') @@ -119,7 +130,7 @@ /* Setup the classic BIOS interrupt table at 0x0 */ lidt idtptr - _reloc(%ebx) -@@ -465,20 +465,20 @@ +@@ -465,20 +465,20 @@ DEBUG('d') ljmp $0x08, $2f - _reloc 2: .code16 @@ -143,7 +154,7 @@ /* we are in real mode now * set up the real mode segment registers : %ds, $ss, %es */ -@@ -486,7 +486,7 @@ +@@ -486,7 +486,7 @@ DEBUG('g') movw %cs, %ax movw %ax, %ds @@ -152,7 +163,7 @@ /* Load the registers */ movl eax - _reloc, %eax movl ebx - _reloc, %ebx -@@ -600,7 +600,7 @@ +@@ -600,7 +600,7 @@ debug_gdt_end: setup16_debug_kernel_pre_protected: .code16 @@ -161,7 +172,7 @@ cli # no interrupts allowed ! movb $0x80, %al # disable NMI for bootup # sequence -@@ -611,7 +611,7 @@ +@@ -611,7 +611,7 @@ setup16_debug_first_code32: .byte 0xbf /* movl $0x12345678, %edi */ location: .long 0x12345678 @@ -170,19 +181,9 @@ .byte 0xb8 /* movl $0x10000, %eax */ setup16_debug_old_code32: .long 0x10000 ---- kexec-tools-1.101/purgatory/arch/i386/include/arch/debug.h.orig 2004-12-20 18:03:17.000000000 -0500 -+++ kexec-tools-1.101/purgatory/arch/i386/include/arch/debug.h 2006-12-01 15:05:42.000000000 -0500 -@@ -311,6 +311,6 @@ - TTYS0_TX_AL - - --#define DEBUG(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') -+#define DEBUG_CHAR(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #define DEBUG_TX_HEX64(x) TTYS0_TX_HEX64(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') --- kexec-tools-1.101/purgatory/arch/i386/entry32-16-debug.S.orig 2004-12-20 18:11:43.000000000 -0500 -+++ kexec-tools-1.101/purgatory/arch/i386/entry32-16-debug.S 2006-12-01 15:05:42.000000000 -0500 -@@ -55,15 +55,15 @@ ++++ kexec-tools-1.101/purgatory/arch/i386/entry32-16-debug.S 2007-01-05 12:45:07.000000000 -0500 +@@ -55,15 +55,15 @@ entry16_debug: orl %ecx, 0x14 + gdt @@ -201,7 +202,7 @@ /* Note we don't disable the a20 line, (this shouldn't be required) * The code to do it is in kexec_test and it is a real pain. * I will worry about that when I need it. -@@ -77,26 +77,26 @@ +@@ -77,26 +77,26 @@ DEBUG('c') movl %eax, %fs movl %eax, %gs @@ -232,7 +233,7 @@ /* we are in real mode now * set up the real mode segment registers : %ds, $ss, %es */ -@@ -104,7 +104,7 @@ +@@ -104,7 +104,7 @@ DEBUG('g') movw %cs, %ax movw %ax, %ds @@ -241,7 +242,7 @@ /* Load the registers */ movl eax - entry16_debug, %eax movl ebx - entry16_debug, %ebx -@@ -176,7 +176,7 @@ +@@ -176,7 +176,7 @@ gdt_end: .text entry16_debug_pre32: .code16 @@ -250,7 +251,7 @@ cli # no interrupts allowed ! movb $0x80, %al # disable NMI for bootup # sequence -@@ -186,7 +186,7 @@ +@@ -186,7 +186,7 @@ DEBUG('i') entry16_debug_first32: .code32 @@ -259,9 +260,9 @@ .byte 0xb8 /* movl $0x10000, %eax */ entry16_debug_old_first32: .long 0x100000 ---- kexec-tools-1.101/purgatory/arch/x86_64/include/arch/debug.h.orig 2004-12-20 18:05:40.000000000 -0500 -+++ kexec-tools-1.101/purgatory/arch/x86_64/include/arch/debug.h 2006-12-01 15:05:42.000000000 -0500 -@@ -311,7 +311,7 @@ +--- kexec-tools-1.101/purgatory/arch/i386/include/arch/debug.h.orig 2004-12-20 18:03:17.000000000 -0500 ++++ kexec-tools-1.101/purgatory/arch/i386/include/arch/debug.h 2007-01-05 12:45:07.000000000 -0500 +@@ -311,6 +311,6 @@ TTYS0_TX_AL @@ -269,30 +270,9 @@ +#define DEBUG_CHAR(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #define DEBUG_TX_HEX64(x) TTYS0_TX_HEX64(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - ---- kexec-tools-1.101/kexec/kexec.h.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec.h 2006-12-01 15:05:42.000000000 -0500 -@@ -116,6 +116,9 @@ - struct mem_ehdr rhdr; - unsigned long backup_start; - unsigned long kexec_flags; -+ unsigned long kern_vaddr_start; -+ unsigned long kern_paddr_start; -+ unsigned long kern_size; - }; - - void usage(void); -@@ -177,6 +180,7 @@ - extern void *xmalloc(size_t size); - extern void *xrealloc(void *ptr, size_t size); - extern char *slurp_file(const char *filename, off_t *r_size); -+extern char *slurp_file_len(const char *filename, off_t size); - extern char *slurp_decompress_file(const char *filename, off_t *r_size); - extern void add_segment(struct kexec_info *info, - const void *buf, size_t bufsz, unsigned long base, size_t memsz); ---- kexec-tools-1.101/kexec/Makefile.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/Makefile 2006-12-01 15:05:42.000000000 -0500 -@@ -13,6 +13,7 @@ +--- kexec-tools-1.101/kexec/Makefile.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/Makefile 2007-01-05 12:45:07.000000000 -0500 +@@ -13,6 +13,7 @@ KEXEC_C_SRCS:= kexec/kexec.c KEXEC_C_SRCS+= kexec/ifdown.c KEXEC_C_SRCS+= kexec/kexec-elf.c KEXEC_C_SRCS+= kexec/kexec-elf-exec.c @@ -300,228 +280,156 @@ KEXEC_C_SRCS+= kexec/kexec-elf-rel.c KEXEC_C_SRCS+= kexec/kexec-elf-boot.c KEXEC_C_SRCS+= kexec/crashdump.c ---- kexec-tools-1.101/kexec/kexec-elf-exec.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf-exec.c 2006-12-01 15:05:42.000000000 -0500 -@@ -11,11 +11,12 @@ +--- kexec-tools-1.101/kexec/kexec-elf-rel.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/kexec-elf-rel.c 2007-01-05 12:45:07.000000000 -0500 +@@ -135,10 +135,11 @@ static struct mem_rela elf_rela(struct m + return rela; + } - static const int probe_debug = 0; - --int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr) -+int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr, +-int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr) ++int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr, + uint32_t flags) { - struct mem_phdr *phdr, *end_phdr; int result; - result = build_elf_info(buf, len, ehdr); + result = build_elf_info(buf, len, ehdr, flags); if (result < 0) { return result; } -@@ -136,11 +137,11 @@ - } +@@ -412,12 +413,12 @@ int elf_rel_load(struct mem_ehdr *ehdr, - void elf_exec_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, -- const char *buf, off_t len) -+ const char *buf, off_t len, uint32_t flags) + void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, + const char *buf, off_t len, unsigned long min, unsigned long max, +- int end) ++ int end, uint32_t flags) { int result; + /* Parse the Elf file */ -- result = build_elf_exec_info(buf, len, ehdr); -+ result = build_elf_exec_info(buf, len, ehdr, flags); +- result = build_elf_rel_info((char *)purgatory, purgatory_size, ehdr); ++ result = build_elf_rel_info(buf, len, ehdr, flags); if (result < 0) { - die("ELF exec parse failed\n"); + die("ELF rel parse failed\n"); } ---- kexec-tools-1.101/kexec/kexec.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec.c 2006-12-01 15:05:42.000000000 -0500 -@@ -391,6 +391,50 @@ - return buf; +--- kexec-tools-1.101/kexec/kexec-elf.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/kexec-elf.c 2007-01-05 12:45:07.000000000 -0500 +@@ -368,7 +368,8 @@ static int build_mem_elf64_phdr(const ch + return 0; } -+/* This functions reads either specified number of bytes from the file or -+ lesser if EOF is met. */ -+ -+char *slurp_file_len(const char *filename, off_t size) -+{ -+ int fd; -+ char *buf; -+ off_t progress; -+ ssize_t result; -+ -+ if (!filename) -+ return 0; -+ fd = open(filename, O_RDONLY); -+ if (fd < 0) { -+ fprintf(stderr, "Cannot open %s: %s\n", filename, -+ strerror(errno)); -+ return 0; -+ } -+ buf = xmalloc(size); -+ progress = 0; -+ while(progress < size) { -+ result = read(fd, buf + progress, size - progress); -+ if (result < 0) { -+ if ((errno == EINTR) || (errno == EAGAIN)) -+ continue; -+ fprintf(stderr, "read on %s of %ld bytes failed: %s\n", -+ filename, (size - progress)+ 0UL, -+ strerror(errno)); -+ free(buf); -+ return 0; -+ } -+ if (result == 0) -+ /* EOF */ -+ break; -+ progress += result; -+ } -+ result = close(fd); -+ if (result < 0) { -+ die("Close of %s failed: %s\n", -+ filename, strerror(errno)); -+ } -+ return buf; -+} -+ - #if HAVE_ZLIB_H - char *slurp_decompress_file(const char *filename, off_t *r_size) +-static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) ++static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr, ++ uint32_t flags) { ---- kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c 2006-12-01 15:05:42.000000000 -0500 -@@ -133,7 +133,7 @@ - * it's gdt. - */ - elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- 0x3000, 640*1024, -1); -+ 0x3000, 640*1024, -1, 0); + size_t phdr_size, mem_phdr_size; + int i; +@@ -418,9 +419,11 @@ static int build_mem_phdrs(const char *b - /* The argument/parameter segment */ - setup_size = kern16_size + command_line_len; ---- kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c 2006-12-01 15:05:42.000000000 -0500 -@@ -209,10 +209,11 @@ + /* Check the program headers to be certain + * they are safe to use. ++ * Skip the check if ELF_SKIP_FILESZ_CHECK is set. + */ + phdr = &ehdr->e_phdr[i]; +- if ((phdr->p_offset + phdr->p_filesz) > len) { ++ if (!(flags & ELF_SKIP_FILESZ_CHECK) ++ && (phdr->p_offset + phdr->p_filesz) > len) { + /* The segment does not fit in the buffer */ + if (probe_debug) { + fprintf(stderr, "ELF segment not in file\n"); +@@ -580,7 +583,8 @@ static int build_mem_elf64_shdr(const ch + return 0; + } - - /* Load the ELF executable */ -- elf_exec_build_load(info, &ehdr, buf, len); -+ elf_exec_build_load(info, &ehdr, buf, len, 0); +-static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) ++static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr, ++ uint32_t flags) + { + size_t shdr_size, mem_shdr_size; + int i; +@@ -628,11 +632,12 @@ static int build_mem_shdrs(const char *b + } + /* Check the section headers to be certain + * they are safe to use. ++ * Skip the check if ELF_SKIP_FILESZ_CHECK is set. + */ + shdr = &ehdr->e_shdr[i]; +- if ((shdr->sh_type != SHT_NOBITS) && +- ((shdr->sh_offset + shdr->sh_size) > len)) +- { ++ if (!(flags & ELF_SKIP_FILESZ_CHECK) ++ && (shdr->sh_type != SHT_NOBITS) ++ && (shdr->sh_offset + shdr->sh_size) > len) { + /* The section does not fit in the buffer */ + if (probe_debug) { + fprintf(stderr, "ELF section %d not in file\n", +@@ -710,7 +715,8 @@ static int build_mem_notes(const char *b + note_size += (hdr.n_descsz + 3) & ~3; + + if ((hdr.n_namesz != 0) && (name[hdr.n_namesz -1] != '\0')) { +- die("Note name is not null termiated"); ++ fprintf(stderr, "Note name is not null termiated\n"); ++ return -1; + } + ehdr->e_note[i].n_type = hdr.n_type; + ehdr->e_note[i].n_name = (char *)name; +@@ -729,7 +735,8 @@ void free_elf_info(struct mem_ehdr *ehdr + memset(ehdr, 0, sizeof(*ehdr)); + } + +-int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr) ++int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr, ++ uint32_t flags) + { + int result; + result = build_mem_ehdr(buf, len, ehdr); +@@ -737,14 +744,14 @@ int build_elf_info(const char *buf, off_ + return result; + } + if ((ehdr->e_phoff > 0) && (ehdr->e_phnum > 0)) { +- result = build_mem_phdrs(buf, len, ehdr); ++ result = build_mem_phdrs(buf, len, ehdr, flags); + if (result < 0) { + free_elf_info(ehdr); + return result; + } + } + if ((ehdr->e_shoff > 0) && (ehdr->e_shnum > 0)) { +- result = build_mem_shdrs(buf, len, ehdr); ++ result = build_mem_shdrs(buf, len, ehdr, flags); + if (result < 0) { + free_elf_info(ehdr); + return result; +--- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2007-01-05 12:45:07.000000000 -0500 +@@ -56,7 +56,7 @@ int elf_ia64_probe(const char *buf, off_ + { + struct mem_ehdr ehdr; + int result; +- result = build_elf_exec_info(buf, len, &ehdr); ++ result = build_elf_exec_info(buf, len, &ehdr, 0); + if (result < 0) { + if (probe_debug) { + fprintf(stderr, "Not an ELF executable\n"); +@@ -163,7 +163,7 @@ int elf_ia64_load(int argc, char **argv, + } + + /* Parse the Elf file */ +- result = build_elf_exec_info(buf, len, &ehdr); ++ result = build_elf_exec_info(buf, len, &ehdr, 0); + if (result < 0) { + fprintf(stderr, "ELF parse failed\n"); + free_elf_info(&ehdr); +@@ -198,7 +198,7 @@ int elf_ia64_load(int argc, char **argv, /* Load the setup code */ -- elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, 0, ULONG_MAX, 1); -+ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, 0, -+ ULONG_MAX, 1, 0); - - /* The first segment will contain the multiboot headers: - * ============= ---- kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c 2006-12-01 15:05:42.000000000 -0500 -@@ -47,7 +47,7 @@ - - struct mem_ehdr ehdr; - int result; -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - if (probe_debug) { - fprintf(stderr, "Not an ELF executable\n"); -@@ -177,7 +177,7 @@ - } + elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, +- 0x0, ULONG_MAX, -1); ++ 0x0, ULONG_MAX, -1, 0); - /* Load the ELF executable */ -- elf_exec_build_load(info, &ehdr, buf, len); -+ elf_exec_build_load(info, &ehdr, buf, len, 0); - entry = ehdr.e_entry; - max_addr = elf_max_addr(&ehdr); -@@ -186,7 +186,7 @@ - if (arg_style != ARG_STYLE_NONE) { - /* Load the setup code */ - elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- 0, ULONG_MAX, 1); -+ 0, ULONG_MAX, 1, 0); - } - if (arg_style == ARG_STYLE_NONE) { - info->entry = (void *)entry; ---- kexec-tools-1.101/kexec/arch/ppc/kexec-elf-ppc.c.orig 2005-01-20 14:10:56.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ppc/kexec-elf-ppc.c 2006-12-01 15:05:42.000000000 -0500 -@@ -72,7 +72,7 @@ - - struct mem_ehdr ehdr; - int result; -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - goto out; - } -@@ -180,7 +180,7 @@ - } - - /* Parse the Elf file */ -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - free_elf_info(&ehdr); - return result; ---- kexec-tools-1.101/kexec/arch/x86_64/kexec-x86_64.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/x86_64/kexec-x86_64.c 2006-12-01 15:05:42.000000000 -0500 -@@ -64,7 +64,7 @@ - continue; - str = line + consumed; - end = end + 1; --#if 0 -+#ifdef DEBUG - printf("%016Lx-%016Lx : %s", - start, end, str); - #endif -@@ -104,7 +104,7 @@ - memory_range[memory_ranges].start = start; - memory_range[memory_ranges].end = end; - memory_range[memory_ranges].type = type; --#if 0 -+#ifdef DEBUG - printf("%016Lx-%016Lx : %x\n", - start, end, type); - #endif ---- kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c 2006-12-01 15:05:42.000000000 -0500 -@@ -47,7 +47,7 @@ - - struct mem_ehdr ehdr; - int result; -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - if (probe_debug) { - fprintf(stderr, "Not an ELF executable\n"); -@@ -177,7 +177,7 @@ - } - - /* Load the ELF executable */ -- elf_exec_build_load(info, &ehdr, buf, len); -+ elf_exec_build_load(info, &ehdr, buf, len, 0); - - entry = ehdr.e_entry; - max_addr = elf_max_addr(&ehdr); -@@ -186,7 +186,7 @@ - if (arg_style != ARG_STYLE_NONE) { - /* Load the setup code */ - elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- 0, ULONG_MAX, 1); -+ 0, ULONG_MAX, 1, 0); - } - if (arg_style == ARG_STYLE_NONE) { - info->entry = (void *)entry; ---- kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-rel-x86_64.c.orig 2004-12-21 12:51:24.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-rel-x86_64.c 2006-12-01 15:05:42.000000000 -0500 -@@ -60,7 +60,7 @@ - void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, - void *location, unsigned long address, unsigned long value) - { --#if 0 -+#ifdef DEBUG - fprintf(stderr, "%s\n", reloc_name(r_type)); - #endif - switch(r_type) { ---- kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.c 2006-12-01 15:05:42.000000000 -0500 + if (load_crashdump_segments(info, &ehdr, max_addr, 0, +--- kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.c 2007-01-05 12:45:07.000000000 -0500 @@ -24,8 +24,10 @@ #include #include @@ -533,7 +441,7 @@ #include #include "../../kexec.h" #include "../../kexec-elf.h" -@@ -40,6 +42,137 @@ +@@ -40,6 +42,137 @@ extern struct arch_options_t arch_option /* Forward Declaration. */ static int exclude_crash_reserve_region(int *nr_ranges); @@ -671,7 +579,7 @@ /* Stores a sorted list of RAM memory ranges for which to create elf headers. * A separate program header is created for backup region */ static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES]; -@@ -245,7 +378,7 @@ +@@ -245,7 +378,7 @@ static int add_memmap(struct memory_rang memmap_p[j+1] = memmap_p[j]; memmap_p[tidx].start = addr; memmap_p[tidx].end = addr + size - 1; @@ -680,7 +588,7 @@ printf("Memmap after adding segment\n"); for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { mstart = memmap_p[i].start; -@@ -330,7 +463,7 @@ +@@ -330,7 +463,7 @@ static int delete_memmap(struct memory_r memmap_p[j-1] = memmap_p[j]; memmap_p[j-1].start = memmap_p[j-1].end = 0; } @@ -689,7 +597,7 @@ printf("Memmap after deleting segment\n"); for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { mstart = memmap_p[i].start; -@@ -404,7 +537,7 @@ +@@ -404,7 +537,7 @@ static int cmdline_add_memmap(char *cmdl die("Command line overflow\n"); strcat(cmdline, str_mmap); } @@ -698,7 +606,7 @@ printf("Command line after adding memmap\n"); printf("%s\n", cmdline); #endif -@@ -432,7 +565,7 @@ +@@ -432,7 +565,7 @@ static int cmdline_add_elfcorehdr(char * if (cmdlen > (COMMAND_LINE_SIZE - 1)) die("Command line overflow\n"); strcat(cmdline, str); @@ -707,7 +615,7 @@ printf("Command line after adding elfcorehdr\n"); printf("%s\n", cmdline); #endif -@@ -465,7 +598,7 @@ +@@ -465,7 +598,7 @@ static int cmdline_add_memmap_acpi(char die("Command line overflow\n"); strcat(cmdline, str_mmap); @@ -716,7 +624,7 @@ printf("Command line after adding acpi memmap\n"); printf("%s\n", cmdline); #endif -@@ -536,6 +669,27 @@ +@@ -536,6 +669,27 @@ static int prepare_crash_memory_elf64_he (elf->e_phnum)++; } @@ -744,7 +652,7 @@ /* Setup PT_LOAD type program header for every system RAM chunk. * A seprate program header for Backup Region*/ for (i = 0; i < CRASH_MAX_MEMORY_RANGES; i++) { -@@ -555,21 +709,13 @@ +@@ -555,21 +709,13 @@ static int prepare_crash_memory_elf64_he else phdr->p_offset = mstart; @@ -771,7 +679,7 @@ phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; /* Do we need any alignment of segments? */ phdr->p_align = 0; -@@ -593,6 +739,12 @@ +@@ -593,6 +739,12 @@ int load_crashdump_segments(struct kexec long int nr_cpus = 0; struct memory_range *mem_range, *memmap_p; @@ -784,7 +692,7 @@ if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0) return -1; -@@ -638,7 +790,7 @@ +@@ -638,7 +790,7 @@ int load_crashdump_segments(struct kexec * This is a makeshift solution until it is fixed in kernel. */ elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base, @@ -793,10 +701,21 @@ if (delete_memmap(memmap_p, elfcorehdr, sz) < 0) return -1; cmdline_add_memmap(mod_cmdline, memmap_p); ---- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2006-12-01 15:05:42.000000000 -0500 -@@ -56,7 +56,7 @@ +--- kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-rel-x86_64.c.orig 2004-12-21 12:51:24.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-rel-x86_64.c 2007-01-05 12:45:07.000000000 -0500 +@@ -60,7 +60,7 @@ static const char *reloc_name(unsigned l + void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, + void *location, unsigned long address, unsigned long value) { +-#if 0 ++#ifdef DEBUG + fprintf(stderr, "%s\n", reloc_name(r_type)); + #endif + switch(r_type) { +--- kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c 2007-01-05 12:45:07.000000000 -0500 +@@ -47,7 +47,7 @@ int elf_x86_64_probe(const char *buf, of + struct mem_ehdr ehdr; int result; - result = build_elf_exec_info(buf, len, &ehdr); @@ -804,27 +723,123 @@ if (result < 0) { if (probe_debug) { fprintf(stderr, "Not an ELF executable\n"); -@@ -163,7 +163,7 @@ +@@ -177,7 +177,7 @@ int elf_x86_64_load(int argc, char **arg + } + + /* Load the ELF executable */ +- elf_exec_build_load(info, &ehdr, buf, len); ++ elf_exec_build_load(info, &ehdr, buf, len, 0); + + entry = ehdr.e_entry; + max_addr = elf_max_addr(&ehdr); +@@ -186,7 +186,7 @@ int elf_x86_64_load(int argc, char **arg + if (arg_style != ARG_STYLE_NONE) { + /* Load the setup code */ + elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, +- 0, ULONG_MAX, 1); ++ 0, ULONG_MAX, 1, 0); + } + if (arg_style == ARG_STYLE_NONE) { + info->entry = (void *)entry; +--- kexec-tools-1.101/kexec/arch/x86_64/kexec-x86_64.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/x86_64/kexec-x86_64.c 2007-01-05 12:45:07.000000000 -0500 +@@ -64,7 +64,7 @@ int get_memory_ranges(struct memory_rang + continue; + str = line + consumed; + end = end + 1; +-#if 0 ++#ifdef DEBUG + printf("%016Lx-%016Lx : %s", + start, end, str); + #endif +@@ -104,7 +104,7 @@ int get_memory_ranges(struct memory_rang + memory_range[memory_ranges].start = start; + memory_range[memory_ranges].end = end; + memory_range[memory_ranges].type = type; +-#if 0 ++#ifdef DEBUG + printf("%016Lx-%016Lx : %x\n", + start, end, type); + #endif +--- kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c 2007-01-05 12:45:07.000000000 -0500 +@@ -47,7 +47,7 @@ int elf_x86_probe(const char *buf, off_t + + struct mem_ehdr ehdr; + int result; +- result = build_elf_exec_info(buf, len, &ehdr); ++ result = build_elf_exec_info(buf, len, &ehdr, 0); + if (result < 0) { + if (probe_debug) { + fprintf(stderr, "Not an ELF executable\n"); +@@ -177,7 +177,7 @@ int elf_x86_load(int argc, char **argv, + } + + /* Load the ELF executable */ +- elf_exec_build_load(info, &ehdr, buf, len); ++ elf_exec_build_load(info, &ehdr, buf, len, 0); + + entry = ehdr.e_entry; + max_addr = elf_max_addr(&ehdr); +@@ -186,7 +186,7 @@ int elf_x86_load(int argc, char **argv, + if (arg_style != ARG_STYLE_NONE) { + /* Load the setup code */ + elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, +- 0, ULONG_MAX, 1); ++ 0, ULONG_MAX, 1, 0); + } + if (arg_style == ARG_STYLE_NONE) { + info->entry = (void *)entry; +--- kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c 2007-01-05 12:45:07.000000000 -0500 +@@ -209,10 +209,11 @@ int multiboot_x86_load(int argc, char ** + + + /* Load the ELF executable */ +- elf_exec_build_load(info, &ehdr, buf, len); ++ elf_exec_build_load(info, &ehdr, buf, len, 0); + + /* Load the setup code */ +- elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, 0, ULONG_MAX, 1); ++ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, 0, ++ ULONG_MAX, 1, 0); + + /* The first segment will contain the multiboot headers: + * ============= +--- kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c 2007-01-05 12:45:07.000000000 -0500 +@@ -175,7 +175,7 @@ int do_bzImage_load(struct kexec_info *i + * it's gdt. + */ + elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, +- 0x3000, 640*1024, -1); ++ 0x3000, 640*1024, -1, 0); + + /* The argument/parameter segment */ + setup_size = kern16_size + command_line_len; +--- kexec-tools-1.101/kexec/arch/ppc/kexec-elf-ppc.c.orig 2005-01-20 14:10:56.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/ppc/kexec-elf-ppc.c 2007-01-05 12:45:07.000000000 -0500 +@@ -72,7 +72,7 @@ int elf_ppc_probe(const char *buf, off_t + + struct mem_ehdr ehdr; + int result; +- result = build_elf_exec_info(buf, len, &ehdr); ++ result = build_elf_exec_info(buf, len, &ehdr, 0); + if (result < 0) { + goto out; + } +@@ -180,7 +180,7 @@ int elf_ppc_load(int argc, char **argv, } /* Parse the Elf file */ - result = build_elf_exec_info(buf, len, &ehdr); + result = build_elf_exec_info(buf, len, &ehdr, 0); if (result < 0) { - fprintf(stderr, "ELF parse failed\n"); free_elf_info(&ehdr); -@@ -198,7 +198,7 @@ - - /* Load the setup code */ - elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- 0x0, ULONG_MAX, -1); -+ 0x0, ULONG_MAX, -1, 0); - - - if (load_crashdump_segments(info, &ehdr, max_addr, 0, ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c 2006-12-01 15:05:42.000000000 -0500 -@@ -52,7 +52,7 @@ + return result; +--- kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c 2007-01-05 12:45:07.000000000 -0500 +@@ -52,7 +52,7 @@ int elf_ppc64_probe(const char *buf, off { struct mem_ehdr ehdr; int result; @@ -833,7 +848,7 @@ if (result < 0) { goto out; } -@@ -163,7 +163,7 @@ +@@ -163,7 +163,7 @@ int elf_ppc64_load(int argc, char **argv } /* Parse the Elf file */ @@ -842,7 +857,7 @@ if (result < 0) { free_elf_info(&ehdr); return result; -@@ -213,7 +213,7 @@ +@@ -213,7 +213,7 @@ int elf_ppc64_load(int argc, char **argv memcpy(seg_buf, purgatory, purgatory_size); seg_size = purgatory_size; elf_rel_build_load(info, &info->rhdr, (const char *)purgatory, @@ -851,39 +866,8 @@ /* Add a ram-disk to the current image * Note: Add the ramdisk after elf_rel_build_load ---- kexec-tools-1.101/kexec/kexec-elf-rel.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf-rel.c 2006-12-01 15:05:42.000000000 -0500 -@@ -135,10 +135,11 @@ - return rela; - } - --int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr) -+int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) - { - int result; -- result = build_elf_info(buf, len, ehdr); -+ result = build_elf_info(buf, len, ehdr, flags); - if (result < 0) { - return result; - } -@@ -412,12 +413,12 @@ - - void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, - const char *buf, off_t len, unsigned long min, unsigned long max, -- int end) -+ int end, uint32_t flags) - { - int result; - - /* Parse the Elf file */ -- result = build_elf_rel_info((char *)purgatory, purgatory_size, ehdr); -+ result = build_elf_rel_info(buf, len, ehdr, flags); - if (result < 0) { - die("ELF rel parse failed\n"); - } ---- /dev/null 2006-11-22 10:18:18.589138000 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf-core.c 2006-12-01 15:05:42.000000000 -0500 +--- /dev/null 2006-12-27 08:05:56.458406418 -0500 ++++ kexec-tools-1.101/kexec/kexec-elf-core.c 2007-01-05 12:45:07.000000000 -0500 @@ -0,0 +1,29 @@ +#include +#include @@ -914,107 +898,9 @@ + + return 0; +} ---- kexec-tools-1.101/kexec/crashdump.h.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/crashdump.h 2006-12-01 15:05:42.000000000 -0500 -@@ -5,5 +5,7 @@ - - /* Need to find a better way to determine per cpu notes section size. */ - #define MAX_NOTE_BYTES 1024 -+/* Expecting ELF headers to fit in 4K. Increase it if you need more. */ -+#define KCORE_ELF_HEADERS_SIZE 4096 - - #endif /* CRASHDUMP_H */ ---- kexec-tools-1.101/kexec/kexec-elf.c.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf.c 2006-12-01 15:05:42.000000000 -0500 -@@ -368,7 +368,8 @@ - return 0; - } - --static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) -+static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) - { - size_t phdr_size, mem_phdr_size; - int i; -@@ -418,9 +419,11 @@ - - /* Check the program headers to be certain - * they are safe to use. -+ * Skip the check if ELF_SKIP_FILESZ_CHECK is set. - */ - phdr = &ehdr->e_phdr[i]; -- if ((phdr->p_offset + phdr->p_filesz) > len) { -+ if (!(flags & ELF_SKIP_FILESZ_CHECK) -+ && (phdr->p_offset + phdr->p_filesz) > len) { - /* The segment does not fit in the buffer */ - if (probe_debug) { - fprintf(stderr, "ELF segment not in file\n"); -@@ -580,7 +583,8 @@ - return 0; - } - --static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) -+static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) - { - size_t shdr_size, mem_shdr_size; - int i; -@@ -628,11 +632,12 @@ - } - /* Check the section headers to be certain - * they are safe to use. -+ * Skip the check if ELF_SKIP_FILESZ_CHECK is set. - */ - shdr = &ehdr->e_shdr[i]; -- if ((shdr->sh_type != SHT_NOBITS) && -- ((shdr->sh_offset + shdr->sh_size) > len)) -- { -+ if (!(flags & ELF_SKIP_FILESZ_CHECK) -+ && (shdr->sh_type != SHT_NOBITS) -+ && (shdr->sh_offset + shdr->sh_size) > len) { - /* The section does not fit in the buffer */ - if (probe_debug) { - fprintf(stderr, "ELF section %d not in file\n", -@@ -710,7 +715,8 @@ - note_size += (hdr.n_descsz + 3) & ~3; - - if ((hdr.n_namesz != 0) && (name[hdr.n_namesz -1] != '\0')) { -- die("Note name is not null termiated"); -+ fprintf(stderr, "Note name is not null termiated\n"); -+ return -1; - } - ehdr->e_note[i].n_type = hdr.n_type; - ehdr->e_note[i].n_name = (char *)name; -@@ -729,7 +735,8 @@ - memset(ehdr, 0, sizeof(*ehdr)); - } - --int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr) -+int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) - { - int result; - result = build_mem_ehdr(buf, len, ehdr); -@@ -737,14 +744,14 @@ - return result; - } - if ((ehdr->e_phoff > 0) && (ehdr->e_phnum > 0)) { -- result = build_mem_phdrs(buf, len, ehdr); -+ result = build_mem_phdrs(buf, len, ehdr, flags); - if (result < 0) { - free_elf_info(ehdr); - return result; - } - } - if ((ehdr->e_shoff > 0) && (ehdr->e_shnum > 0)) { -- result = build_mem_shdrs(buf, len, ehdr); -+ result = build_mem_shdrs(buf, len, ehdr, flags); - if (result < 0) { - free_elf_info(ehdr); - return result; ---- kexec-tools-1.101/kexec/kexec-elf.h.orig 2006-12-01 15:05:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf.h 2006-12-01 15:05:42.000000000 -0500 -@@ -82,22 +82,29 @@ +--- kexec-tools-1.101/kexec/kexec-elf.h.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/kexec-elf.h 2007-01-05 12:45:07.000000000 -0500 +@@ -82,22 +82,29 @@ typedef struct uint32_t n_type; /* Type of the note. */ } ElfNN_Nhdr; @@ -1049,3 +935,117 @@ extern int elf_rel_find_symbol(struct mem_ehdr *ehdr, const char *name, struct mem_sym *ret_sym); +--- kexec-tools-1.101/kexec/kexec-elf-exec.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/kexec-elf-exec.c 2007-01-05 12:45:07.000000000 -0500 +@@ -11,11 +11,12 @@ + + static const int probe_debug = 0; + +-int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr) ++int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr, ++ uint32_t flags) + { + struct mem_phdr *phdr, *end_phdr; + int result; +- result = build_elf_info(buf, len, ehdr); ++ result = build_elf_info(buf, len, ehdr, flags); + if (result < 0) { + return result; + } +@@ -136,11 +137,11 @@ int elf_exec_load(struct mem_ehdr *ehdr, + } + + void elf_exec_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, +- const char *buf, off_t len) ++ const char *buf, off_t len, uint32_t flags) + { + int result; + /* Parse the Elf file */ +- result = build_elf_exec_info(buf, len, ehdr); ++ result = build_elf_exec_info(buf, len, ehdr, flags); + if (result < 0) { + die("ELF exec parse failed\n"); + } +--- kexec-tools-1.101/kexec/crashdump.h.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/crashdump.h 2007-01-05 12:45:07.000000000 -0500 +@@ -5,5 +5,7 @@ extern int get_crash_notes_per_cpu(int c + + /* Need to find a better way to determine per cpu notes section size. */ + #define MAX_NOTE_BYTES 1024 ++/* Expecting ELF headers to fit in 4K. Increase it if you need more. */ ++#define KCORE_ELF_HEADERS_SIZE 4096 + + #endif /* CRASHDUMP_H */ +--- kexec-tools-1.101/kexec/kexec.h.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/kexec.h 2007-01-05 12:45:07.000000000 -0500 +@@ -116,6 +116,9 @@ struct kexec_info { + struct mem_ehdr rhdr; + unsigned long backup_start; + unsigned long kexec_flags; ++ unsigned long kern_vaddr_start; ++ unsigned long kern_paddr_start; ++ unsigned long kern_size; + }; + + void usage(void); +@@ -177,6 +180,7 @@ extern void die(char *fmt, ...); + extern void *xmalloc(size_t size); + extern void *xrealloc(void *ptr, size_t size); + extern char *slurp_file(const char *filename, off_t *r_size); ++extern char *slurp_file_len(const char *filename, off_t size); + extern char *slurp_decompress_file(const char *filename, off_t *r_size); + extern void add_segment(struct kexec_info *info, + const void *buf, size_t bufsz, unsigned long base, size_t memsz); +--- kexec-tools-1.101/kexec/kexec.c.orig 2007-01-05 11:15:00.000000000 -0500 ++++ kexec-tools-1.101/kexec/kexec.c 2007-01-05 12:45:07.000000000 -0500 +@@ -391,6 +391,50 @@ char *slurp_file(const char *filename, o + return buf; + } + ++/* This functions reads either specified number of bytes from the file or ++ lesser if EOF is met. */ ++ ++char *slurp_file_len(const char *filename, off_t size) ++{ ++ int fd; ++ char *buf; ++ off_t progress; ++ ssize_t result; ++ ++ if (!filename) ++ return 0; ++ fd = open(filename, O_RDONLY); ++ if (fd < 0) { ++ fprintf(stderr, "Cannot open %s: %s\n", filename, ++ strerror(errno)); ++ return 0; ++ } ++ buf = xmalloc(size); ++ progress = 0; ++ while(progress < size) { ++ result = read(fd, buf + progress, size - progress); ++ if (result < 0) { ++ if ((errno == EINTR) || (errno == EAGAIN)) ++ continue; ++ fprintf(stderr, "read on %s of %ld bytes failed: %s\n", ++ filename, (size - progress)+ 0UL, ++ strerror(errno)); ++ free(buf); ++ return 0; ++ } ++ if (result == 0) ++ /* EOF */ ++ break; ++ progress += result; ++ } ++ result = close(fd); ++ if (result < 0) { ++ die("Close of %s failed: %s\n", ++ filename, strerror(errno)); ++ } ++ return buf; ++} ++ + #if HAVE_ZLIB_H + char *slurp_decompress_file(const char *filename, off_t *r_size) + { diff --git a/kexec-tools-1.101-relocatable-bzimage.patch b/kexec-tools-1.101-relocatable-bzimage.patch new file mode 100644 index 0000000..62dc7ec --- /dev/null +++ b/kexec-tools-1.101-relocatable-bzimage.patch @@ -0,0 +1,172 @@ +--- kexec-tools-1.101/include/x86/x86-linux.h.orig 2004-12-20 05:10:21.000000000 -0500 ++++ kexec-tools-1.101/include/x86/x86-linux.h 2007-01-05 11:05:30.000000000 -0500 +@@ -141,7 +141,10 @@ struct x86_linux_param_header { + uint32_t high_filesz; /* 0x254 */ + uint8_t reserved15[0x2d0 - 0x258]; /* 0x258 */ + #else +- uint8_t reserved15[0x2d0 - 0x230]; /* 0x230 */ ++ /* 2.04+ */ ++ uint32_t kernel_alignment; /* 0x230 */ ++ uint8_t relocatable_kernel; /* 0x234 */ ++ uint8_t reserved15[0x2d0 - 0x235]; /* 0x230 */ + #endif + struct e820entry e820_map[E820MAX]; /* 0x2d0 */ + /* 0x550 */ +@@ -201,12 +204,15 @@ struct x86_linux_header { + uint32_t high_filesz; /* 0x254 */ + uint32_t tail[32*1024 - 0x258]; /* 0x258 */ + #else +- uint8_t tail[32*1024 - 0x230]; /* 0x230 */ ++ uint32_t kernel_alignment; /* 0x230 */ ++ uint8_t relocatable_kernel; /* 0x234 */ ++ uint8_t tail[32*1024 - 0x235]; /* 0x230 */ + #endif + } PACKED; + + #endif /* ASSEMBLY */ + + #define DEFAULT_INITRD_ADDR_MAX 0x37FFFFFF ++#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF + + #endif /* X86_LINUX_H */ +--- kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c.orig 2007-01-05 11:05:11.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c 2007-01-05 11:05:30.000000000 -0500 +@@ -680,7 +680,9 @@ int load_crashdump_segments(struct kexec + tmp = xmalloc(sz); + memset(tmp, 0, sz); + info->backup_start = add_buffer(info, tmp, sz, sz, align, +- 0, max_addr, 1); ++ 0, max_addr, -1); ++ dfprintf(stdout, "Created backup segment at 0x%lx\n", ++ info->backup_start); + if (delete_memmap(memmap_p, info->backup_start, sz) < 0) + return -1; + +@@ -719,7 +721,8 @@ int load_crashdump_segments(struct kexec + * This is a makeshift solution until it is fixed in kernel. + */ + elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base, +- max_addr, 1); ++ max_addr, -1); ++ dfprintf(stdout, "Created elf header segment at 0x%lx\n", elfcorehdr); + if (delete_memmap(memmap_p, elfcorehdr, sz) < 0) + return -1; + cmdline_add_memmap(mod_cmdline, memmap_p); +--- kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.c.orig 2007-01-05 11:05:11.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.c 2007-01-05 11:05:30.000000000 -0500 +@@ -59,6 +59,7 @@ void setup_linux_bootloader_parameters( + initrd_addr_max = DEFAULT_INITRD_ADDR_MAX; + if (real_mode->protocol_version >= 0x0203) { + initrd_addr_max = real_mode->initrd_addr_max; ++ dfprintf(stdout, "initrd_addr_max is 0x%lx\n", initrd_addr_max); + } + + /* Load the initrd if we have one */ +@@ -66,6 +67,8 @@ void setup_linux_bootloader_parameters( + initrd_base = add_buffer(info, + initrd_buf, initrd_size, initrd_size, + 4096, INITRD_BASE, initrd_addr_max, -1); ++ dfprintf(stdout, "Loaded initrd at 0x%lx size 0x%lx\n", ++ initrd_base, initrd_size); + } else { + initrd_base = 0; + initrd_size = 0; +--- kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c.orig 2007-01-05 11:05:11.000000000 -0500 ++++ kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c 2007-01-05 11:07:04.000000000 -0500 +@@ -34,8 +34,10 @@ + #include + #include "../../kexec.h" + #include "../../kexec-elf.h" ++#include "../../kexec-syscall.h" + #include "kexec-x86.h" + #include "x86-linux-setup.h" ++#include "crashdump-x86.h" + #include + + static const int probe_debug = 0; +@@ -109,6 +111,7 @@ int do_bzImage_load(struct kexec_info *i + unsigned long setup_base, setup_size; + struct entry32_regs regs32; + struct entry16_regs regs16; ++ char *modified_cmdline; + + /* + * Find out about the file I am about to load. +@@ -128,6 +131,45 @@ int do_bzImage_load(struct kexec_info *i + return -1; + } + ++ /* Can't use bzImage for crash dump purposes with real mode entry */ ++ if((info->kexec_flags & KEXEC_ON_CRASH) && real_mode_entry) { ++ fprintf(stderr, "Can't use bzImage for crash dump purposes" ++ " with real mode entry\n"); ++ return -1; ++ } ++ ++ if((info->kexec_flags & KEXEC_ON_CRASH) && !relocatable_kernel) { ++ fprintf(stderr, "BzImage is not relocatable. Can't be used" ++ " as capture kernel.\n"); ++ return -1; ++ } ++ ++ /* Need to append some command line parameters internally in case of ++ * taking crash dumps. ++ */ ++ if (info->kexec_flags & KEXEC_ON_CRASH) { ++ modified_cmdline = xmalloc(COMMAND_LINE_SIZE); ++ memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); ++ if (command_line) { ++ strncpy(modified_cmdline, command_line, ++ COMMAND_LINE_SIZE); ++ modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; ++ } ++ ++ /* If panic kernel is being loaded, additional segments need ++ * to be created. load_crashdump_segments will take care of ++ * loading the segments as high in memory as possible, hence ++ * in turn as away as possible from kernel to avoid being ++ * stomped by the kernel. ++ */ ++ if (load_crashdump_segments(info, modified_cmdline, -1, 0) < 0) ++ return -1; ++ ++ /* Use new command line buffer */ ++ command_line = modified_cmdline; ++ command_line_len = strlen(command_line) +1; ++ } ++ + /* Load the trampoline. This must load at a higher address + * the the argument/parameter segment or the kernel will stomp + * it's gdt. +@@ -139,7 +181,16 @@ int do_bzImage_load(struct kexec_info *i + setup_size = kern16_size + command_line_len; + real_mode = xmalloc(setup_size); + memcpy(real_mode, kernel, kern16_size); +- if (real_mode->protocol_version >= 0x0200) { ++ ++ if (info->kexec_flags & KEXEC_ON_CRASH) { ++ /* If using bzImage for capture kernel, then we will not be ++ * executing real mode code. setup segment can be loaded ++ * anywhere as we will be just reading command line. ++ */ ++ setup_base = add_buffer(info, real_mode, setup_size, setup_size, ++ 16, 0x3000, -1, 1); ++ } ++ else if (real_mode->protocol_version >= 0x0200) { + /* Careful setup_base must be greater than 8K */ + setup_base = add_buffer(info, real_mode, setup_size, setup_size, + 16, 0x3000, 640*1024, -1); +--- kexec-tools-1.101/kexec/kexec.h.orig 2007-01-05 11:05:11.000000000 -0500 ++++ kexec-tools-1.101/kexec/kexec.h 2007-01-05 11:05:30.000000000 -0500 +@@ -197,4 +197,11 @@ int arch_compat_trampoline(struct kexec_ + void arch_update_purgatory(struct kexec_info *info); + + #define MAX_LINE 160 ++ ++#ifdef DEBUG ++#define dfprintf(args...) do {fprintf(args);} while(0) ++#else ++#define dfprintf(args...) do { } while(0) ++#endif ++ + #endif /* KEXEC_H */