diff -Napur -X /home/jbarnes/dontdiff kexec-tools-1.95.orig/kexec/kexec-ia64.c kexec-tools-1.95-ia64/kexec/kexec-ia64.c --- kexec-tools-1.95.orig/kexec/kexec-ia64.c 1969-12-31 16:00:00.000000000 -0800 +++ kexec-tools-1.95-ia64/kexec/kexec-ia64.c 2004-07-27 14:15:33.000000000 -0700 @@ -0,0 +1,304 @@ +/* + * kexec: Linux boots Linux + * + * Copyright (C) 2003,2004 Eric Biederman (ebiederm@xmission.com) + * Copyright (C) 2004 Albert Herranz + * Copyright (C) 2004 Silicon Graphics, Inc. + * Jesse Barnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation (version 2 of the License). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kexec.h" + +#define MAX_MEMORY_RANGES 64 +#define MAX_LINE 160 +static struct memory_range memory_range[MAX_MEMORY_RANGES]; + +static int debug = 0; + +#define BOOTLOADER "kexec" +#define BOOTLOADER_VERSION VERSION +#define MAX_COMMAND_LINE 256 + +/* + * elf64_ia64_probe - sanity check the elf image + * + * Make sure that the file image has a reasonable chance of working. + */ +int elf64_ia64_probe(FILE * file) +{ + Elf64_Ehdr ehdr; + if (fseek(file, 0, SEEK_SET) < 0) { + fprintf(stderr, "seek error: %s\n", strerror(errno)); + return -1; + } + if (fread(&ehdr, sizeof(ehdr), 1, file) != 1) { + if (debug) { + fprintf(stderr, "File too short.\n"); + } + return 0; + } + if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) { + /* No ELF header */ + if (debug) { + fprintf(stderr, "No ELF header.\n"); + } + return 0; + } + if (ehdr.e_ident[EI_CLASS] != ELFCLASS64) { + /* Not a 64bit ELF file */ + if (debug) { + fprintf(stderr, "Not a 64bit ELF file.\n"); + } + return 0; + } + if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) { + /* not a little endian ELF file */ + if (debug) { + fprintf(stderr, "Not a little endian ELF file.\n"); + } + return 0; + } + if ((ehdr.e_ident[EI_VERSION] != EV_CURRENT) || + (ehdr.e_version != EV_CURRENT)) { + /* unkown elf version */ + if (debug) { + fprintf(stderr, "Unknown ELF file version.\n"); + } + return 0; + } + if (ehdr.e_type != ET_EXEC) { + /* not an ELF executable */ + if (debug) { + fprintf(stderr, "Not an ELF executable.\n"); + } + return 0; + } + + if (ehdr.e_ehsize != sizeof(Elf64_Ehdr)) { + /* invalid ELF header size */ + if (debug) { + fprintf(stderr, "Invalid ELF header size.\n"); + } + return 0; + } + if (ehdr.e_phentsize != sizeof(Elf64_Phdr)) { + /* invalid program header size */ + if (debug) { + fprintf(stderr, "Invalid program header size.\n"); + } + return 0; + } + if ((ehdr.e_phoff == 0) || (ehdr.e_phnum == 0)) { + /* no program header */ + if (debug) { + fprintf(stderr, "No program header.\n"); + } + return 0; + } + /* Verify the architecuture specific bits */ + if (ehdr.e_machine != EM_IA_64) { + /* for a different architecture */ + if (debug) { + fprintf(stderr, "Not for this architecture.\n"); + } + return 0; + } + return 1; +} + +void elf64_ia64_usage(void) +{ + printf + ("-d, --debug Enable debugging to help spot a failure.\n" + " --command-line=STRING Set the kernel command line to STRING.\n" + " --append=STRING Set the kernel command line to STRING.\n"); +} + +int elf64_ia64_load(FILE * file, int argc, char **argv, + void **ret_entry, struct kexec_segment **ret_segments, + int *ret_nr_segments) +{ + Elf64_Ehdr ehdr; + Elf64_Phdr *phdr; + struct kexec_segment *segment; + int nr_segments; + size_t phdr_bytes; + const char *command_line; + int command_line_len; + unsigned long mstart; + char *buf; + size_t size; + int i; + int opt; +#define OPT_APPEND (OPT_MAX+0) + static const struct option options[] = { + KEXEC_OPTIONS + {"debug", 0, 0, OPT_DEBUG}, + {"command-line", 1, 0, OPT_APPEND}, + {"append", 1, 0, OPT_APPEND}, + {0, 0, 0, 0}, + }; + + static const char short_options[] = KEXEC_OPT_STR "d"; + + debug = 0; + command_line = 0; + while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { + switch (opt) { + default: + /* Ignore core options */ + if (opt < OPT_MAX) { + break; + } + case '?': + usage(); + return -1; + case OPT_DEBUG: + debug = 1; + break; + case OPT_APPEND: + command_line = optarg; + break; + } + } + command_line_len = 0; + if (command_line) { + command_line_len = strlen(command_line) + 1; + } + + /* Read in the Elf header */ + if (fseek(file, 0, SEEK_SET) != 0) { + fprintf(stderr, "seek error: %s\n", strerror(errno)); + return -1; + } + if (fread(&ehdr, sizeof(ehdr), 1, file) != 1) { + fprintf(stderr, "read error: %s\n", strerror(errno)); + return -1; + } + /* Read in the program header */ + phdr_bytes = sizeof(*phdr) * ehdr.e_phnum; + phdr = malloc(phdr_bytes); + if (phdr == 0) { + fprintf(stderr, "malloc failed: %s\n", strerror(errno)); + return -1; + } + if (fseek(file, ehdr.e_phoff, SEEK_SET) != 0) { + fprintf(stderr, "seek error: %s\n", strerror(errno)); + return -1; + } + if (fread(phdr, phdr_bytes, 1, file) != 1) { + fprintf(stderr, "read error: %s\n", strerror(errno)); + return -1; + } + + /* Setup the segments */ + segment = malloc(sizeof(*segment) * (ehdr.e_phnum + 1)); + if (segment == 0) { + fprintf(stderr, "malloc failed: %s\n", strerror(errno)); + return -1; + } + + /* Skip the argument segment */ + nr_segments = 0; + segment[nr_segments].buf = 0; + segment[nr_segments].bufsz = 0; + segment[nr_segments].mem = 0; + segment[nr_segments].memsz = 0; + nr_segments++; + + /* Now all the rest of the segments */ + for (i = 0; i < ehdr.e_phnum; i++) { + if (phdr[i].p_type != PT_LOAD) { + continue; + } + size = phdr[i].p_filesz; + if (size > phdr[i].p_memsz) { + size = phdr[i].p_memsz; + } + buf = malloc(size); + if (buf == 0) { + fprintf(stderr, "malloc failed: %s\n", strerror(errno)); + return -1; + } + segment[nr_segments].buf = buf; + segment[nr_segments].bufsz = size; + mstart = phdr[i].p_paddr; + segment[nr_segments].mem = (void *)mstart; + segment[nr_segments].memsz = phdr[i].p_memsz; + if (valid_memory_range(segment + nr_segments) < 0) { + fprintf(stderr, "Invalid memory segment %p - %p\n", + segment[nr_segments].mem, + ((char *)segment[nr_segments].mem) + + segment[nr_segments].memsz); + return -1; + } + nr_segments++; + if (size == 0) { + /* Don't do file I/O if there is nothing in the file */ + continue; + } + if (fseek(file, phdr[i].p_offset, SEEK_SET) != 0) { + fprintf(stderr, "seek failed: %s\n", strerror(errno)); + return -1; + } + if (fread(buf, size, 1, file) != 1) { + fprintf(stderr, "Read failed: %s\n", strerror(errno)); + return -1; + } + } + + /* Generate and setup the argument segment */ + if (sort_segments(segment, nr_segments) < 0) { + return -1; + } + + if (locate_arguments(segment, nr_segments, 4, ~0UL) < 0) { + return -1; + } + + *ret_entry = segment[0].mem; + *ret_nr_segments = nr_segments; + *ret_segments = segment; + return 0; +} + +/* Return a sorted list of available memory ranges. */ +int get_memory_ranges(struct memory_range **range, int *ranges) +{ + return 0; +} + +/* Supported file types and callbacks */ +struct file_type file_type[] = { + {"elf64-ia64", elf64_ia64_probe, elf64_ia64_load, elf64_ia64_usage}, +}; +int file_types = sizeof(file_type) / sizeof(file_type[0]); diff -Napur -X /home/jbarnes/dontdiff kexec-tools-1.95.orig/kexec/Makefile kexec-tools-1.95-ia64/kexec/Makefile --- kexec-tools-1.95.orig/kexec/Makefile 2004-07-09 11:26:43.000000000 -0700 +++ kexec-tools-1.95-ia64/kexec/Makefile 2004-07-27 14:08:25.000000000 -0700 @@ -17,6 +17,10 @@ endif ifeq ($(ARCH),ppc64) KEXEC_C_SRCS+= kexec/kexec-zImage-ppc64.c endif +ifeq ($(ARCH),ia64) +KEXEC_C_SRCS+= kexec/kexec-ia64.c +KEXEC_C_SRCS+= kexec/ifdown.c +endif KEXEC_C_OBJS:= $(patsubst %.c, $(OBJDIR)/%.o, $(KEXEC_C_SRCS)) KEXEC_C_DEPS:= $(patsubst %.c, $(OBJDIR)/%.d, $(KEXEC_C_SRCS)) diff -Napur -X /home/jbarnes/dontdiff kexec-tools-1.95.orig/Makefile.main kexec-tools-1.95-ia64/Makefile.main --- kexec-tools-1.95.orig/Makefile.main 2004-07-09 11:21:21.000000000 -0700 +++ kexec-tools-1.95-ia64/Makefile.main 2004-07-27 11:03:19.000000000 -0700 @@ -21,6 +21,7 @@ MAN_PAGES:= BINARIES_i386:=$(SBINDIR)/kexec $(BINDIR)/kexec_test BINARIES_ppc:=$(SBINDIR)/kexec BINARIES_ppc64:=$(SBINDIR)/kexec +BINARIES_ia64:=$(SBINDIR)/kexec BINARIES:=$(BINARIES_$(ARCH)) TARGETS:=$(BINARIES) $(MAN_PAGES)