[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2015-8956, CVE-2016-5195, CVE-2016-8658, CVE-2016-7117, CVE-2016-0823, CVE-2016-7425, CVE-2016-6327, CVE-2016-6828, CVE-2016-5696, CVE-2016-6480, CVE-2015-7513, CVE-2016-1237

Fix "uptime" and "ps -t" for SLES9

## Package
crash

## Files to modify
- defs.h
- kernel.c
- task.c

## Target Source Code

### defs.h

#### region() [lines 636-742]
```c
#define GCC_3_3_3     (0x8000)
#define USE_OLD_BT   (0x10000)
#define USE_OPT_BT   (0x10000)
#define ARCH_XEN     (0x20000)
#define NO_IKCONFIG  (0x40000)
#define DWARF_UNWIND (0x80000)
#define NO_DWARF_UNWIND       (0x100000)
#define DWARF_UNWIND_MEMORY   (0x200000)
#define DWARF_UNWIND_EH_FRAME (0x400000)
#define DWARF_UNWIND_CAPABLE  (DWARF_UNWIND_MEMORY|DWARF_UNWIND_EH_FRAME)
#define DWARF_UNWIND_MODULES  (0x800000)
#define BUGVERBOSE_OFF       (0x1000000)
#define RELOC_SET            (0x2000000)
#define RELOC_FORCE          (0x4000000)
#define ARCH_OPENVZ          (0x8000000)
#define ARCH_PVOPS          (0x10000000)
#define PRE_KERNEL_INIT     (0x20000000)
#define ARCH_PVOPS_XEN      (0x40000000)

#define GCC_VERSION_DEPRECATED (GCC_3_2|GCC_3_2_3|GCC_2_96|GCC_3_3_2|GCC_3_3_3)

/* flags2 */
#define RELOC_AUTO                  (0x1ULL)
#define KASLR                       (0x2ULL)
#define KASLR_CHECK                 (0x4ULL)
#define GET_TIMESTAMP               (0x8ULL)
#define TVEC_BASES_V3              (0x10ULL)
#define TIMER_BASES                (0x20ULL)
#define IRQ_DESC_TREE_RADIX        (0x40ULL)
#define IRQ_DESC_TREE_XARRAY       (0x80ULL)
#define KMOD_PAX                  (0x100ULL)

#define XEN()       (kt->flags & ARCH_XEN)
#define OPENVZ()    (kt->flags & ARCH_OPENVZ)
#define PVOPS()     (kt->flags & ARCH_PVOPS)
#define PVOPS_XEN() (kt->flags & ARCH_PVOPS_XEN)

#define PAX_MODULE_SPLIT() (kt->flags2 & KMOD_PAX)

#define XEN_MACHINE_TO_MFN(m)    ((ulonglong)(m) >> PAGESHIFT())
#define XEN_PFN_TO_PSEUDO(p)     ((ulonglong)(p) << PAGESHIFT())

#define XEN_MFN_NOT_FOUND        (~0UL)
#define XEN_PFNS_PER_PAGE        (PAGESIZE()/sizeof(ulong))
#define XEN_FOREIGN_FRAME        (1UL << (BITS()-1))

#define XEN_MACHADDR_NOT_FOUND   (~0ULL)

#define XEN_P2M_PER_PAGE	(PAGESIZE() / sizeof(unsigned long))
#define XEN_P2M_MID_PER_PAGE	(PAGESIZE() / sizeof(unsigned long *))
#define XEN_P2M_TOP_PER_PAGE	(PAGESIZE() / sizeof(unsigned long **))

struct kernel_table {                   /* kernel data */
	ulong flags;
	ulong stext;
	ulong etext;
	ulong stext_init;
	ulong etext_init;
	ulong init_begin;
	ulong init_end;
	ulong end;
	int cpus;
	char *cpus_override;
	void (*display_bh)(void);
        ulong module_list;
        ulong kernel_module;
	int mods_installed;
	struct timespec date;
	char proc_version[BUFSIZE];
	struct new_utsname utsname;
	uint kernel_version[3];
	uint gcc_version[3];
	int runq_siblings;
	int kernel_NR_CPUS;
	long __per_cpu_offset[NR_CPUS];
	long *__rq_idx;
	long *__cpu_idx;
	ulong *cpu_flags;
#define POSSIBLE  (0x1)
#define PRESENT   (0x2)
#define ONLINE    (0x4)
#define NMI       (0x8)
#define POSSIBLE_MAP (POSSIBLE)
#define PRESENT_MAP   (PRESENT)
#define ONLINE_MAP     (ONLINE)
#define ACTIVE_MAP       (0x10)
	int BUG_bytes;
	ulong xen_flags;
#define WRITABLE_PAGE_TABLES    (0x1)
#define SHADOW_PAGE_TABLES      (0x2)
#define CANONICAL_PAGE_TABLES   (0x4)
#define XEN_SUSPEND             (0x8)
	char *m2p_page;
	ulong phys_to_machine_mapping;
	ulong p2m_table_size;
#define P2M_MAPPING_CACHE    (512)
	struct p2m_mapping_cache {
		ulong mapping;
		ulong pfn;
		ulong start;
		ulong end;
	} p2m_mapping_cache[P2M_MAPPING_CACHE];
#define P2M_MAPPING_PAGE_PFN(c) \
   (PVOPS_XEN() ? kt->p2m_mapping_cache[c].pfn : \
    (((kt->p2m_mapping_cache[c].mapping - kt->phys_to_machine_mapping)/PAGESIZE()) \
    * XEN_PFNS_PER_PAGE))
	ulong last_mapping_read;
```

#### region() [lines 5786-5892]
```c
	int fd;
	int flags;
	int type;
	long csum;
	off_t size;
};

#define REMOTE_VERBOSE   (O_RDWR << 1)
#define REMOTE_COPY_DONE (REMOTE_VERBOSE << 1)
#define TYPE_ELF         (REMOTE_VERBOSE << 2)
#define TYPE_DEVMEM      (REMOTE_VERBOSE << 3)
#define TYPE_MCLXCD      (REMOTE_VERBOSE << 4)
#define TYPE_LKCD        (REMOTE_VERBOSE << 5)
#define TYPE_S390D       (REMOTE_VERBOSE << 6)
#define TYPE_NETDUMP     (REMOTE_VERBOSE << 7)

ulonglong xen_m2p(ulonglong);

void read_in_kernel_config(int);

#define IKCFG_INIT   (0)
#define IKCFG_READ   (1)
#define IKCFG_SETUP  (2)
#define IKCFG_FREE   (3)

int get_kernel_config(char *, char **);
enum {
	IKCONFIG_N,
	IKCONFIG_Y,
	IKCONFIG_M,
	IKCONFIG_STR,
};

#define MAGIC_START  "IKCFG_ST"
#define MAGIC_END    "IKCFG_ED"
#define MAGIC_SIZE   (sizeof(MAGIC_START) - 1)

/*
 *  dev.c
 */
void dev_init(void);
void dump_dev_table(void);
void devdump_extract(void *, ulonglong, char *, FILE *);
void devdump_info(void *, ulonglong, FILE *);

/*
 *  ipcs.c
 */
void ipcs_init(void);
ulong idr_find(ulong, int);

#ifdef ARM
void arm_init(int);
void arm_dump_machdep_table(ulong);
int arm_is_vmalloc_addr(ulong);
void arm_dump_backtrace_entry(struct bt_info *, int, ulong, ulong);

#define display_idt_table() \
        error(FATAL, "-d option is not applicable to ARM architecture\n")

struct arm_pt_regs {
	ulong uregs[18];
};

#define ARM_cpsr	uregs[16]
#define ARM_pc		uregs[15]
#define ARM_lr		uregs[14]
#define ARM_sp		uregs[13]
#define ARM_ip		uregs[12]
#define ARM_fp		uregs[11]
#define ARM_r10		uregs[10]
#define ARM_r9		uregs[9]
#define ARM_r8		uregs[8]
#define ARM_r7		uregs[7]
#define ARM_r6		uregs[6]
#define ARM_r5		uregs[5]
#define ARM_r4		uregs[4]
#define ARM_r3		uregs[3]
#define ARM_r2		uregs[2]
#define ARM_r1		uregs[1]
#define ARM_r0		uregs[0]
#define ARM_ORIG_r0	uregs[17]

#define KSYMS_START	(0x1)
#define PHYS_BASE	(0x2)
#define PGTABLE_V2	(0x4)
#define IDMAP_PGD	(0x8)

#define KVBASE_MASK	(0x1ffffff)

struct machine_specific {
	ulong phys_base;
	ulong vmalloc_start_addr;
	ulong modules_vaddr;
	ulong modules_end;
	ulong kernel_text_start;
	ulong kernel_text_end;
	ulong exception_text_start;
	ulong exception_text_end;
	ulonglong last_pgd_read_lpae;
	ulonglong last_pmd_read_lpae;
	ulonglong last_ptbl_read_lpae;
	struct arm_pt_regs *crash_task_regs;
	int unwind_index_prel31;
};

int init_unwind_tables(void);
```

#### kernel_init() [lines 203-309]
```c
	ulong retflags;
};

/*
 *  program_context flags
 */
#define LIVE_SYSTEM                 (0x1ULL)
#define TTY                         (0x2ULL)
#define RUNTIME                     (0x4ULL)
#define IN_FOREACH                  (0x8ULL)
#define MCLXCD                     (0x10ULL)
#define CMDLINE_IFILE              (0x20ULL)
#define MFD_RDWR                   (0x40ULL)
#define KVMDUMP                    (0x80ULL)
#define SILENT                    (0x100ULL)
#define SADUMP                    (0x200ULL)
#define HASH                      (0x400ULL)
#define SCROLL                    (0x800ULL)
#define NO_CONSOLE               (0x1000ULL)
#define RUNTIME_IFILE            (0x2000ULL)
#define DROP_CORE                (0x4000ULL)
#define LKCD                     (0x8000ULL)
#define GDB_INIT                (0x10000ULL)
#define IN_GDB                  (0x20000ULL)
#define RCLOCAL_IFILE           (0x40000ULL)
#define RCHOME_IFILE            (0x80000ULL)
#define VMWARE_VMSS            (0x100000ULL)
#define READLINE               (0x200000ULL)
#define _SIGINT_               (0x400000ULL)
#define IN_RESTART             (0x800000ULL)
#define KERNEL_DEBUG_QUERY    (0x1000000ULL)
#define DEVMEM                (0x2000000ULL)
#define REM_LIVE_SYSTEM       (0x4000000ULL)
#define NAMELIST_LOCAL        (0x8000000ULL)
#define LIVE_RAMDUMP         (0x10000000ULL)
#define NAMELIST_SAVED       (0x20000000ULL)
#define DUMPFILE_SAVED       (0x40000000ULL)
#define UNLINK_NAMELIST      (0x80000000ULL)
#define NAMELIST_UNLINKED   (0x100000000ULL)
#define REM_MCLXCD          (0x200000000ULL)
#define REM_LKCD            (0x400000000ULL)
#define NAMELIST_NO_GZIP    (0x800000000ULL)
#define UNLINK_MODULES     (0x1000000000ULL)
#define S390D              (0x2000000000ULL)
#define REM_S390D          (0x4000000000ULL)
#define SYSRQ              (0x8000000000ULL)
#define KDUMP             (0x10000000000ULL)
#define NETDUMP           (0x20000000000ULL)
#define REM_NETDUMP       (0x40000000000ULL)
#define SYSMAP            (0x80000000000ULL)
#define SYSMAP_ARG       (0x100000000000ULL)
#define MEMMOD           (0x200000000000ULL)
#define MODPRELOAD       (0x400000000000ULL)
#define DISKDUMP         (0x800000000000ULL)
#define DATADEBUG       (0x1000000000000ULL)
#define FINDKERNEL      (0x2000000000000ULL)
#define VERSION_QUERY   (0x4000000000000ULL)
#define READNOW         (0x8000000000000ULL)
#define NOCRASHRC      (0x10000000000000ULL)
#define INIT_IFILE     (0x20000000000000ULL)
#define XENDUMP        (0x40000000000000ULL)
#define XEN_HYPER      (0x80000000000000ULL)
#define XEN_CORE      (0x100000000000000ULL)
#define PLEASE_WAIT   (0x200000000000000ULL)
#define IFILE_ERROR   (0x400000000000000ULL)
#define KERNTYPES     (0x800000000000000ULL)
#define MINIMAL_MODE (0x1000000000000000ULL)
#define CRASHBUILTIN (0x2000000000000000ULL)
#define PRELOAD_EXTENSIONS \
		     (0x4000000000000000ULL)
#define PROC_KCORE   (0x8000000000000000ULL)

#define ACTIVE()            (pc->flags & LIVE_SYSTEM)
#define LOCAL_ACTIVE()      ((pc->flags & (LIVE_SYSTEM|LIVE_RAMDUMP)) == LIVE_SYSTEM)
#define DUMPFILE()          (!(pc->flags & LIVE_SYSTEM))
#define LIVE()              (pc->flags2 & LIVE_DUMP || pc->flags & LIVE_SYSTEM)
#define MEMORY_SOURCES (NETDUMP|KDUMP|MCLXCD|LKCD|DEVMEM|S390D|MEMMOD|DISKDUMP|XENDUMP|CRASHBUILTIN|KVMDUMP|PROC_KCORE|SADUMP|VMWARE_VMSS|LIVE_RAMDUMP)
#define DUMPFILE_TYPES      (DISKDUMP|NETDUMP|KDUMP|MCLXCD|LKCD|S390D|XENDUMP|KVMDUMP|SADUMP|VMWARE_VMSS|LIVE_RAMDUMP)
#define REMOTE()            (pc->flags2 & REMOTE_DAEMON)
#define REMOTE_ACTIVE()     (pc->flags & REM_LIVE_SYSTEM)
#define REMOTE_DUMPFILE() \
	   (pc->flags & (REM_NETDUMP|REM_MCLXCD|REM_LKCD|REM_S390D))
#define REMOTE_MEMSRC()     (REMOTE_ACTIVE() || REMOTE_PAUSED() || REMOTE_DUMPFILE())
#define LKCD_DUMPFILE()     (pc->flags & (LKCD|REM_LKCD))
#define NETDUMP_DUMPFILE()  (pc->flags & (NETDUMP|REM_NETDUMP))
#define DISKDUMP_DUMPFILE() (pc->flags & DISKDUMP)
#define KDUMP_DUMPFILE()    (pc->flags & KDUMP)
#define XENDUMP_DUMPFILE()  (pc->flags & XENDUMP)
#define XEN_HYPER_MODE()    (pc->flags & XEN_HYPER)
#define SYSRQ_TASK(X)       ((pc->flags & SYSRQ) && is_task_active(X))
#define XEN_CORE_DUMPFILE() (pc->flags & XEN_CORE)
#define LKCD_KERNTYPES()    (pc->flags & KERNTYPES)
#define KVMDUMP_DUMPFILE()  (pc->flags & KVMDUMP)
#define SADUMP_DUMPFILE()  (pc->flags & SADUMP)
#define VMSS_DUMPFILE()     (pc->flags & VMWARE_VMSS)
#define QEMU_MEM_DUMP_NO_VMCOREINFO() \
	    ((pc->flags2 & (QEMU_MEM_DUMP_ELF|QEMU_MEM_DUMP_COMPRESSED)) && !(pc->flags2 & VMCOREINFO))

#define NETDUMP_LOCAL    (0x1)  /* netdump_data flags */
#define NETDUMP_REMOTE   (0x2)
#define VMCORE_VALID()   (nd->flags & (NETDUMP_LOCAL|NETDUMP_REMOTE|KDUMP_LOCAL))
#define NETDUMP_ELF32    (0x4)
#define NETDUMP_ELF64    (0x8)
#define PARTIAL_DUMP    (0x10)  /* netdump or diskdump */
#define KDUMP_ELF32     (0x20)
#define KDUMP_ELF64     (0x40)
```

#### get_uptime() [lines 4757-4864]
```c
#define GNU_ADD_SYMBOL_FILE         (11)
#define GNU_DELETE_SYMBOL_FILE      (12)
#define GNU_VERSION                 (13)
#define GNU_PATCH_SYMBOL_VALUES     (14)
#define GNU_GET_SYMBOL_TYPE         (15)
#define GNU_USER_PRINT_OPTION       (16)
#define GNU_SET_CRASH_BLOCK         (17)
#define GNU_GET_FUNCTION_RANGE      (18)
#define GNU_GET_NEXT_DATATYPE       (19)
#define GNU_LOOKUP_STRUCT_CONTENTS  (20)
#define GNU_DEBUG_COMMAND           (100)
/*
 *  GNU flags
 */
#define GNU_PRINT_LINE_NUMBERS   (0x1)
#define GNU_FUNCTION_ONLY        (0x2)
#define GNU_PRINT_ENUMERATORS    (0x4)
#define GNU_RETURN_ON_ERROR      (0x8)
#define GNU_COMMAND_FAILED      (0x10)
#define GNU_FROM_TTY_OFF        (0x20)
#define GNU_NO_READMEM          (0x40)
#define GNU_VAR_LENGTH_TYPECODE (0x80)

#undef TRUE
#undef FALSE

#define TRUE  (1)
#define FALSE (0)

#ifdef GDB_COMMON
/*
 *  function prototypes required by modified gdb source files.
 */
int console(char *, ...);
int gdb_CRASHDEBUG(ulong);
int gdb_readmem_callback(ulong, void *, int, int);
void patch_load_module(struct objfile *objfile, struct minimal_symbol *msymbol);
int patch_kernel_symbol(struct gnu_request *);
struct syment *symbol_search(char *);
int gdb_line_number_callback(ulong, ulong, ulong);
int gdb_print_callback(ulong);
#endif

#ifndef GDB_COMMON
/*
 *  WARNING: the following type codes are type_code enums from gdb/gdbtypes.h
 */
enum type_code {
  TYPE_CODE_UNDEF,              /* Not used; catches errors */
  TYPE_CODE_PTR,                /* Pointer type */
  TYPE_CODE_ARRAY,              /* Array type with lower & upper bounds. */
  TYPE_CODE_STRUCT,             /* C struct or Pascal record */
  TYPE_CODE_UNION,              /* C union or Pascal variant part */
  TYPE_CODE_ENUM,               /* Enumeration type */
#if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1) || defined(GDB_7_0) || defined(GD
/* ... truncated ... */
```

## Upstream Fix
```diff
From: Alan Tyson <atyson@hp.com>
Subject: [PATCH] Fix "uptime" and "ps -t" for SLES9
References: 352836

This patch adds a quirk for SLES9 jiffies initialisation and corrects the time
data in "uptime" and "ps -t" command.

Acked-by: Bernhard Walle <bwalle@suse.de>

---
 defs.h   |    8 ++++++++
 kernel.c |    9 ++++++++-
 task.c   |   11 +++++++++++
 3 files changed, 27 insertions(+), 1 deletion(-)

--- a/defs.h
+++ b/defs.h
@@ -685,6 +685,7 @@ struct kernel_table {
 		ulong p2m_missing;
 	} pvops_xen;
 	int highest_irq;
+    int is_suse_kernel;
 #define IKCONFIG_AVAIL	0x1	/* kernel contains ikconfig data */
 #define IKCONFIG_LOADED	0x2	/* ikconfig data is currently loaded */
 	int ikconfig_flags;
@@ -5835,6 +5836,13 @@ extern struct lkcd_environment *lkcd;

 #endif  /* LKCD_COMMON */

+
+/*
+ * SUSE specific
+ */
+#define is_SLES9() \
+	((THIS_KERNEL_VERSION == LINUX(2,6,5)) && kt->is_suse_kernel)
+
 /*
  *  gdb_interface.c
  */
--- a/kernel.c
+++ b/kernel.c
@@ -252,6 +252,12 @@ kernel_init()

 	verify_version();

+	/*
+	 * check if we have a suse kernel (this is the module supported
+	 * patch of agruen@suse.de
+	 */
+	kt->is_suse_kernel = symbol_exists("unsupported");
+
 	if (symbol_exists("__per_cpu_offset")) {
 		if (LKCD_KERNTYPES())
 			i = get_cpus_possible();
@@ -4806,7 +4812,7 @@ get_uptime(char *buf, ulonglong *j64p)

 	if (symbol_exists("jiffies_64")) {
 		get_symbol_data("jiffies_64", sizeof(ulonglong), &jiffies_64);
-		if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) {
+		if (THIS_KERNEL_VERSION >= LINUX(2,6,0) && !is_SLES9()) {
 			wrapped = (jiffies_64 & 0xffffffff00000000ULL);
 			if (wrapped) {
 				wrapped -= 0x100000000ULL;
@@ -5358,6 +5364,7 @@ no_cpu_flags:
 	if (symbol_exists("p2m_mid_missing"))
 		fprintf(fp, "            p2m_mid_missing: %lx\n", kt->pvops_xen.p2m_mid_missing);
 	fprintf(fp, "                p2m_missing: %lx\n", kt->pvops_xen.p2m_missing);
+	fprintf(fp, "         is_suse_kernel: %ld\n", kt->is_suse_kernel);
 }

 /*
--- a/task.c
+++ b/task.c
@@ -3669,6 +3669,12 @@ start_time_timespec(void)
 	default:
 		break;
 	}
+	/* SLES9 stores start_time in nanoseconds, so set TIMESPEC in order */
+	/* to do the right calculations in convert_start_time               */
+	if (is_SLES9()) {
+		tt->flags |= TIMESPEC;
+		return TRUE;
+	}

 	tt->flags |= NO_TIMESPEC;

@@ -3700,6 +3706,11 @@ convert_start_time(ulonglong start_time,
 	ulong tmp1, tmp2;
 	ulonglong wrapped;

+	/* SLES9's start_time is neither jiffies nor a timespec.  It's ns */
+	if (is_SLES9()) {
+		start_time = start_time / 1000000000;
+	}
+
         switch(tt->flags & (TIMESPEC | NO_TIMESPEC))
         {
         case TIMESPEC:

```

Generate a backported patch for the SUSE target version.

[Assistant]
From: Alan Tyson <atyson@hp.com>
Subject: [PATCH] Fix "uptime" and "ps -t" for SLES9
References: 352836

This patch adds a quirk for SLES9 jiffies initialisation and corrects the time
data in "uptime" and "ps -t" command.

Acked-by: Bernhard Walle <bwalle@suse.de>

---
 defs.h   |    8 ++++++++
 kernel.c |    9 ++++++++-
 task.c   |   11 +++++++++++
 3 files changed, 27 insertions(+), 1 deletion(-)

--- a/defs.h
+++ b/defs.h
@@ -685,6 +685,7 @@ struct kernel_table {
 		ulong p2m_missing;
 	} pvops_xen;
 	int highest_irq;
+    int is_suse_kernel;
 #define IKCONFIG_AVAIL	0x1	/* kernel contains ikconfig data */
 #define IKCONFIG_LOADED	0x2	/* ikconfig data is currently loaded */
 	int ikconfig_flags;
@@ -5835,6 +5836,13 @@ extern struct lkcd_environment *lkcd;

 #endif  /* LKCD_COMMON */

+
+/*
+ * SUSE specific
+ */
+#define is_SLES9() \
+	((THIS_KERNEL_VERSION == LINUX(2,6,5)) && kt->is_suse_kernel)
+
 /*
  *  gdb_interface.c
  */
--- a/kernel.c
+++ b/kernel.c
@@ -252,6 +252,12 @@ kernel_init()

 	verify_version();

+	/*
+	 * check if we have a suse kernel (this is the module supported
+	 * patch of agruen@suse.de
+	 */
+	kt->is_suse_kernel = symbol_exists("unsupported");
+
 	if (symbol_exists("__per_cpu_offset")) {
 		if (LKCD_KERNTYPES())
 			i = get_cpus_possible();
@@ -4806,7 +4812,7 @@ get_uptime(char *buf, ulonglong *j64p)

 	if (symbol_exists("jiffies_64")) {
 		get_symbol_data("jiffies_64", sizeof(ulonglong), &jiffies_64);
-		if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) {
+		if (THIS_KERNEL_VERSION >= LINUX(2,6,0) && !is_SLES9()) {
 			wrapped = (jiffies_64 & 0xffffffff00000000ULL);
 			if (wrapped) {
 				wrapped -= 0x100000000ULL;
@@ -5358,6 +5364,7 @@ no_cpu_flags:
 	if (symbol_exists("p2m_mid_missing"))
 		fprintf(fp, "            p2m_mid_missing: %lx\n", kt->pvops_xen.p2m_mid_missing);
 	fprintf(fp, "                p2m_missing: %lx\n", kt->pvops_xen.p2m_missing);
+	fprintf(fp, "         is_suse_kernel: %ld\n", kt->is_suse_kernel);
 }

 /*
--- a/task.c
+++ b/task.c
@@ -3669,6 +3669,12 @@ start_time_timespec(void)
 	default:
 		break;
 	}
+	/* SLES9 stores start_time in nanoseconds, so set TIMESPEC in order */
+	/* to do the right calculations in convert_start_time               */
+	if (is_SLES9()) {
+		tt->flags |= TIMESPEC;
+		return TRUE;
+	}

 	tt->flags |= NO_TIMESPEC;

@@ -3700,6 +3706,11 @@ convert_start_time(ulonglong start_time,
 	ulong tmp1, tmp2;
 	ulonglong wrapped;

+	/* SLES9's start_time is neither jiffies nor a timespec.  It's ns */
+	if (is_SLES9()) {
+		start_time = start_time / 1000000000;
+	}
+
         switch(tt->flags & (TIMESPEC | NO_TIMESPEC))
         {
         case TIMESPEC:


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2015-8956, CVE-2016-5195, CVE-2016-8658, CVE-2016-7117, CVE-2016-0823, CVE-2016-7425, CVE-2016-6327, CVE-2016-6828, CVE-2016-5696, CVE-2016-6480, CVE-2015-7513, CVE-2016-1237

CFLAGS.extra  |    1 +

## Package
crash

## Files to modify
- b/CFLAGS.extra
- b/LDFLAGS.extra

## Upstream Fix
```diff
---
 CFLAGS.extra  |    1 +
 LDFLAGS.extra |    1 +
 2 files changed, 2 insertions(+)

Index: b/CFLAGS.extra
===================================================================
--- /dev/null
+++ b/CFLAGS.extra
@@ -0,0 +1 @@
+-DLZO
Index: b/LDFLAGS.extra
===================================================================
--- /dev/null
+++ b/LDFLAGS.extra
@@ -0,0 +1 @@
+-llzo2

```

Generate a backported patch for the SUSE target version.

[Assistant]
---
 CFLAGS.extra  |    1 +
 LDFLAGS.extra |    1 +
 2 files changed, 2 insertions(+)

Index: b/CFLAGS.extra
===================================================================
--- /dev/null
+++ b/CFLAGS.extra
@@ -0,0 +1 @@
+-DLZO
Index: b/LDFLAGS.extra
===================================================================
--- /dev/null
+++ b/LDFLAGS.extra
@@ -0,0 +1 @@
+-llzo2


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2015-8956, CVE-2016-5195, CVE-2016-8658, CVE-2016-7117, CVE-2016-0823, CVE-2016-7425, CVE-2016-6327, CVE-2016-6828, CVE-2016-5696, CVE-2016-6480, CVE-2015-7513, CVE-2016-1237

From: Petr Tesarik <ptesarik@suse.cz>

## Package
crash

## Files to modify
- CFLAGS.extra
- LDFLAGS.extra

## Upstream Fix
```diff
From: Petr Tesarik <ptesarik@suse.cz>
Subject: enably snappy support
Patch-mainline: never, configurable default

Signed-off-by: Petr Tesarik <ptesarik@suse.cz>

---
 CFLAGS.extra  |    2 +-
 LDFLAGS.extra |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

--- a/CFLAGS.extra
+++ b/CFLAGS.extra
@@ -1 +1 @@
--DLZO
+-DLZO -DSNAPPY
--- a/LDFLAGS.extra
+++ b/LDFLAGS.extra
@@ -1 +1 @@
--llzo2
+-llzo2 -lsnappy

```

Generate a backported patch for the SUSE target version.

[Assistant]
From: Petr Tesarik <ptesarik@suse.cz>
Subject: enably snappy support
Patch-mainline: never, configurable default

Signed-off-by: Petr Tesarik <ptesarik@suse.cz>

---
 CFLAGS.extra  |    2 +-
 LDFLAGS.extra |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

--- a/CFLAGS.extra
+++ b/CFLAGS.extra
@@ -1 +1 @@
--DLZO
+-DLZO -DSNAPPY
--- a/LDFLAGS.extra
+++ b/LDFLAGS.extra
@@ -1 +1 @@
--llzo2
+-llzo2 -lsnappy


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2015-8956, CVE-2016-5195, CVE-2016-8658, CVE-2016-7117, CVE-2016-0823, CVE-2016-7425, CVE-2016-6327, CVE-2016-6828, CVE-2016-5696, CVE-2016-6480, CVE-2015-7513, CVE-2016-1237

eppic/applications/crash/eppic.c | 1110 +++++++++++++++++++++++++++++++++++++++

## Package
crash

## Files to modify
- b/extensions/eppic.mk
- b/extensions/eppic/applications/crash/eppic.c

## Upstream Fix
```diff
---
 eppic/applications/crash/eppic.c | 1110 +++++++++++++++++++++++++++++++++++++++
 extensions/eppic.mk              |   26
 2 files changed, 1112 insertions(+), 24 deletions(-)

Index: b/extensions/eppic.mk
===================================================================
--- a/extensions/eppic.mk
+++ b/extensions/eppic.mk
@@ -28,29 +28,7 @@ all:
 	@if [ -f /usr/bin/flex ] && [ -f /usr/bin/bison ]; then \
 	  if [ -f ../$(GDB)/crash.target ]; \
         then \
-        if  [ ! -f $(APPFILE) ]; \
-        then \
-          if [ -f "$(GIT)" ]; \
-          then \
-             if [ -n "$(EPPIC_GIT_URL)" ]; then \
-               git clone "$(EPPIC_GIT_URL)" eppic; \
-             else \
-	          if [ -n "$(GOOGLE)" ] ; then \
-	            git clone https://code.google.com/p/eppic eppic; \
-	          fi; \
-             fi; \
-          else \
-	     if [ ! -f "$(GIT)" ]; then \
-	         echo "eppic.so: git command is needed for pulling eppic extension code"; \
-	     fi; \
-          fi; \
-        fi; \
-        if  [ -f $(APPFILE) ]; \
-        then \
 	        make -f eppic.mk eppic.so; \
-        else \
-            echo "eppic.so: failed to pull eppic code from git repo"; \
-        fi; \
       else \
 	    echo "eppic.so: build failed: requires the crash $(GDB) module"; \
       fi ;\
@@ -61,8 +39,8 @@ all:
 lib-eppic:
 	cd eppic/libeppic && make

-eppic.so: ../defs.h $(APPFILE) lib-eppic
-	gcc -g -Ieppic/libeppic -I../$(GDB)/gdb -I../$(GDB)/bfd -I../$(GDB)/include -I../$(GDB)/gdb/config -I../$(GDB)/gdb/common -I../$(GDB) -nostartfiles -shared -rdynamic -o eppic.so $(APPFILE) -fPIC $(TARGET_FLAGS) $(GDB_FLAGS) -Leppic/libeppic -leppic
+eppic.so: ../defs.h $(APPFILE)
+	gcc -g -I../$(GDB)/gdb -I../$(GDB)/bfd -I../$(GDB)/include -I../$(GDB)/gdb/config -I../$(GDB)/gdb/common -I../$(GDB) -nostartfiles -shared -rdynamic -o eppic.so $(APPFILE) -fPIC $(TARGET_FLAGS) $(GDB_FLAGS) -leppic

 clean:
 	if  [ -d eppic/libeppic ]; \
Index: b/extensions/eppic/applications/crash/eppic.c
===================================================================
--- /dev/null
+++ b/extensions/eppic/applications/crash/eppic.c
@@ -0,0 +1,1110 @@
+/*
+ * $Id: eppic.c,v 1.15 2012/01/04 14:46:57 anderson Exp $
+ *
+ * This file is part of lcrash, an analysis tool for Linux memory dumps.
+ *
+ * Created by Silicon Graphics, Inc.
+ * Contributions by IBM, and others
+ *
+ * Copyright (C) 1999 - 2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001, 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version. See the file COPYING for more
+ * information.
+ */
+
+#include "gdb/defs.h"
+#include "target.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "frame.h"
+#include "value.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcmd.h"
+/*#include "call-cmds.h"*/
+#include "gdb_regex.h"
+#include "expression.h"
+#include "language.h"
+#include "demangle.h"
+#include "inferior.h"
+#include "linespec.h"
+#include "source.h"
+#include "filenames.h"		/* for FILENAME_CMP */
+#include "objc-lang.h"
+
+#include "hashtab.h"
+
+#include "gdb_obstack.h"
+#include "block.h"
+#include "dictionary.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
+#include <ctype.h>
+#include "cp-abi.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <eppic_api.h>
+
+/////////////////////////////////////////////////////////////////////////
+// some stuff from crash's defs.h, file which cannot be included here.
+// Hate to do this but this is a quick port.
+// If anyone cares to work on the include and defs structure to make
+// this work cleanly...
+//
+/*
+ *  Global data (global_data.c)
+ */
+extern char *args[];
+extern int argcnt;
+extern int argerrs;
+#define SYNOPSIS      (0x1)
+#define COMPLETE_HELP (0x2)
+#define PIPE_TO_LESS  (0x4)
+#define KVADDR (0x1)
+#define QUIET (0x4)
+
+typedef void (*cmd_func_t)(void);
+
+struct command_table_entry {               /* one for each command in menu */
+	char *name;
+	cmd_func_t func;
+	char **help_data;
+	ulong flags;
+};
+extern FILE *fp;
+extern char *crash_global_cmd();
+
+typedef unsigned long long int ulonglong;
+extern int readmem(ulonglong, int, void *, long, char *, ulong);
+extern int symbol_exists(char *);
+extern ulong symbol_value(char *);
+extern void cmd_usage(char *, int);
+extern void register_extension(struct command_table_entry *);
+
+
+//
+/////////////////////////////////////////////////////////////////////////
+/*
+	This is the glue between the eppic interpreter and crash.
+*/
+
+static int
+apigetmem(ull iaddr, void *p, int nbytes)
+{
+	return readmem(iaddr, KVADDR, p, nbytes, NULL, QUIET);
+}
+
+// Since crash is target dependant (build for the
+static uint8_t apigetuint8(void* ptr)
+{
+uint8_t val;
+    if(!readmem((unsigned long)ptr, KVADDR, (char*)&val, sizeof val, NULL, QUIET)) return (uint8_t)-1;
+    return val;
+}
+
+static uint16_t apigetuint16(void* ptr)
+{
+uint16_t val;
+    if(!readmem((unsigned long)ptr, KVADDR, (char*)&val, sizeof val, NULL, QUIET)) return (uint16_t)-1;
+    return val;
+}
+
+static uint32_t apigetuint32(void* ptr)
+{
+uint32_t val;
+    if(!readmem((unsigned long)ptr, KVADDR, (char*)&val, sizeof val, NULL, QUIET)) return (uint32_t)-1;
+    return val;
+}
+
+static uint64_t apigetuint64(void* ptr)
+{
+uint64_t val;
+    if(!readmem((unsigned long)ptr, KVADDR, (char*)&val, sizeof val, NULL, QUIET)) return (uint64_t)-1;
+    return val;
+}
+
+static int
+apiputmem(ull iaddr, void *p, int nbytes)
+{
+	return 1;
+}
+
+/* extract a complex type (struct, union and enum) */
+static int
+apigetctype(int ctype, char *name, TYPE_S *tout)
+{
+    struct symbol *sym;
+    struct type *type;
+    int v=0;
+
+    eppic_dbg_named(DBG_TYPE, name, 2, "Looking for type %d name [%s] in struct domain...", ctype, name);
+#ifdef GDB_6_1
+    sym = lookup_symbol(name, 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL);
+#else
+    sym = lookup_symbol(name, 0, STRUCT_DOMAIN, 0);
+#endif
+    if(!sym) {
+            eppic_dbg_named(DBG_TYPE, name, 2, "Not found.\nLooking for type %d name [%s] in var domain...", ctype, name);
+#ifdef GDB_6_1
+            sym = lookup_symbol(name, 0, VAR_DOMAIN, 0, (struct symtab **) NULL);
+#else
+            sym = lookup_symbol(name, 0, VAR_DOMAIN, 0);
+#endif
+            if(sym) {
+                eppic_dbg_named(DBG_TYPE, name, 2, "found class=%d\n", sym->aclass);
+                if(sym->aclass == LOC_TYPEDEF) v=1;
+            }
+    }
+
+    if (sym) {
+        type=sym->type;
+        if(eppic_is_typedef(ctype) && v) goto match;
+        eppic_dbg_named(DBG_TYPE, name, 2, "TYPE_CODE is %d ctype %d\n", TYPE_CODE(type), ctype);
+        switch(TYPE_CODE(type)) {
+	    case TYPE_CODE_INT:
+                eppic_dbg_named(DBG_TYPE, name, 2, "Variable is integer\n");
+		if (eppic_is_typedef(ctype)) {
+		    eppic_dbg_named(DBG_TYPE, name, 2,
+				    "integer is not a typedef\n");
+		    break;
+
+		}
+
+            case TYPE_CODE_TYPEDEF:
+                                    if(eppic_is_typedef(ctype))  goto match; break;
+            case TYPE_CODE_ENUM:    if(eppic_is_enum(ctype))     goto match; break;
+            case TYPE_CODE_STRUCT:  if(eppic_is_struct(ctype))   goto match; break;
+            case TYPE_CODE_UNION:   if(eppic_is_union(ctype))    goto match; break;
+        }
+        eppic_dbg_named(DBG_TYPE, name, 2, "Found but no match.\n");
+    }
+    else eppic_dbg_named(DBG_TYPE, name, 2, "Not Found.\n");
+
+    return 0;
+
+match:
+    eppic_dbg_named(DBG_TYPE, name, 2, "Found.\n");
+    /* populate */
+    eppic_type_settype(tout, ctype);
+    eppic_type_setsize(tout, TYPE_LENGTH(type));
+    eppic_type_setidx(tout, (ull)(unsigned long)type);
+    eppic_pushref(tout, 0);
+    return 1;
+}
+
+/* set idx value to actual array indexes from specified size */
+static void
+eppic_setupidx(TYPE_S*t, int ref, int nidx, int *idxlst)
+{
+        /* put the idxlst in index size format */
+        if(nidx) {
+
+                int i;
+
+                for(i=0;i<nidx-1;i++) {
+			/* kludge for array dimensions of [1] */
+			if (idxlst[i+1] == 0) {
+				idxlst[i+1] = 1;
+			}
+			idxlst[i]=idxlst[i]/idxlst[i+1];
+		}
+
+                /* divide by element size for last element bound */
+                if(ref) idxlst[i] /= eppic_defbsize();
+                else idxlst[i] /= eppic_type_getsize(t);
+                eppic_type_setidxlst(t, idxlst);
+        }
+}
+/*
+	This function needs to drill down a typedef and
+	return the corresponding type.
+	If the typedef is from a basetype eppic_parsetype() will be
+	called back to build the type
+*/
+static char *
+drilldowntype(struct type *type, TYPE_S *t)
+{
+char *tstr=0;
+int fctflg=0, ref=0;
+int *idxlst=0;
+int nidx=0;
+
+	while(type)
+	{
+            check_typedef(type);
+
+            // check out for stub types and pull in the definition instead
+            if(TYPE_STUB(type) && TYPE_TAG_NAME(type)) {
+#ifdef GDB_6_1
+                struct symbol *sym=lookup_symbol(TYPE_TAG_NAME(type), 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL);
+#else
+                struct symbol *sym=lookup_symbol(TYPE_TAG_NAME(type), 0, STRUCT_DOMAIN, 0);
+#endif
+                if(sym) {
+                    type=sym->type;
+                }
+            }
+            switch(TYPE_CODE(type)) {
+
+		/* typedef inserts a level of reference to the 1'dactual type */
+		case TYPE_CODE_PTR:
+
+			ref++;
+                        type=TYPE_TARGET_TYPE(type);
+       			/* this could be a void*, in which case the drill down stops here */
+			if(!type) {
+
+				/* make it a char* */
+				eppic_parsetype("char", t, ref);
+				return 0;
+
+			}
+		break;
+
+		/* handle pointer to functions */
+		case TYPE_CODE_FUNC:
+
+			fctflg=1;
+                        type=TYPE_TARGET_TYPE(type);
+		break;
+
+		/* Is this an array ? if so then just skip this type info and
+		   we only need information on the elements themselves */
+		case TYPE_CODE_ARRAY:
+                        if(!idxlst) idxlst=eppic_calloc(sizeof(int)*(MAXIDX+1));
+                        if(nidx >= MAXIDX) eppic_error("Too many indexes! max=%d\n", MAXIDX);
+                        if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+	                {
+                            idxlst[nidx++]=TYPE_LENGTH (type) / TYPE_LENGTH (check_typedef(TYPE_TARGET_TYPE (type)));
+                        }
+                        type=TYPE_TARGET_TYPE(type);
+		break;
+
+		/* typedef points to a typedef itself */
+		case TYPE_CODE_TYPEDEF:
+                        type=TYPE_TARGET_TYPE(type);
+		break;
+
+		case TYPE_CODE_INT:
+
+			eppic_parsetype(tstr=TYPE_NAME(type), t, 0);
+			type=0;
+		break;
+
+		case TYPE_CODE_BOOL:
+			eppic_parsetype("char", t, ref);
+			type=0;
+			break;
+
+		case TYPE_CODE_UNION:
+			eppic_type_mkunion(t);
+			goto label;
+
+		case TYPE_CODE_ENUM:
+			eppic_type_mkenum(t);
+			goto label;
+
+		case TYPE_CODE_STRUCT:
+		{
+			eppic_type_mkstruct(t);
+
+label:
+			eppic_type_setsize(t, TYPE_LENGTH(type));
+			eppic_type_setidx(t, (ull)(unsigned long)type);
+			tstr=TYPE_TAG_NAME(type);
+                        if(tstr) apigetctype(V_STRUCT, tstr, t);
+                        type=0;
+		}
+		break;
+
+		/* we don;t have all the info about it */
+		case TYPE_CODE_VOID:
+			eppic_parsetype("int", t, 0);
+                        type=0;
+		break;
+
+
+		default:
+			eppic_error("Oops drilldowntype");
+		break;
+		}
+
+
+	}
+	eppic_setupidx(t, ref, nidx, idxlst);
+	if(fctflg) eppic_type_setfct(t, 1);
+	eppic_pushref(t, ref+(nidx?1:0));
+	if(tstr) return eppic_strdup(tstr);
+	return eppic_strdup("");
+}
+
+static char *
+apigetrtype(ull idx, TYPE_S *t)
+{
+	return drilldowntype((struct type*)(unsigned long)(idx), t);
+}
+
+/*
+   	Return the name of a symbol at an address (if any)
+*/
+static char*
+apifindsym(char *p)
+{
+    return NULL;
+}
+
+
+/*
+	Get the type, size and position information for a member of a structure.
+*/
+static char*
+apimember(char *mname,  ull tnum, TYPE_S *tm, MEMBER_S *m, ull *lnum)
+{
+struct type *type=(struct type*)(unsigned long)tnum;
+int midx;
+#define LASTNUM (*lnum)
+
+	/* if we're being asked the next member in a getfirst/getnext sequence */
+	if(mname && !mname[0] && LASTNUM) {
+
+		midx = LASTNUM;
+
+	} else {
+
+		if (TYPE_CODE(type) == TYPE_CODE_TYPEDEF) {
+			return 0;
+		}
+		if ((TYPE_CODE(type) != TYPE_CODE_STRUCT) && (TYPE_CODE(type) != TYPE_CODE_UNION)) {
+			return 0;
+		}
+                midx=0;
+	}
+	while(midx < TYPE_NFIELDS(type)) {
+
+		if (!mname || !mname[0] || !strcmp(mname, TYPE_FIELD_NAME(type, midx))) {
+
+                        check_typedef(TYPE_FIELD_TYPE(type, midx));
+			eppic_member_soffset(m, TYPE_FIELD_BITPOS(type, midx)/8);
+			eppic_member_ssize(m, TYPE_FIELD_TYPE(type, midx)->length);
+			eppic_member_snbits(m, TYPE_FIELD_BITSIZE(type, midx));
+			eppic_member_sfbit(m, TYPE_FIELD_BITPOS(type, midx)%8);
+			eppic_member_sname(m, TYPE_FIELD_NAME(type, midx));
+			LASTNUM=midx+1;
+			return drilldowntype(TYPE_FIELD_TYPE(type, midx), tm);
+		}
+		midx++;
+	}
+	return 0;
+}
+
+/*
+	This function gets the proper allignment value for a type.
+*/
+static int
+apialignment(ull idx)
+{
+struct type *type=(struct type *)(unsigned long)idx;
+
+    while(1)
+    {
+	switch(TYPE_CODE(type)) {
+
+	    case TYPE_CODE_ARRAY: case TYPE_CODE_TYPEDEF:
+		    type=TYPE_TARGET_TYPE(type);
+	    break;
+
+	    case TYPE_CODE_STRUCT:
+	    case TYPE_CODE_UNION:
+	    {
+		int max=0, cur;
+		int midx=0;
+
+		while(midx < TYPE_NFIELDS(type)) {
+                    cur=apialignment((ull)(unsigned long)TYPE_FIELD_TYPE(type, midx));
+	            if(cur > max) max=cur;
+	            midx++;
+		}
+		return max;
+            }
+
+
+	    case TYPE_CODE_PTR:
+	    case TYPE_CODE_ENUM:
+	    case TYPE_CODE_INT:
+
+		    return TYPE_LENGTH (type);
+
+	    default:
+
+		    eppic_error("Oops apialignment");
+	}
+    }
+}
+
+/* get the value of a symbol */
+static int
+apigetval(char *name, ull *val,  VALUE_S *value)
+{
+    if (symbol_exists(name)) {
+
+        *val=symbol_value(name);
+
+        if(value) {
+            struct expression *expr;
+            struct value *sval;
+            struct cleanup *old_chain = NULL;
+            struct type *type;
+            VALUE_S *vref;
+            TYPE_S *stype;
+            expr = parse_expression (name);
+            old_chain = make_cleanup (free_current_contents, &expr);
+            sval = evaluate_type (expr);
+            type = value_type(sval);
+            stype=eppic_gettype(value);
+            apigetrtype((ull)type, stype);
+            eppic_pushref(stype, 1);
+            eppic_setmemaddr(value, *val);
+            eppic_do_deref(1, value, value);
+            *val=eppic_getval(value);
+            if(!eppic_typeislocal(stype) && eppic_type_getidx(stype) > 100) {
+                char *tname;
+                type=(struct type*)((long)eppic_type_getidx(stype));
+                if(type->main_type) tname=type->main_type->tag_name;
+                if(tname) eppic_chktype(stype, tname);
+            }
+            do_cleanups (old_chain);
+        }
+        return 1;
+    }
+    return 0;
+}
+
+/*
+	Get the list of enum symbols.
+*/
+ENUM_S*
+apigetenum(char *name)
+{
+    struct symbol *sym;
+
+#ifdef GDB_6_1
+    sym = lookup_symbol(name, 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL);
+#else
+    sym = lookup_symbol(name, 0, STRUCT_DOMAIN, 0);
+#endif
+    if (sym && TYPE_CODE(sym->type)==TYPE_CODE_ENUM) {
+	ENUM_S *et=0;
+        struct type *type=sym->type;
+        int n=0;
+	while(n < TYPE_NFIELDS (type)) {
+      	    et=eppic_add_enum(et, eppic_strdup(TYPE_FIELD_NAME(type, n)), TYPE_FIELD_BITPOS(type, n));
+            n++;
+	}
+        return et;
+    }
+    return 0;
+}
+
+/*
+	Return the list of preprocessor defines.
+	For Irix we have to get the die for a startup.c file.
+	Of dwarf type DW_TAG_compile_unit.
+	the DW_AT_producer will contain the compile line.
+
+	We then need to parse that line to get all the -Dname[=value]
+*/
+DEF_S *
+apigetdefs(void)
+{
+DEF_S *dt=0;
+int i;
+static struct linuxdefs_s {
+
+	char *name;
+	char *value;
+
+} linuxdefs[] = {
+
+	{"crash",		"1"},
+	{"linux",		"1"},
+	{"__linux",		"1"},
+	{"__linux__",		"1"},
+	{"unix",		"1"},
+	{"__unix",		"1"},
+	{"__unix__",		"1"},
+	// helper macros
+	{"LINUX_2_2_16",	"(LINUX_RELEASE==0x020210)"},
+	{"LINUX_2_2_17",	"(LINUX_RELEASE==0x020211)"},
+	{"LINUX_2_4_0",		"(LINUX_RELEASE==0x020400)"},
+	{"LINUX_2_2_X",		"(((LINUX_RELEASE) & 0xffff00) == 0x020200)"},
+	{"LINUX_2_4_X",		"(((LINUX_RELEASE) & 0xffff00) == 0x020400)"},
+	{"LINUX_2_6_X",		"(((LINUX_RELEASE) & 0xffff00) == 0x020600)"},
+	{"LINUX_3_X_X",         "(((LINUX_RELEASE) & 0xff0000) == 0x030000)"},
+	{"NULL",         "0"},
+#ifdef i386
+	{"i386",         "1"},
+	{"__i386",       "1"},
+	{"__i386__",     "1"},
+	{"BITS_PER_LONG","32"},
+#endif
+#ifdef s390
+	{"s390",         "1"},
+	{"__s390",       "1"},
+	{"__s390__",     "1"},
+	{"BITS_PER_LONG","32"},
+#endif
+#ifdef s390x
+	 {"s390x",       "1"},
+	 {"__s390x",     "1"},
+	 {"__s390x__",   "1"},
+	{"BITS_PER_LONG","32"},
+#endif
+#ifdef __ia64__
+	{"ia64",         "1"},
+	{"__ia64",       "1"},
+	{"__ia64__",     "1"},
+	{"__LP64__",     "1"},
+	{"_LONGLONG",    "1"},
+	{"__LONG_MAX__", "9223372036854775807L"},
+	{"BITS_PER_LONG","64"},
+#endif
+#ifdef __x86_64__
+	{"x86_64",         "1"},
+	{"_x86_64_",       "1"},
+	{"__x86_64__",     "1"},
+	{"__LP64__",     "1"},
+	{"_LONGLONG",    "1"},
+	{"__LONG_MAX__", "9223372036854775807L"},
+	{"BITS_PER_LONG","64"},
+#endif
+#ifdef ppc64
+	{"ppc64",       "1"},
+	{"__ppc64",     "1"},
+	{"__ppc64__",   "1"},
+	{"BITS_PER_LONG","64"},
+#endif
+	};
+
+static char *untdef[] = {
+    "clock",
+    "mode",
+    "pid",
+    "uid",
+    "xtime",
+    "init_task",
+    "size",
+    "type",
+    "level",
+    0
+};
+
+#if 0
+How to extract basic set of -D flags from the kernel image
+
+	prod=eppic_strdup(kl_getproducer());
+	for(p=prod; *p; p++) {
+
+		if(*p=='-' && *(p+1)=='D') {
+
+			char *def=p+2;
+
+			while(*p && *p != '=' && *p != ' ') p++;
+
+			if(!*p || *p == ' ') {
+
+				*p='\0';
+				dt=eppic_add_def(dt, eppic_strdup(def), eppic_strdup("1"));
+
+			} else {
+
+				char *val=p+1;
+
+				*p++='\0';
+				while(*p && *p != ' ') p++;
+				*p='\0';
+
+				dt=eppic_add_def(dt, eppic_strdup(def), eppic_strdup(val));
+			}
+		}
+	}
+#endif
+
+        /* remove some tdef with very usual identifier.
+           could also be cases where the kernel defined a type and variable with same name e.g. xtime.
+           the same can be accomplished in source using #undef <tdefname> or forcing the evaluation of
+           a indentifier as a variable name ex: __var(xtime).
+
+           I tried to make the grammar as unambiqguous as I could.
+
+           If this becomes to much of a problem I might diable usage of all image typedefs usage in eppic!
+        */
+        {
+            char **tdefname=untdef;
+            while(*tdefname) eppic_addneg(*tdefname++);;
+
+        }
+
+	/* insert constant defines from list above */
+	for(i=0;i<sizeof(linuxdefs)/sizeof(linuxdefs[0]);i++) {
+
+		dt=eppic_add_def(dt, eppic_strdup(linuxdefs[i].name),
+			eppic_strdup(linuxdefs[i].value));
+	}
+
+#if 1
+        {
+            ull addr;
+            char banner[200];
+            if(apigetval("linux_banner", &addr, NULL)) {
+                if(apigetmem(addr, banner, sizeof banner-1)) {
+
+                    // parse the banner string and set up release macros
+                    banner[sizeof banner -1]='\0';
+                    char *tok=strtok(banner, " \t");
+                    if(tok) tok=strtok(NULL, " \t");
+                    if(tok) tok=strtok(NULL, " \t");
+                    if(tok) {
+                        int version, patchlevel, sublevel, ret;
+                        ret = sscanf(tok, "%d.%d.%d-", &version, &patchlevel, &sublevel);
+			switch (ret) {
+			case 2:
+			    sublevel = 0;
+			case 3:
+			    sprintf(banner, "0x%02x%02x%02x", version, patchlevel, sublevel);
+		            dt=eppic_add_def(dt, eppic_strdup("LINUX_RELEASE"), eppic_strdup(banner));
+                            eppic_msg("Core LINUX_RELEASE == '%s'\n", tok);
+			default:
+			    break;
+                        }
+                    }
+                }
+                else eppic_msg("Eppic init: could not read symbol 'linux_banner' from corefile.\n");
+            }
+            else eppic_msg("Eppic init: could not find symbol 'linux_banner' in corefile.\n");
+        }
+#endif
+	return dt;
+}
+
+apiops icops= {
+	apigetmem,
+	apiputmem,
+	apimember,
+	apigetctype,
+	apigetrtype,
+	apialignment,
+	apigetval,
+	apigetenum,
+	apigetdefs,
+	apigetuint8,
+	apigetuint16,
+	apigetuint32,
+	apigetuint64,
+	apifindsym
+};
+
+void
+eppic_version(void)
+{
+	eppic_msg("< Eppic interpreter version %d.%d >\n"
+		, S_MAJOR, S_MINOR);
+}
+
+static void
+run_callback(void)
+{
+extern char *crash_global_cmd();
+FILE *ofp = NULL;
+
+	if (fp) {
+		ofp = eppic_getofile();
+		eppic_setofile(fp);
+	}
+
+	eppic_cmd(crash_global_cmd(), args, argcnt);
+
+	if (ofp)
+		eppic_setofile(ofp);
+}
+
+
+void
+edit_cmd(void)
+{
+int c, file=0;
+        while ((c = getopt(argcnt, args, "lf")) != EOF) {
+                switch(c)
+                {
+                case 'l':
+                    eppic_vilast();
+                    return;
+                break;
+                case 'f':
+                    file++;
+                break;
+                default:
+                        argerrs++;
+                        break;
+                }
+        }
+
+        if (argerrs)
+                cmd_usage(crash_global_cmd(), SYNOPSIS);
+
+        else if(args[optind]) {
+            while(args[optind]) {
+	        eppic_vi(args[optind++], file);
+            }
+	}
+        else cmd_usage(crash_global_cmd(), SYNOPSIS);
+}
+
+char *edit_help[]={
+		"edit",
+                "Start a $EDITOR session of a eppic function or file",
+                "<-f fileName>|<function name>",
+                "This command can be use during a tight development cycle",
+                "where frequent editing->run->editing sequences are executed.",
+                "To edit a known eppic macro file use the -f option. To edit the file",
+                "at the location of a known function's declaration omit the -f option.",
+                "Use a single -l option to be brought to the last compile error location.",
+                "",
+                "EXAMPLES:",
+                "  %s> edit -f ps",
+                "  %s> edit ps",
+                "  %s> edit ps_opt",
+                "  %s> edit -l",
+                NULL
+};
+
+
+// these control debug mode when parsing (pre-processor and compile)
+int eppicdebug, eppicppdebug;
+
+void
+load_cmd(void)
+{
+	if(argcnt< 2) cmd_usage(crash_global_cmd(), SYNOPSIS);
+	else {
+            eppic_setofile(fp);
+            eppic_loadunload(1, args[1], 0);
+        }
+}
+
+char *load_help[]={
+		"load",
+                "Load a eppic file",
+                "<fileName>|<Directory>",
+                "  Load a file or a directory. In the case of a directory",
+		"  all files in that directory will be loaded.",
+                NULL
+
+};
+
+void
+unload_cmd(void)
+{
+	if(argcnt < 2) cmd_usage(crash_global_cmd(), SYNOPSIS);
+	else eppic_loadunload(0, args[1], 0);
+}
+
+char *unload_help[]={
+		"unload",
+                "Unload a eppic file",
+                "<fileName>|<Directory>",
+                "  Unload a file or a directory. In the case of a directory",
+		"  all files in that directory will be unloaded.",
+                NULL
+};
+
+void
+sdebug_cmd(void)
+{
+	if(argcnt < 2) eppic_msg("Current eppic debug level is %d\n", eppic_getdbg());
+	else eppic_setdbg(atoi(args[1]));
+}
+
+char *sdebug_help[]={
+		"sdebug",
+                "Print or set eppic debug level",
+                "<Debug level 0..9>",
+                "  Set the debug of eppic. Without any parameter, shows the current debug level.",
+                NULL
+};
+
+void
+sname_cmd(void)
+{
+	if(argcnt < 2) {
+            if(eppic_getname()) eppic_msg("Current eppic name match is '%s'\n", eppic_getname());
+            else eppic_msg("No name match specified yet.\n");
+	} else eppic_setname(args[1]);
+}
+
+char *sname_help[]={
+		"sname",
+                "Print or set eppic name match.",
+                "<name>",
+                "  Set eppic name string for matches. Debug messages that are object oriented",
+                "  will only be displayed if the object name (struct, type, ...) matches this",
+		"  value.",
+                NULL
+};
+
+void
+sclass_cmd(void)
+{
+	if(argcnt < 2) {
+            char **classes=eppic_getclass();
+            eppic_msg("Current eppic classes are :");
+            while(*classes) eppic_msg("'%s' ", *classes++);
+            eppic_msg("\n");
+
+        }
+        else {
+            int i;
+            for(i=1; i<argcnt; i++) eppic_setclass(args[i]);
+        }
+}
+
+char *sclass_help[]={
+		"sclass",
+                "Print or set eppic debug message class(es).",
+                "<className>[, <className>]",
+                "  Set eppic debug classes. Only debug messages that are in the specified classes",
+                "  will be displayed.",
+                NULL
+};
+
+#define NCMDS 200
+static struct command_table_entry command_table[NCMDS] =  {
+
+	{"edit", edit_cmd, edit_help},
+	{"load", load_cmd, load_help},
+	{"unload", unload_cmd, unload_help},
+	{"sdebug", sdebug_cmd, sdebug_help},
+	{"sname", sname_cmd, sname_help},
+	{"sclass", sclass_cmd, sclass_help},
+	{(char *)0 }
+};
+
+static void
+add_eppic_cmd(char *name, void (*cmd)(void), char **help, int flags)
+{
+struct command_table_entry *cp;
+struct command_table_entry *crash_cmd_table();
+
+    // check for a clash with native commands
+    for (cp = crash_cmd_table(); cp->name; cp++) {
+        if (!strcmp(cp->name, name)) {
+            eppic_msg("Eppic command name '%s' conflicts with native crash command.\n", name);
+            return;
+        }
+    }
+
+    // make sure we have enough space for the new command
+    if(!command_table[NCMDS-2].name) {
+        for (cp = command_table; cp->name; cp++);
+        cp->name=eppic_strdup(name);
+        cp->func=cmd;
+        cp->help_data=help;
+        cp->flags=flags;
+    }
+}
+
+static void
+rm_eppic_cmd(char *name)
+{
+struct command_table_entry *cp, *end;
+
+    for (cp = command_table; cp->name; cp++) {
+        if (!strcmp(cp->name, name)) {
+            eppic_free(cp->name);
+            memmove(cp, cp+1, sizeof *cp *(NCMDS-(cp-command_table)-1));
+            break;
+        }
+    }
+}
+
+/*
+	This function is called for every new function
+	generated by a load command. This enables us to
+	register new commands.
+
+	We check here is the functions:
+
+	fname_help()
+	fname_opt()
+	and
+	fname_usage()
+
+	exist, and if so then we have a new command.
+	Then we associated (register) a function with
+	the standard eppic callbacks.
+*/
+void
+reg_callback(char *name, int load)
+{
+char fname[MAX_SYMNAMELEN+sizeof("_usage")+1];
+char *help_str, *opt_str;
+char **help=malloc(sizeof *help * 5);
+
+    if(!help) return;
+    snprintf(fname, sizeof(fname), "%s_help", name);
+    if(eppic_chkfname(fname, 0)) {
+        snprintf(fname, sizeof(fname), "%s_usage", name);
+        if(eppic_chkfname(fname, 0)) {
+            if(load) {
+                opt_str=eppic_strdup((char*)(unsigned long)eppic_exefunc(fname, 0));
+                snprintf(fname, sizeof(fname), "%s_help", name);
+                help_str=eppic_strdup((char*)(unsigned long)eppic_exefunc(fname, 0));
+                help[0]=eppic_strdup(name);
+                help[1]="";
+                help[2]=eppic_strdup(opt_str);
+                help[3]=eppic_strdup(help_str);
+                help[4]=0;
+                add_eppic_cmd(name, run_callback, help, 0);
+                eppic_free(help_str);
+                eppic_free(opt_str);
+                return;
+            }
+            else rm_eppic_cmd(name);
+        }
+    }
+    free(help);
+    return;
+}
+
+/*
+ *  The _fini() function is called if the shared object is unloaded.
+ *  If desired, perform any cleanups here.
+ */
+void _fini()
+{
+    // need to unload any files we have loaded
+
+}
+
+VALUE_S *curtask(VALUE_S *v, ...)
+{
+unsigned long get_curtask();
+    return eppic_makebtype((ull)get_curtask());
+}
+
+_init() /* Register the command set. */
+{
+#define LCDIR "/usr/share/eppic/crash"
+#define LCIDIR "include"
+#define LCUDIR ".eppic"
+
+
+	if(eppic_open() >= 0) {
+
+		char *path, *ipath;
+		char *homepath=0;
+               	char *home=getenv("HOME");
+
+		/* set api, default size, and default sign for types */
+#ifdef i386
+#define EPPIC_ABI  ABI_INTEL_X86
+#else
+#ifdef __ia64__
+#define EPPIC_ABI  ABI_INTEL_IA
+#else
+#ifdef __x86_64__
+#define EPPIC_ABI  ABI_INTEL_IA
+#else
+#ifdef __s390__
+#define EPPIC_ABI  ABI_S390
+#else
+#ifdef __s390x__
+#define EPPIC_ABI  ABI_S390X
+#else
+#ifdef PPC64
+#define EPPIC_ABI  ABI_PPC64
+#else
+#error eppic: Unkown ABI
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+		eppic_apiset(&icops, EPPIC_ABI, sizeof(long), 0);
+
+		eppic_version();
+
+        	/* set the macro search path */
+        	if(!(path=getenv("EPPIC_MPATH"))) {
+
+                	if(home) {
+
+                        	path=eppic_alloc(strlen(home)+sizeof(LCUDIR)+sizeof(LCDIR)+4);
+				homepath=eppic_alloc(strlen(home)+sizeof(LCUDIR)+2);
+
+				/* build a path for call to eppic_load() */
+				strcpy(homepath, home);
+				strcat(homepath, "/");
+				strcat(homepath, LCUDIR);
+
+				/* built the official path */
+                        	strcpy(path, LCDIR);
+                        	strcat(path, ":");
+                        	strcat(path, home);
+                        	strcat(path, "/");
+				strcat(path, LCUDIR);
+                	}
+                	else path=LCDIR;
+		}
+		eppic_setmpath(path);
+
+		fprintf(fp, "\tLoading eppic commands from %s .... ",
+                                         path);
+
+		/* include path */
+		if(!(ipath=getenv("EPPIC_IPATH"))) {
+
+                	if(home) {
+
+                        	ipath=eppic_alloc(strlen(home)+sizeof(LCDIR)+sizeof(LCUDIR)+(sizeof(LCIDIR)*2)+(sizeof("/usr/include")+2)+6);
+
+				/* built the official path */
+                        	strcpy(ipath, LCDIR);
+                        	strcat(ipath, "/"LCIDIR":");
+                        	strcat(ipath, home);
+                        	strcat(ipath, "/");
+				strcat(ipath, LCUDIR);
+				strcat(ipath, "/"LCIDIR);
+				strcat(ipath, ":/usr/include");
+                	}
+                	else ipath=LCDIR"/"LCIDIR;
+		}
+		eppic_setipath(ipath);
+
+		/* set the new function callback */
+		eppic_setcallback(reg_callback);
+
+		/* load the default macros */
+		eppic_loadall();
+
+		/* load some eppic specific commands */
+                register_extension(command_table);
+
+                /* some builtins */
+        	eppic_builtin("int curtask()", curtask);
+
+                fprintf(fp, "Done.\n");
+	}
+        return 1;
+}
+

```

Generate a backported patch for the SUSE target version.

[Assistant]
---
 eppic/applications/crash/eppic.c | 1110 +++++++++++++++++++++++++++++++++++++++
 extensions/eppic.mk              |   26
 2 files changed, 1112 insertions(+), 24 deletions(-)

Index: b/extensions/eppic.mk
===================================================================
--- a/extensions/eppic.mk
+++ b/extensions/eppic.mk
@@ -28,29 +28,7 @@ all:
 	@if [ -f /usr/bin/flex ] && [ -f /usr/bin/bison ]; then \
 	  if [ -f ../$(GDB)/crash.target ]; \
         then \
-        if  [ ! -f $(APPFILE) ]; \
-        then \
-          if [ -f "$(GIT)" ]; \
-          then \
-             if [ -n "$(EPPIC_GIT_URL)" ]; then \
-               git clone "$(EPPIC_GIT_URL)" eppic; \
-             else \
-	          if [ -n "$(GOOGLE)" ] ; then \
-	            git clone https://code.google.com/p/eppic eppic; \
-	          fi; \
-             fi; \
-          else \
-	     if [ ! -f "$(GIT)" ]; then \
-	         echo "eppic.so: git command is needed for pulling eppic extension code"; \
-	     fi; \
-          fi; \
-        fi; \
-        if  [ -f $(APPFILE) ]; \
-        then \
 	        make -f eppic.mk eppic.so; \
-        else \
-            echo "eppic.so: failed to pull eppic code from git repo"; \
-        fi; \
       else \
 	    echo "eppic.so: build failed: requires the crash $(GDB) module"; \
       fi ;\
@@ -61,8 +39,8 @@ all:
 lib-eppic:
 	cd eppic/libeppic && make

-eppic.so: ../defs.h $(APPFILE) lib-eppic
-	gcc -g -Ieppic/libeppic -I../$(GDB)/gdb -I../$(GDB)/bfd -I../$(GDB)/include -I../$(GDB)/gdb/config -I../$(GDB)/gdb/common -I../$(GDB) -nostartfiles -shared -rdynamic -o eppic.so $(APPFILE) -fPIC $(TARGET_FLAGS) $(GDB_FLAGS) -Leppic/libeppic -leppic
+eppic.so: ../defs.h $(APPFILE)
+	gcc -g -I../$(GDB)/gdb -I../$(GDB)/bfd -I../$(GDB)/include -I../$(GDB)/gdb/config -I../$(GDB)/gdb/common -I../$(GDB) -nostartfiles -shared -rdynamic -o eppic.so $(APPFILE) -fPIC $(TARGET_FLAGS) $(GDB_FLAGS) -leppic

 clean:
 	if  [ -d eppic/libeppic ]; \
Index: b/extensions/eppic/applications/crash/eppic.c
===================================================================
--- /dev/null
+++ b/extensions/eppic/applications/crash/eppic.c
@@ -0,0 +1,1110 @@
+/*
+ * $Id: eppic.c,v 1.15 2012/01/04 14:46:57 anderson Exp $
+ *
+ * This file is part of lcrash, an analysis tool for Linux memory dumps.
+ *
+ * Created by Silicon Graphics, Inc.
+ * Contributions by IBM, and others
+ *
+ * Copyright (C) 1999 - 2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001, 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version. See the file COPYING for more
+ * information.
+ */
+
+#include "gdb/defs.h"
+#include "target.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "frame.h"
+#include "value.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcmd.h"
+/*#include "call-cmds.h"*/
+#include "gdb_regex.h"
+#include "expression.h"
+#include "language.h"
+#include "demangle.h"
+#include "inferior.h"
+#include "linespec.h"
+#include "source.h"
+#include "filenames.h"		/* for FILENAME_CMP */
+#include "objc-lang.h"
+
+#include "hashtab.h"
+
+#include "gdb_obstack.h"
+#include "block.h"
+#include "dictionary.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
+#include <ctype.h>
+#include "cp-abi.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <eppic_api.h>
+
+/////////////////////////////////////////////////////////////////////////
+// some stuff from crash's defs.h, file which cannot be included here.
+// Hate to do this but this is a quick port.
+// If anyone cares to work on the include and defs structure to make
+// this work cleanly...
+//
+/*
+ *  Global data (global_data.c)
+ */
+extern char *args[];
+extern int argcnt;
+extern int argerrs;
+#define SYNOPSIS      (0x1)
+#define COMPLETE_HELP (0x2)
+#define PIPE_TO_LESS  (0x4)
+#define KVADDR (0x1)
+#define QUIET (0x4)
+
+typedef void (*cmd_func_t)(void);
+
+struct command_table_entry {               /* one for each command in menu */
+	char *name;
+	cmd_func_t func;
+	char **help_data;
+	ulong flags;
+};
+extern FILE *fp;
+extern char *crash_global_cmd();
+
+typedef unsigned long long int ulonglong;
+extern int readmem(ulonglong, int, void *, long, char *, ulong);
+extern int symbol_exists(char *);
+extern ulong symbol_value(char *);
+extern void cmd_usage(char *, int);
+extern void register_extension(struct command_table_entry *);
+
+
+//
+/////////////////////////////////////////////////////////////////////////
+/*
+	This is the glue between the eppic interpreter and crash.
+*/
+
+static int
+apigetmem(ull iaddr, void *p, int nbytes)
+{
+	return readmem(iaddr, KVADDR, p, nbytes, NULL, QUIET);
+}
+
+// Since crash is target dependant (build for the
+static uint8_t apigetuint8(void* ptr)
+{
+uint8_t val;
+    if(!readmem((unsigned long)ptr, KVADDR, (char*)&val, sizeof val, NULL, QUIET)) return (uint8_t)-1;
+    return val;
+}
+
+static uint16_t apigetuint16(void* ptr)
+{
+uint16_t val;
+    if(!readmem((unsigned long)ptr, KVADDR, (char*)&val, sizeof val, NULL, QUIET)) return (uint16_t)-1;
+    return val;
+}
+
+static uint32_t apigetuint32(void* ptr)
+{
+uint32_t val;
+    if(!readmem((unsigned long)ptr, KVADDR, (char*)&val, sizeof val, NULL, QUIET)) return (uint32_t)-1;
+    return val;
+}
+
+static uint64_t apigetuint64(void* ptr)
+{
+uint64_t val;
+    if(!readmem((unsigned long)ptr, KVADDR, (char*)&val, sizeof val, NULL, QUIET)) return (uint64_t)-1;
+    return val;
+}
+
+static int
+apiputmem(ull iaddr, void *p, int nbytes)
+{
+	return 1;
+}
+
+/* extract a complex type (struct, union and enum) */
+static int
+apigetctype(int ctype, char *name, TYPE_S *tout)
+{
+    struct symbol *sym;
+    struct type *type;
+    int v=0;
+
+    eppic_dbg_named(DBG_TYPE, name, 2, "Looking for type %d name [%s] in struct domain...", ctype, name);
+#ifdef GDB_6_1
+    sym = lookup_symbol(name, 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL);
+#else
+    sym = lookup_symbol(name, 0, STRUCT_DOMAIN, 0);
+#endif
+    if(!sym) {
+            eppic_dbg_named(DBG_TYPE, name, 2, "Not found.\nLooking for type %d name [%s] in var domain...", ctype, name);
+#ifdef GDB_6_1
+            sym = lookup_symbol(name, 0, VAR_DOMAIN, 0, (struct symtab **) NULL);
+#else
+            sym = lookup_symbol(name, 0, VAR_DOMAIN, 0);
+#endif
+            if(sym) {
+                eppic_dbg_named(DBG_TYPE, name, 2, "found class=%d\n", sym->aclass);
+                if(sym->aclass == LOC_TYPEDEF) v=1;
+            }
+    }
+
+    if (sym) {
+        type=sym->type;
+        if(eppic_is_typedef(ctype) && v) goto match;
+        eppic_dbg_named(DBG_TYPE, name, 2, "TYPE_CODE is %d ctype %d\n", TYPE_CODE(type), ctype);
+        switch(TYPE_CODE(type)) {
+	    case TYPE_CODE_INT:
+                eppic_dbg_named(DBG_TYPE, name, 2, "Variable is integer\n");
+		if (eppic_is_typedef(ctype)) {
+		    eppic_dbg_named(DBG_TYPE, name, 2,
+				    "integer is not a typedef\n");
+		    break;
+
+		}
+
+            case TYPE_CODE_TYPEDEF:
+                                    if(eppic_is_typedef(ctype))  goto match; break;
+            case TYPE_CODE_ENUM:    if(eppic_is_enum(ctype))     goto match; break;
+            case TYPE_CODE_STRUCT:  if(eppic_is_struct(ctype))   goto match; break;
+            case TYPE_CODE_UNION:   if(eppic_is_union(ctype))    goto match; break;
+        }
+        eppic_dbg_named(DBG_TYPE, name, 2, "Found but no match.\n");
+    }
+    else eppic_dbg_named(DBG_TYPE, name, 2, "Not Found.\n");
+
+    return 0;
+
+match:
+    eppic_dbg_named(DBG_TYPE, name, 2, "Found.\n");
+    /* populate */
+    eppic_type_settype(tout, ctype);
+    eppic_type_setsize(tout, TYPE_LENGTH(type));
+    eppic_type_setidx(tout, (ull)(unsigned long)type);
+    eppic_pushref(tout, 0);
+    return 1;
+}
+
+/* set idx value to actual array indexes from specified size */
+static void
+eppic_setupidx(TYPE_S*t, int ref, int nidx, int *idxlst)
+{
+        /* put the idxlst in index size format */
+        if(nidx) {
+
+                int i;
+
+                for(i=0;i<nidx-1;i++) {
+			/* kludge for array dimensions of [1] */
+			if (idxlst[i+1] == 0) {
+				idxlst[i+1] = 1;
+			}
+			idxlst[i]=idxlst[i]/idxlst[i+1];
+		}
+
+                /* divide by element size for last element bound */
+                if(ref) idxlst[i] /= eppic_defbsize();
+                else idxlst[i] /= eppic_type_getsize(t);
+                eppic_type_setidxlst(t, idxlst);
+        }
+}
+/*
+	This function needs to drill down a typedef and
+	return the corresponding type.
+	If the typedef is from a basetype eppic_parsetype() will be
+	called back to build the type
+*/
+static char *
+drilldowntype(struct type *type, TYPE_S *t)
+{
+char *tstr=0;
+int fctflg=0, ref=0;
+int *idxlst=0;
+int nidx=0;
+
+	while(type)
+	{
+            check_typedef(type);
+
+            // check out for stub types and pull in the definition instead
+            if(TYPE_STUB(type) && TYPE_TAG_NAME(type)) {
+#ifdef GDB_6_1
+                struct symbol *sym=lookup_symbol(TYPE_TAG_NAME(type), 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL);
+#else
+                struct symbol *sym=lookup_symbol(TYPE_TAG_NAME(type), 0, STRUCT_DOMAIN, 0);
+#endif
+                if(sym) {
+                    type=sym->type;
+                }
+            }
+            switch(TYPE_CODE(type)) {
+
+		/* typedef inserts a level of reference to the 1'dactual type */
+		case TYPE_CODE_PTR:
+
+			ref++;
+                        type=TYPE_TARGET_TYPE(type);
+       			/* this could be a void*, in which case the drill down stops here */
+			if(!type) {
+
+				/* make it a char* */
+				eppic_parsetype("char", t, ref);
+				return 0;
+
+			}
+		break;
+
+		/* handle pointer to functions */
+		case TYPE_CODE_FUNC:
+
+			fctflg=1;
+                        type=TYPE_TARGET_TYPE(type);
+		break;
+
+		/* Is this an array ? if so then just skip this type info and
+		   we only need information on the elements themselves */
+		case TYPE_CODE_ARRAY:
+                        if(!idxlst) idxlst=eppic_calloc(sizeof(int)*(MAXIDX+1));
+                        if(nidx >= MAXIDX) eppic_error("Too many indexes! max=%d\n", MAXIDX);
+                        if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+	                {
+                            idxlst[nidx++]=TYPE_LENGTH (type) / TYPE_LENGTH (check_typedef(TYPE_TARGET_TYPE (type)));
+                        }
+                        type=TYPE_TARGET_TYPE(type);
+		break;
+
+		/* typedef points to a typedef itself */
+		case TYPE_CODE_TYPEDEF:
+                        type=TYPE_TARGET_TYPE(type);
+		break;
+
+		case TYPE_CODE_INT:
+
+			eppic_parsetype(tstr=TYPE_NAME(type), t, 0);
+			type=0;
+		break;
+
+		case TYPE_CODE_BOOL:
+			eppic_parsetype("char", t, ref);
+			type=0;
+			break;
+
+		case TYPE_CODE_UNION:
+			eppic_type_mkunion(t);
+			goto label;
+
+		case TYPE_CODE_ENUM:
+			eppic_type_mkenum(t);
+			goto label;
+
+		case TYPE_CODE_STRUCT:
+		{
+			eppic_type_mkstruct(t);
+
+label:
+			eppic_type_setsize(t, TYPE_LENGTH(type));
+			eppic_type_setidx(t, (ull)(unsigned long)type);
+			tstr=TYPE_TAG_NAME(type);
+                        if(tstr) apigetctype(V_STRUCT, tstr, t);
+                        type=0;
+		}
+		break;
+
+		/* we don;t have all the info about it */
+		case TYPE_CODE_VOID:
+			eppic_parsetype("int", t, 0);
+                        type=0;
+		break;
+
+
+		default:
+			eppic_error("Oops drilldowntype");
+		break;
+		}
+
+
+	}
+	eppic_setupidx(t, ref, nidx, idxlst);
+	if(fctflg) eppic_type_setfct(t, 1);
+	eppic_pushref(t, ref+(nidx?1:0));
+	if(tstr) return eppic_strdup(tstr);
+	return eppic_strdup("");
+}
+
+static char *
+apigetrtype(ull idx, TYPE_S *t)
+{
+	return drilldowntype((struct type*)(unsigned long)(idx), t);
+}
+
+/*
+   	Return the name of a symbol at an address (if any)
+*/
+static char*
+apifindsym(char *p)
+{
+    return NULL;
+}
+
+
+/*
+	Get the type, size and position information for a member of a structure.
+*/
+static char*
+apimember(char *mname,  ull tnum, TYPE_S *tm, MEMBER_S *m, ull *lnum)
+{
+struct type *type=(struct type*)(unsigned long)tnum;
+int midx;
+#define LASTNUM (*lnum)
+
+	/* if we're being asked the next member in a getfirst/getnext sequence */
+	if(mname && !mname[0] && LASTNUM) {
+
+		midx = LASTNUM;
+
+	} else {
+
+		if (TYPE_CODE(type) == TYPE_CODE_TYPEDEF) {
+			return 0;
+		}
+		if ((TYPE_CODE(type) != TYPE_CODE_STRUCT) && (TYPE_CODE(type) != TYPE_CODE_UNION)) {
+			return 0;
+		}
+                midx=0;
+	}
+	while(midx < TYPE_NFIELDS(type)) {
+
+		if (!mname || !mname[0] || !strcmp(mname, TYPE_FIELD_NAME(type, midx))) {
+
+                        check_typedef(TYPE_FIELD_TYPE(type, midx));
+			eppic_member_soffset(m, TYPE_FIELD_BITPOS(type, midx)/8);
+			eppic_member_ssize(m, TYPE_FIELD_TYPE(type, midx)->length);
+			eppic_member_snbits(m, TYPE_FIELD_BITSIZE(type, midx));
+			eppic_member_sfbit(m, TYPE_FIELD_BITPOS(type, midx)%8);
+			eppic_member_sname(m, TYPE_FIELD_NAME(type, midx));
+			LASTNUM=midx+1;
+			return drilldowntype(TYPE_FIELD_TYPE(type, midx), tm);
+		}
+		midx++;
+	}
+	return 0;
+}
+
+/*
+	This function gets the proper allignment value for a type.
+*/
+static int
+apialignment(ull idx)
+{
+struct type *type=(struct type *)(unsigned long)idx;
+
+    while(1)
+    {
+	switch(TYPE_CODE(type)) {
+
+	    case TYPE_CODE_ARRAY: case TYPE_CODE_TYPEDEF:
+		    type=TYPE_TARGET_TYPE(type);
+	    break;
+
+	    case TYPE_CODE_STRUCT:
+	    case TYPE_CODE_UNION:
+	    {
+		int max=0, cur;
+		int midx=0;
+
+		while(midx < TYPE_NFIELDS(type)) {
+                    cur=apialignment((ull)(unsigned long)TYPE_FIELD_TYPE(type, midx));
+	            if(cur > max) max=cur;
+	            midx++;
+		}
+		return max;
+            }
+
+
+	    case TYPE_CODE_PTR:
+	    case TYPE_CODE_ENUM:
+	    case TYPE_CODE_INT:
+
+		    return TYPE_LENGTH (type);
+
+	    default:
+
+		    eppic_error("Oops apialignment");
+	}
+    }
+}
+
+/* get the value of a symbol */
+static int
+apigetval(char *name, ull *val,  VALUE_S *value)
+{
+    if (symbol_exists(name)) {
+
+        *val=symbol_value(name);
+
+        if(value) {
+            struct expression *expr;
+            struct value *sval;
+            struct cleanup *old_chain = NULL;
+            struct type *type;
+            VALUE_S *vref;
+            TYPE_S *stype;
+            expr = parse_expression (name);
+            old_chain = make_cleanup (free_current_contents, &expr);
+            sval = evaluate_type (expr);
+            type = value_type(sval);
+            stype=eppic_gettype(value);
+            apigetrtype((ull)type, stype);
+            eppic_pushref(stype, 1);
+            eppic_setmemaddr(value, *val);
+            eppic_do_deref(1, value, value);
+            *val=eppic_getval(value);
+            if(!eppic_typeislocal(stype) && eppic_type_getidx(stype) > 100) {
+                char *tname;
+                type=(struct type*)((long)eppic_type_getidx(stype));
+                if(type->main_type) tname=type->main_type->tag_name;
+                if(tname) eppic_chktype(stype, tname);
+            }
+            do_cleanups (old_chain);
+        }
+        return 1;
+    }
+    return 0;
+}
+
+/*
+	Get the list of enum symbols.
+*/
+ENUM_S*
+apigetenum(char *name)
+{
+    struct symbol *sym;
+
+#ifdef GDB_6_1
+    sym = lookup_symbol(name, 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL);
+#else
+    sym = lookup_symbol(name, 0, STRUCT_DOMAIN, 0);
+#endif
+    if (sym && TYPE_CODE(sym->type)==TYPE_CODE_ENUM) {
+	ENUM_S *et=0;
+        struct type *type=sym->type;
+        int n=0;
+	while(n < TYPE_NFIELDS (type)) {
+      	    et=eppic_add_enum(et, eppic_strdup(TYPE_FIELD_NAME(type, n)), TYPE_FIELD_BITPOS(type, n));
+            n++;
+	}
+        return et;
+    }
+    return 0;
+}
+
+/*
+	Return the list of preprocessor defines.
+	For Irix we have to get the die for a startup.c file.
+	Of dwarf type DW_TAG_compile_unit.
+	the DW_AT_producer will contain the compile line.
+
+	We then need to parse that line to get all the -Dname[=value]
+*/
+DEF_S *
+apigetdefs(void)
+{
+DEF_S *dt=0;
+int i;
+static struct linuxdefs_s {
+
+	char *name;
+	char *value;
+
+} linuxdefs[] = {
+
+	{"crash",		"1"},
+	{"linux",		"1"},
+	{"__linux",		"1"},
+	{"__linux__",		"1"},
+	{"unix",		"1"},
+	{"__unix",		"1"},
+	{"__unix__",		"1"},
+	// helper macros
+	{"LINUX_2_2_16",	"(LINUX_RELEASE==0x020210)"},
+	{"LINUX_2_2_17",	"(LINUX_RELEASE==0x020211)"},
+	{"LINUX_2_4_0",		"(LINUX_RELEASE==0x020400)"},
+	{"LINUX_2_2_X",		"(((LINUX_RELEASE) & 0xffff00) == 0x020200)"},
+	{"LINUX_2_4_X",		"(((LINUX_RELEASE) & 0xffff00) == 0x020400)"},
+	{"LINUX_2_6_X",		"(((LINUX_RELEASE) & 0xffff00) == 0x020600)"},
+	{"LINUX_3_X_X",         "(((LINUX_RELEASE) & 0xff0000) == 0x030000)"},
+	{"NULL",         "0"},
+#ifdef i386
+	{"i386",         "1"},
+	{"__i386",       "1"},
+	{"__i386__",     "1"},
+	{"BITS_PER_LONG","32"},
+#endif
+#ifdef s390
+	{"s390",         "1"},
+	{"__s390",       "1"},
+	{"__s390__",     "1"},
+	{"BITS_PER_LONG","32"},
+#endif
+#ifdef s390x
+	 {"s390x",       "1"},
+	 {"__s390x",     "1"},
+	 {"__s390x__",   "1"},
+	{"BITS_PER_LONG","32"},
+#endif
+#ifdef __ia64__
+	{"ia64",         "1"},
+	{"__ia64",       "1"},
+	{"__ia64__",     "1"},
+	{"__LP64__",     "1"},
+	{"_LONGLONG",    "1"},
+	{"__LONG_MAX__", "9223372036854775807L"},
+	{"BITS_PER_LONG","64"},
+#endif
+#ifdef __x86_64__
+	{"x86_64",         "1"},
+	{"_x86_64_",       "1"},
+	{"__x86_64__",     "1"},
+	{"__LP64__",     "1"},
+	{"_LONGLONG",    "1"},
+	{"__LONG_MAX__", "9223372036854775807L"},
+	{"BITS_PER_LONG","64"},
+#endif
+#ifdef ppc64
+	{"ppc64",       "1"},
+	{"__ppc64",     "1"},
+	{"__ppc64__",   "1"},
+	{"BITS_PER_LONG","64"},
+#endif
+	};
+
+static char *untdef[] = {
+    "clock",
+    "mode",
+    "pid",
+    "uid",
+    "xtime",
+    "init_task",
+    "size",
+    "type",
+    "level",
+    0
+};
+
+#if 0
+How to extract basic set of -D flags from the kernel image
+
+	prod=eppic_strdup(kl_getproducer());
+	for(p=prod; *p; p++) {
+
+		if(*p=='-' && *(p+1)=='D') {
+
+			char *def=p+2;
+
+			while(*p && *p != '=' && *p != ' ') p++;
+
+			if(!*p || *p == ' ') {
+
+				*p='\0';
+				dt=eppic_add_def(dt, eppic_strdup(def), eppic_strdup("1"));
+
+			} else {
+
+				char *val=p+1;
+
+				*p++='\0';
+				while(*p && *p != ' ') p++;
+				*p='\0';
+
+				dt=eppic_add_def(dt, eppic_strdup(def), eppic_strdup(val));
+			}
+		}
+	}
+#endif
+
+        /* remove some tdef with very usual identifier.
+           could also be cases where the kernel defined a type and variable with same name e.g. xtime.
+           the same can be accomplished in source using #undef <tdefname> or forcing the evaluation of
+           a indentifier as a variable name ex: __var(xtime).
+
+           I tried to make the grammar as unambiqguous as I could.
+
+           If this becomes to much of a problem I might diable usage of all image typedefs usage in eppic!
+        */
+        {
+            char **tdefname=untdef;
+            while(*tdefname) eppic_addneg(*tdefname++);;
+
+        }
+
+	/* insert constant defines from list above */
+	for(i=0;i<sizeof(linuxdefs)/sizeof(linuxdefs[0]);i++) {
+
+		dt=eppic_add_def(dt, eppic_strdup(linuxdefs[i].name),
+			eppic_strdup(linuxdefs[i].value));
+	}
+
+#if 1
+        {
+            ull addr;
+            char banner[200];
+            if(apigetval("linux_banner", &addr, NULL)) {
+                if(apigetmem(addr, banner, sizeof banner-1)) {
+
+                    // parse the banner string and set up release macros
+                    banner[sizeof banner -1]='\0';
+                    char *tok=strtok(banner, " \t");
+                    if(tok) tok=strtok(NULL, " \t");
+                    if(tok) tok=strtok(NULL, " \t");
+                    if(tok) {
+                        int version, patchlevel, sublevel, ret;
+                        ret = sscanf(tok, "%d.%d.%d-", &version, &patchlevel, &sublevel);
+			switch (ret) {
+			case 2:
+			    sublevel = 0;
+			case 3:
+			    sprintf(banner, "0x%02x%02x%02x", version, patchlevel, sublevel);
+		            dt=eppic_add_def(dt, eppic_strdup("LINUX_RELEASE"), eppic_strdup(banner));
+                            eppic_msg("Core LINUX_RELEASE == '%s'\n", tok);
+			default:
+			    break;
+                        }
+                    }
+                }
+                else eppic_msg("Eppic init: could not read symbol 'linux_banner' from corefile.\n");
+            }
+            else eppic_msg("Eppic init: could not find symbol 'linux_banner' in corefile.\n");
+        }
+#endif
+	return dt;
+}
+
+apiops icops= {
+	apigetmem,
+	apiputmem,
+	apimember,
+	apigetctype,
+	apigetrtype,
+	apialignment,
+	apigetval,
+	apigetenum,
+	apigetdefs,
+	apigetuint8,
+	apigetuint16,
+	apigetuint32,
+	apigetuint64,
+	apifindsym
+};
+
+void
+eppic_version(void)
+{
+	eppic_msg("< Eppic interpreter version %d.%d >\n"
+		, S_MAJOR, S_MINOR);
+}
+
+static void
+run_callback(void)
+{
+extern char *crash_global_cmd();
+FILE *ofp = NULL;
+
+	if (fp) {
+		ofp = eppic_getofile();
+		eppic_setofile(fp);
+	}
+
+	eppic_cmd(crash_global_cmd(), args, argcnt);
+
+	if (ofp)
+		eppic_setofile(ofp);
+}
+
+
+void
+edit_cmd(void)
+{
+int c, file=0;
+        while ((c = getopt(argcnt, args, "lf")) != EOF) {
+                switch(c)
+                {
+                case 'l':
+                    eppic_vilast();
+                    return;
+                break;
+                case 'f':
+                    file++;
+                break;
+                default:
+                        argerrs++;
+                        break;
+                }
+        }
+
+        if (argerrs)
+                cmd_usage(crash_global_cmd(), SYNOPSIS);
+
+        else if(args[optind]) {
+            while(args[optind]) {
+	        eppic_vi(args[optind++], file);
+            }
+	}
+        else cmd_usage(crash_global_cmd(), SYNOPSIS);
+}
+
+char *edit_help[]={
+		"edit",
+                "Start a $EDITOR session of a eppic function or file",
+                "<-f fileName>|<function name>",
+                "This command can be use during a tight development cycle",
+                "where frequent editing->run->editing sequences are executed.",
+                "To edit a known eppic macro file use the -f option. To edit the file",
+                "at the location of a known function's declaration omit the -f option.",
+                "Use a single -l option to be brought to the last compile error location.",
+                "",
+                "EXAMPLES:",
+                "  %s> edit -f ps",
+                "  %s> edit ps",
+                "  %s> edit ps_opt",
+                "  %s> edit -l",
+                NULL
+};
+
+
+// these control debug mode when parsing (pre-processor and compile)
+int eppicdebug, eppicppdebug;
+
+void
+load_cmd(void)
+{
+	if(argcnt< 2) cmd_usage(crash_global_cmd(), SYNOPSIS);
+	else {
+            eppic_setofile(fp);
+            eppic_loadunload(1, args[1], 0);
+        }
+}
+
+char *load_help[]={
+		"load",
+                "Load a eppic file",
+                "<fileName>|<Directory>",
+                "  Load a file or a directory. In the case of a directory",
+		"  all files in that directory will be loaded.",
+                NULL
+
+};
+
+void
+unload_cmd(void)
+{
+	if(argcnt < 2) cmd_usage(crash_global_cmd(), SYNOPSIS);
+	else eppic_loadunload(0, args[1], 0);
+}
+
+char *unload_help[]={
+		"unload",
+                "Unload a eppic file",
+                "<fileName>|<Directory>",
+                "  Unload a file or a directory. In the case of a directory",
+		"  all files in that directory will be unloaded.",
+                NULL
+};
+
+void
+sdebug_cmd(void)
+{
+	if(argcnt < 2) eppic_msg("Current eppic debug level is %d\n", eppic_getdbg());
+	else eppic_setdbg(atoi(args[1]));
+}
+
+char *sdebug_help[]={
+		"sdebug",
+                "Print or set eppic debug level",
+                "<Debug level 0..9>",
+                "  Set the debug of eppic. Without any parameter, shows the current debug level.",
+                NULL
+};
+
+void
+sname_cmd(void)
+{
+	if(argcnt < 2) {
+            if(eppic_getname()) eppic_msg("Current eppic name match is '%s'\n", eppic_getname());
+            else eppic_msg("No name match specified yet.\n");
+	} else eppic_setname(args[1]);
+}
+
+char *sname_help[]={
+		"sname",
+                "Print or set eppic name match.",
+                "<name>",
+                "  Set eppic name string for matches. Debug messages that are object oriented",
+                "  will only be displayed if the object name (struct, type, ...) matches this",
+		"  value.",
+                NULL
+};
+
+void
+sclass_cmd(void)
+{
+	if(argcnt < 2) {
+            char **classes=eppic_getclass();
+            eppic_msg("Current eppic classes are :");
+            while(*classes) eppic_msg("'%s' ", *classes++);
+            eppic_msg("\n");
+
+        }
+        else {
+            int i;
+            for(i=1; i<argcnt; i++) eppic_setclass(args[i]);
+        }
+}
+
+char *sclass_help[]={
+		"sclass",
+                "Print or set eppic debug message class(es).",
+                "<className>[, <className>]",
+                "  Set eppic debug classes. Only debug messages that are in the specified classes",
+                "  will be displayed.",
+                NULL
+};
+
+#define NCMDS 200
+static struct command_table_entry command_table[NCMDS] =  {
+
+	{"edit", edit_cmd, edit_help},
+	{"load", load_cmd, load_help},
+	{"unload", unload_cmd, unload_help},
+	{"sdebug", sdebug_cmd, sdebug_help},
+	{"sname", sname_cmd, sname_help},
+	{"sclass", sclass_cmd, sclass_help},
+	{(char *)0 }
+};
+
+static void
+add_eppic_cmd(char *name, void (*cmd)(void), char **help, int flags)
+{
+struct command_table_entry *cp;
+struct command_table_entry *crash_cmd_table();
+
+    // check for a clash with native commands
+    for (cp = crash_cmd_table(); cp->name; cp++) {
+        if (!strcmp(cp->name, name)) {
+            eppic_msg("Eppic command name '%s' conflicts with native crash command.\n", name);
+            return;
+        }
+    }
+
+    // make sure we have enough space for the new command
+    if(!command_table[NCMDS-2].name) {
+        for (cp = command_table; cp->name; cp++);
+        cp->name=eppic_strdup(name);
+        cp->func=cmd;
+        cp->help_data=help;
+        cp->flags=flags;
+    }
+}
+
+static void
+rm_eppic_cmd(char *name)
+{
+struct command_table_entry *cp, *end;
+
+    for (cp = command_table; cp->name; cp++) {
+        if (!strcmp(cp->name, name)) {
+            eppic_free(cp->name);
+            memmove(cp, cp+1, sizeof *cp *(NCMDS-(cp-command_table)-1));
+            break;
+        }
+    }
+}
+
+/*
+	This function is called for every new function
+	generated by a load command. This enables us to
+	register new commands.
+
+	We check here is the functions:
+
+	fname_help()
+	fname_opt()
+	and
+	fname_usage()
+
+	exist, and if so then we have a new command.
+	Then we associated (register) a function with
+	the standard eppic callbacks.
+*/
+void
+reg_callback(char *name, int load)
+{
+char fname[MAX_SYMNAMELEN+sizeof("_usage")+1];
+char *help_str, *opt_str;
+char **help=malloc(sizeof *help * 5);
+
+    if(!help) return;
+    snprintf(fname, sizeof(fname), "%s_help", name);
+    if(eppic_chkfname(fname, 0)) {
+        snprintf(fname, sizeof(fname), "%s_usage", name);
+        if(eppic_chkfname(fname, 0)) {
+            if(load) {
+                opt_str=eppic_strdup((char*)(unsigned long)eppic_exefunc(fname, 0));
+                snprintf(fname, sizeof(fname), "%s_help", name);
+                help_str=eppic_strdup((char*)(unsigned long)eppic_exefunc(fname, 0));
+                help[0]=eppic_strdup(name);
+                help[1]="";
+                help[2]=eppic_strdup(opt_str);
+                help[3]=eppic_strdup(help_str);
+                help[4]=0;
+                add_eppic_cmd(name, run_callback, help, 0);
+                eppic_free(help_str);
+                eppic_free(opt_str);
+                return;
+            }
+            else rm_eppic_cmd(name);
+        }
+    }
+    free(help);
+    return;
+}
+
+/*
+ *  The _fini() function is called if the shared object is unloaded.
+ *  If desired, perform any cleanups here.
+ */
+void _fini()
+{
+    // need to unload any files we have loaded
+
+}
+
+VALUE_S *curtask(VALUE_S *v, ...)
+{
+unsigned long get_curtask();
+    return eppic_makebtype((ull)get_curtask());
+}
+
+_init() /* Register the command set. */
+{
+#define LCDIR "/usr/share/eppic/crash"
+#define LCIDIR "include"
+#define LCUDIR ".eppic"
+
+
+	if(eppic_open() >= 0) {
+
+		char *path, *ipath;
+		char *homepath=0;
+               	char *home=getenv("HOME");
+
+		/* set api, default size, and default sign for types */
+#ifdef i386
+#define EPPIC_ABI  ABI_INTEL_X86
+#else
+#ifdef __ia64__
+#define EPPIC_ABI  ABI_INTEL_IA
+#else
+#ifdef __x86_64__
+#define EPPIC_ABI  ABI_INTEL_IA
+#else
+#ifdef __s390__
+#define EPPIC_ABI  ABI_S390
+#else
+#ifdef __s390x__
+#define EPPIC_ABI  ABI_S390X
+#else
+#ifdef PPC64
+#define EPPIC_ABI  ABI_PPC64
+#else
+#error eppic: Unkown ABI
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+		eppic_apiset(&icops, EPPIC_ABI, sizeof(long), 0);
+
+		eppic_version();
+
+        	/* set the macro search path */
+        	if(!(path=getenv("EPPIC_MPATH"))) {
+
+                	if(home) {
+
+                        	path=eppic_alloc(strlen(home)+sizeof(LCUDIR)+sizeof(LCDIR)+4);
+				homepath=eppic_alloc(strlen(home)+sizeof(LCUDIR)+2);
+
+				/* build a path for call to eppic_load() */
+				strcpy(homepath, home);
+				strcat(homepath, "/");
+				strcat(homepath, LCUDIR);
+
+				/* built the official path */
+                        	strcpy(path, LCDIR);
+                        	strcat(path, ":");
+                        	strcat(path, home);
+                        	strcat(path, "/");
+				strcat(path, LCUDIR);
+                	}
+                	else path=LCDIR;
+		}
+		eppic_setmpath(path);
+
+		fprintf(fp, "\tLoading eppic commands from %s .... ",
+                                         path);
+
+		/* include path */
+		if(!(ipath=getenv("EPPIC_IPATH"))) {
+
+                	if(home) {
+
+                        	ipath=eppic_alloc(strlen(home)+sizeof(LCDIR)+sizeof(LCUDIR)+(sizeof(LCIDIR)*2)+(sizeof("/usr/include")+2)+6);
+
+				/* built the official path */
+                        	strcpy(ipath, LCDIR);
+                        	strcat(ipath, "/"LCIDIR":");
+                        	strcat(ipath, home);
+                        	strcat(ipath, "/");
+				strcat(ipath, LCUDIR);
+				strcat(ipath, "/"LCIDIR);
+				strcat(ipath, ":/usr/include");
+                	}
+                	else ipath=LCDIR"/"LCIDIR;
+		}
+		eppic_setipath(ipath);
+
+		/* set the new function callback */
+		eppic_setcallback(reg_callback);
+
+		/* load the default macros */
+		eppic_loadall();
+
+		/* load some eppic specific commands */
+                register_extension(command_table);
+
+                /* some builtins */
+        	eppic_builtin("int curtask()", curtask);
+
+                fprintf(fp, "Done.\n");
+	}
+        return 1;
+}
+


[System]
You are a security patch backporting assistant for SUSE/openSUSE.

Given a CVE description and an upstream fix, adapt the patch to work with
the target SUSE package version. Output the backported patch in unified
diff format. If the upstream fix applies directly, output it unchanged.

[User]
## CVE: CVE-2016-8666, CVE-2016-5195

filesys.c |   37 ++++++++++++++++++++++++++++---------

## Package
crash

## Files to modify
- filesys.c

## Target Source Code

### filesys.c

#### region() [lines 481-587]
```c
					break;
			}
		} while (i != start);
	}

	return searchdirs;
}

static int
build_kernel_directory(char *buf)
{
	char *p1, *p2;

	if (!strstr(kt->proc_version, "Linux version "))
		return FALSE;

	BZERO(buf, BUFSIZE);
	sprintf(buf, "/lib/modules/");

	p1 = &kt->proc_version[strlen("Linux version ")];
	p2 = &buf[strlen(buf)];

	while (*p1 != ' ')
		*p2++ = *p1++;

	strcat(buf, "/build");
	return TRUE;
}

static int
redhat_kernel_directory_v1(char *buf)
{
	char *p1, *p2;

	if (!strstr(kt->proc_version, "Linux version "))
		return FALSE;

	BZERO(buf, BUFSIZE);
	sprintf(buf, "/usr/src/redhat/BUILD/kernel-");

	p1 = &kt->proc_version[strlen("Linux version ")];
	p2 = &buf[strlen(buf)];

	while (((*p1 >= '0') && (*p1 <= '9')) || (*p1 == '.'))
		*p2++ = *p1++;

	strcat(buf, "/linux");
	return TRUE;
}

static int
redhat_kernel_directory_v2(char *buf)
{
        char *p1, *p2;

        if (!strstr(kt->proc_version, "Linux version "))
                return FALSE;

        BZERO(buf, BUFSIZE);
        sprintf(buf, "/usr/src/redhat/BUILD/kernel-");

        p1 = &kt->proc_version[strlen("Linux version ")];
        p2 = &buf[strlen(buf)];

        while (((*p1 >= '0') && (*p1 <= '9')) || (*p1 == '.'))
                *p2++ = *p1++;

        strcat(buf, "/linux-");

        p1 = &kt->proc_version[strlen("Linux version ")];
        p2 = &buf[strlen(buf)];

        while (((*p1 >= '0') && (*p1 <= '9')) || (*p1 == '.'))
                *p2++ = *p1++;

        return TRUE;
}

static int
redhat_debug_directory(char *buf)
{
        char *p1, *p2;

        if (!strstr(kt->proc_version, "Linux version "))
                return FALSE;

        BZERO(buf, BUFSIZE);
        sprintf(buf, "%s/", pc->redhat_debug_loc);

        p1 = &kt->proc_version[strlen("Linux version ")];
        p2 = &buf[strlen(buf)];

        while (*p1 != ' ')
                *p2++ = *p1++;

        return TRUE;
}

/*
 *  If a namelist was not entered, presume we're using the currently-running
 *  kernel.  Read its version string from /proc/version, and then look in
 *  the search directories for a kernel with the same version string embedded
 *  in it.
 */
static int
find_booted_kernel(void)
```

#### find_booted_kernel() [lines 116-197]
```c
			}
			if (!pc->dumpfile)
				check_live_arch_mismatch();
			if (!find_booted_kernel())
	                	program_usage(SHORT_FORM);
		}

		if (!pc->dumpfile) {
			pc->flags |= LIVE_SYSTEM;
			get_live_memory_source();
		}

		if ((pc->nfd = open(pc->namelist, O_RDONLY)) < 0)
			error(FATAL, "%s: %s\n", pc->namelist, strerror(errno));
		else {
			close(pc->nfd);
			pc->nfd = -1;
		}

		if (LOCAL_ACTIVE() && !(pc->namelist_debug || pc->system_map)) {
			memory_source_init();
			match_proc_version();
		}

	}

	memory_source_init();

	if (ACTIVE())
		proc_kcore_init(fp, UNUSED);

	if (CRASHDEBUG(1)) {
		fprintf(fp, "readmem: %s() ", readmem_function_name());
		if (ACTIVE()) {
			fprintf(fp, "-> %s ", pc->live_memsrc);
			if (pc->flags & MEMMOD)
				fprintf(fp, "(module)");
			else if (pc->flags & CRASHBUILTIN)
				fprintf(fp, "(built-in)");
		}
		fprintf(fp, "\n");
	}
}

/*
 *  Do whatever's necessary to handle the memory source.
 */
static void
memory_source_init(void)
{
	if (REMOTE() && !(pc->flags2 & MEMSRC_LOCAL))
		return;

	if (pc->flags & KERNEL_DEBUG_QUERY)
		return;

        if (LOCAL_ACTIVE()) {
		if (pc->mfd != -1)  /* already been here */
			return;

		if (!STREQ(pc->live_memsrc, "/dev/mem") &&
		     STREQ(pc->live_memsrc, pc->memory_device)) {
			if (memory_driver_init())
				return;

			error(INFO, "cannot initialize crash memory driver\n");
			error(INFO, "using /dev/mem\n\n");
			pc->flags &= ~MEMMOD;
			pc->flags |= DEVMEM;
			pc->readmem = read_dev_mem;
			pc->writemem = write_dev_mem;
			pc->live_memsrc = "/dev/mem";
		}

		if (STREQ(pc->live_memsrc, "/dev/mem")) {
	                if ((pc->mfd = open("/dev/mem", O_RDWR)) < 0) {
	                        if ((pc->mfd = open("/dev/mem", O_RDONLY)) < 0)
	                                error(FATAL, "/dev/mem: %s\n",
	                                        strerror(errno));
	                } else
	                        pc->flags |= MFD_RDWR;
		} else if (STREQ(pc->live_memsrc, "/proc/kcore")) {
```

## Upstream Fix
```diff
---
 filesys.c |   37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

--- a/filesys.c
+++ b/filesys.c
@@ -530,6 +530,8 @@ static int
 find_booted_kernel(void)
 {
 	char kernel[BUFSIZE];
+	char *kernel_unpacked;
+	char *real_kernel;
 	char buffer[BUFSIZE];
 	char **searchdirs;
 	int i, preferred, wrapped;
@@ -579,16 +581,25 @@ find_booted_kernel(void)
 			sprintf(kernel, "%s%s", searchdirs[i], dp->d_name);

 			if (mount_point(kernel) ||
-			    !file_readable(kernel) ||
-                            !is_elf_file(kernel))
+			    !file_readable(kernel))
 				continue;

+			if (is_compressed_kernel(kernel, &kernel_unpacked))
+				real_kernel = kernel_unpacked;
+			else {
+				kernel_unpacked = NULL;
+				real_kernel = kernel;
+			}
+
 			if (CRASHDEBUG(1))
 				fprintf(fp, "find_booted_kernel: check: %s\n",
 					kernel);

-			found = match_file_string(kernel, kt->proc_version, buffer);
-
+			if (!is_elf_file(real_kernel))
+				continue;
+
+			found = match_file_string(real_kernel, kt->proc_version, buffer);
+
 			if (found)
 				break;
 	        }
@@ -599,17 +610,25 @@ find_booted_kernel(void)
 	build_searchdirs(DESTROY, NULL);

 	if (found) {
-                if ((pc->namelist = (char *)malloc
-		    (strlen(kernel)+1)) == NULL)
+		if ((pc->namelist_orig = strdup(kernel)) == NULL)
+			error(FATAL, "booted kernel real name malloc: %s\n",
+				strerror(errno));
+		else if ((pc->namelist = strdup(real_kernel)) == NULL)
 			error(FATAL, "booted kernel name malloc: %s\n",
 				strerror(errno));
-                else {
-                        strcpy(pc->namelist, kernel);
+                else
 			if (CRASHDEBUG(1))
 				fprintf(fp, "find_booted_kernel: found: %s\n",
 					pc->namelist);
+			if (kernel_unpacked)
+				free(kernel_unpacked);
                         return TRUE;
-                }
+	}
+
+	if (kernel_unpacked) {
+		remove(kernel_unpacked);
+		if (kernel_unpacked)
+			free(kernel_unpacked);
 	}

 	error(INFO,

```

Generate a backported patch for the SUSE target version.

[Assistant]
---
 filesys.c |   37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

--- a/filesys.c
+++ b/filesys.c
@@ -530,6 +530,8 @@ static int
 find_booted_kernel(void)
 {
 	char kernel[BUFSIZE];
+	char *kernel_unpacked;
+	char *real_kernel;
 	char buffer[BUFSIZE];
 	char **searchdirs;
 	int i, preferred, wrapped;
@@ -579,16 +581,25 @@ find_booted_kernel(void)
 			sprintf(kernel, "%s%s", searchdirs[i], dp->d_name);

 			if (mount_point(kernel) ||
-			    !file_readable(kernel) ||
-                            !is_elf_file(kernel))
+			    !file_readable(kernel))
 				continue;

+			if (is_compressed_kernel(kernel, &kernel_unpacked))
+				real_kernel = kernel_unpacked;
+			else {
+				kernel_unpacked = NULL;
+				real_kernel = kernel;
+			}
+
 			if (CRASHDEBUG(1))
 				fprintf(fp, "find_booted_kernel: check: %s\n",
 					kernel);

-			found = match_file_string(kernel, kt->proc_version, buffer);
-
+			if (!is_elf_file(real_kernel))
+				continue;
+
+			found = match_file_string(real_kernel, kt->proc_version, buffer);
+
 			if (found)
 				break;
 	        }
@@ -599,17 +610,25 @@ find_booted_kernel(void)
 	build_searchdirs(DESTROY, NULL);

 	if (found) {
-                if ((pc->namelist = (char *)malloc
-		    (strlen(kernel)+1)) == NULL)
+		if ((pc->namelist_orig = strdup(kernel)) == NULL)
+			error(FATAL, "booted kernel real name malloc: %s\n",
+				strerror(errno));
+		else if ((pc->namelist = strdup(real_kernel)) == NULL)
 			error(FATAL, "booted kernel name malloc: %s\n",
 				strerror(errno));
-                else {
-                        strcpy(pc->namelist, kernel);
+                else
 			if (CRASHDEBUG(1))
 				fprintf(fp, "find_booted_kernel: found: %s\n",
 					pc->namelist);
+			if (kernel_unpacked)
+				free(kernel_unpacked);
                         return TRUE;
-                }
+	}
+
+	if (kernel_unpacked) {
+		remove(kernel_unpacked);
+		if (kernel_unpacked)
+			free(kernel_unpacked);
 	}

 	error(INFO,