[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-2013-5634, CVE-2015-8956, CVE-2016-2069, CVE-2016-5696, CVE-2016-6130, CVE-2016-6327, CVE-2016-6480, CVE-2016-6828, CVE-2016-7042, CVE-2016-7097, CVE-2016-7425, CVE-2016-8658

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

## Package
crash

## Files to modify
- extensions/eppic.mk

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

--- 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 ]; \
--- /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(-)

--- 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 ]; \
--- /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-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
- b/filesys.c

## Target Source Code

### filesys.c

#### region() [lines 480-586]
```c
				else
					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() [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
From: Petr Tesarik <ptesarik@suse.cz>
Subject: Automatically detect compressed booted kernel
References: bnc#777516, bnc#828260
Patch-mainline: not yet

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

---
 filesys.c |   26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

Index: b/filesys.c
===================================================================
--- a/filesys.c
+++ b/filesys.c
@@ -529,6 +529,7 @@ static int
 find_booted_kernel(void)
 {
 	char kernel[BUFSIZE];
+	char *real_kernel;
 	char buffer[BUFSIZE];
 	char **searchdirs;
 	int i, preferred, wrapped;
@@ -578,16 +579,24 @@ 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, &real_kernel))
+				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)) {
+				if (real_kernel != kernel)
+					free(real_kernel);
+				continue;
+			}
+
+			found = match_file_string(real_kernel, kt->proc_version, buffer);
+
 			if (found)
 				break;
 	        }
@@ -607,10 +616,19 @@ find_booted_kernel(void)
 			if (CRASHDEBUG(1))
 				fprintf(fp, "find_booted_kernel: found: %s\n",
 					pc->namelist);
+			if (real_kernel != kernel) {
+				pc->namelist_orig = pc->namelist;
+				pc->namelist = real_kernel;
+			}
                         return TRUE;
                 }
 	}

+	if (real_kernel != kernel) {
+		remove(real_kernel);
+		free(real_kernel);
+	}
+
 	error(INFO,
              "cannot find booted kernel -- please enter namelist argument\n\n");
 	return FALSE;

```

Generate a backported patch for the SUSE target version.

[Assistant]
From: Petr Tesarik <ptesarik@suse.cz>
Subject: Automatically detect compressed booted kernel
References: bnc#777516, bnc#828260
Patch-mainline: not yet

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

---
 filesys.c |   26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

Index: b/filesys.c
===================================================================
--- a/filesys.c
+++ b/filesys.c
@@ -529,6 +529,7 @@ static int
 find_booted_kernel(void)
 {
 	char kernel[BUFSIZE];
+	char *real_kernel;
 	char buffer[BUFSIZE];
 	char **searchdirs;
 	int i, preferred, wrapped;
@@ -578,16 +579,24 @@ 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, &real_kernel))
+				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)) {
+				if (real_kernel != kernel)
+					free(real_kernel);
+				continue;
+			}
+
+			found = match_file_string(real_kernel, kt->proc_version, buffer);
+
 			if (found)
 				break;
 	        }
@@ -607,10 +616,19 @@ find_booted_kernel(void)
 			if (CRASHDEBUG(1))
 				fprintf(fp, "find_booted_kernel: found: %s\n",
 					pc->namelist);
+			if (real_kernel != kernel) {
+				pc->namelist_orig = pc->namelist;
+				pc->namelist = real_kernel;
+			}
                         return TRUE;
                 }
 	}

+	if (real_kernel != kernel) {
+		remove(real_kernel);
+		free(real_kernel);
+	}
+
 	error(INFO,
              "cannot find booted kernel -- please enter namelist argument\n\n");
 	return FALSE;


[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
- b/symbols.c

## Target Source Code

### symbols.c

#### symtab_init() [lines 161-255]
```c
 *  sorts, and stores, them in a static table for quick reference.
 */
void
symtab_init(void)
{
	char **matching;
  	long symcount;
  	void *minisyms;
  	unsigned int size;
	asymbol *sort_x;
	asymbol *sort_y;

  	if ((st->bfd = bfd_openr(pc->namelist, NULL)) == NULL)
		error(FATAL, "cannot open object file: %s\n", pc->namelist);

  	if (!bfd_check_format_matches(st->bfd, bfd_object, &matching))
		error(FATAL, "cannot determine object file format: %s\n",
			pc->namelist);
	/*
	 *  Check whether the namelist is a kerntypes file built by
	 *  dwarfextract, which places a magic number in e_version.
	 */
	if (file_elf_version(pc->namelist) == EV_DWARFEXTRACT)
		pc->flags |= KERNTYPES;

	if (pc->flags & SYSMAP) {
		bfd_map_over_sections(st->bfd, section_header_info,
			VERIFY_SECTIONS);
		if ((st->flags & (NO_SEC_LOAD|NO_SEC_CONTENTS)) ==
		    (NO_SEC_LOAD|NO_SEC_CONTENTS)) {
			error(INFO, "%s: no text and data contents\n",
				pc->namelist);
			error(FATAL, pc->flags & SYSMAP_ARG ?
				DEBUGINFO_ERROR_MESSAGE1 :
				DEBUGINFO_ERROR_MESSAGE2);
		}
		store_sysmap_symbols();
		return;
	} else if (LKCD_KERNTYPES())
		error(FATAL, "%s: use of kerntypes requires a system map\n",
			pc->namelist);

	/*
	 *  Pull a bait-and-switch on st->bfd if we've got a separate
         *  .gnu_debuglink file that matches the CRC. Not done for kerntypes.
	 */
	if (!(LKCD_KERNTYPES()) &&
	    !(bfd_get_file_flags(st->bfd) & HAS_SYMS)) {
		if (!check_gnu_debuglink(st->bfd))
			no_debugging_data(FATAL);
	}

	/*
	 *  Gather references to the kernel sections.
	 */
        if ((st->sections = (struct sec *)
             malloc(st->bfd->section_count * sizeof(struct sec *))) == NULL)
                error(FATAL, "symbol table section array malloc: %s\n",
                        strerror(errno));
	BZERO(st->sections, st->bfd->section_count * sizeof(struct sec *));
	st->first_section_start = st->last_section_end = 0;

	bfd_map_over_sections(st->bfd, section_header_info, KERNEL_SECTIONS);
	if ((st->flags & (NO_SEC_LOAD|NO_SEC_CONTENTS)) ==
	    (NO_SEC_LOAD|NO_SEC_CONTENTS)) {
		if (!pc->namelist_debug && !pc->debuginfo_file) {
			error(INFO, "%s: no text and data contents\n",
				pc->namelist);
			error(FATAL, DEBUGINFO_ERROR_MESSAGE2);
		}
	}

	symcount = bfd_read_minisymbols(st->bfd, FALSE, &minisyms, &size);

	if (symcount <= 0)
		no_debugging_data(FATAL);

	sort_x = bfd_make_empty_symbol(st->bfd);
	sort_y = bfd_make_empty_symbol(st->bfd);
	if (sort_x == NULL || sort_y == NULL)
		error(FATAL, "bfd_make_empty_symbol() failed\n");

	kaslr_init();

	gnu_qsort(st->bfd, minisyms, symcount, size, sort_x, sort_y);

	store_symbols(st->bfd, FALSE, minisyms, symcount, size);

	free(minisyms);

	symname_hash_init();
	symval_hash_init();
}

/*
```

#### check_gnu_debuglink() [lines 206-232]
```c
	 */
	if (!(LKCD_KERNTYPES()) &&
	    !(bfd_get_file_flags(st->bfd) & HAS_SYMS)) {
		if (!check_gnu_debuglink(st->bfd))
			no_debugging_data(FATAL);
	}

	/*
	 *  Gather references to the kernel sections.
	 */
        if ((st->sections = (struct sec *)
             malloc(st->bfd->section_count * sizeof(struct sec *))) == NULL)
                error(FATAL, "symbol table section array malloc: %s\n",
                        strerror(errno));
	BZERO(st->sections, st->bfd->section_count * sizeof(struct sec *));
	st->first_section_start = st->last_section_end = 0;

	bfd_map_over_sections(st->bfd, section_header_info, KERNEL_SECTIONS);
	if ((st->flags & (NO_SEC_LOAD|NO_SEC_CONTENTS)) ==
	    (NO_SEC_LOAD|NO_SEC_CONTENTS)) {
		if (!pc->namelist_debug && !pc->debuginfo_file) {
			error(INFO, "%s: no text and data contents\n",
				pc->namelist);
			error(FATAL, DEBUGINFO_ERROR_MESSAGE2);
		}
	}

```

## Upstream Fix
```diff
From: Petr Tesarik <ptesarik@suse.cz>
Subject: Search debuginfo files in the original directory
References: bnc#723639

If debuginfo is in a separate file and the kernel image is compressed,
then it should be found in the same directory as the original (compressed)
image, not in the directory with the uncompressed image (TMPDIR).

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

---
 symbols.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

Index: b/symbols.c
===================================================================
--- a/symbols.c
+++ b/symbols.c
@@ -192,9 +192,9 @@ symtab_init(void)
 	 *  Pull a bait-and-switch on st->bfd if we've got a separate
          *  .gnu_debuglink file that matches the CRC. Not done for kerntypes.
 	 */
-	if (!(LKCD_KERNTYPES()) &&
-	    !(bfd_get_file_flags(st->bfd) & HAS_SYMS)) {
-		if (!check_gnu_debuglink(st->bfd))
+	if (!(LKCD_KERNTYPES())) {
+		if (!check_gnu_debuglink(st->bfd) &&
+		    !(bfd_get_file_flags(st->bfd) & HAS_SYMS))
 			no_debugging_data(FATAL);
 	}

@@ -253,13 +253,16 @@ check_gnu_debuglink(bfd *bfd)
 	char *contents;
 	int crc_offset;
 	unsigned long crc32;
+	char *namelist;
 	char *dirname;
 	char *namelist_debug;
         char **matching;

+	namelist = pc->namelist_orig ? pc->namelist_orig : pc->namelist;
+
         sect = bfd_get_section_by_name(bfd, ".gnu_debuglink");
 	if (!sect) {
-		error(INFO, "%s: no .gnu_debuglink section\n", pc->namelist);
+		error(INFO, "%s: no .gnu_debuglink section\n", namelist);
 		return FALSE;
 	}

@@ -280,14 +283,14 @@ check_gnu_debuglink(bfd *bfd)
 			contents, crc32);

   	if ((pc->debuginfo_file = (char *)
-	    malloc(((strlen(pc->namelist) + strlen("/.debug/") +
+	    malloc(((strlen(namelist) + strlen("/.debug/") +
 	    + strlen(".debug") + strlen(" /usr/lib/debug/boot/ "))*10)
 	    + strlen(pc->namelist_debug ? pc->namelist_debug : " "))) == NULL)
 		error(FATAL, "debuginfo file name malloc: %s\n",
 			strerror(errno));

-	dirname = GETBUF(strlen(pc->namelist)+1);
-	strcpy(dirname, pc->namelist);
+	dirname = GETBUF(strlen(namelist)+1);
+	strcpy(dirname, namelist);

   	for (i = strlen(dirname)-1; i >= 0; i--)
     	{

```

Generate a backported patch for the SUSE target version.

[Assistant]
From: Petr Tesarik <ptesarik@suse.cz>
Subject: Search debuginfo files in the original directory
References: bnc#723639

If debuginfo is in a separate file and the kernel image is compressed,
then it should be found in the same directory as the original (compressed)
image, not in the directory with the uncompressed image (TMPDIR).

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

---
 symbols.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

Index: b/symbols.c
===================================================================
--- a/symbols.c
+++ b/symbols.c
@@ -192,9 +192,9 @@ symtab_init(void)
 	 *  Pull a bait-and-switch on st->bfd if we've got a separate
          *  .gnu_debuglink file that matches the CRC. Not done for kerntypes.
 	 */
-	if (!(LKCD_KERNTYPES()) &&
-	    !(bfd_get_file_flags(st->bfd) & HAS_SYMS)) {
-		if (!check_gnu_debuglink(st->bfd))
+	if (!(LKCD_KERNTYPES())) {
+		if (!check_gnu_debuglink(st->bfd) &&
+		    !(bfd_get_file_flags(st->bfd) & HAS_SYMS))
 			no_debugging_data(FATAL);
 	}

@@ -253,13 +253,16 @@ check_gnu_debuglink(bfd *bfd)
 	char *contents;
 	int crc_offset;
 	unsigned long crc32;
+	char *namelist;
 	char *dirname;
 	char *namelist_debug;
         char **matching;

+	namelist = pc->namelist_orig ? pc->namelist_orig : pc->namelist;
+
         sect = bfd_get_section_by_name(bfd, ".gnu_debuglink");
 	if (!sect) {
-		error(INFO, "%s: no .gnu_debuglink section\n", pc->namelist);
+		error(INFO, "%s: no .gnu_debuglink section\n", namelist);
 		return FALSE;
 	}

@@ -280,14 +283,14 @@ check_gnu_debuglink(bfd *bfd)
 			contents, crc32);

   	if ((pc->debuginfo_file = (char *)
-	    malloc(((strlen(pc->namelist) + strlen("/.debug/") +
+	    malloc(((strlen(namelist) + strlen("/.debug/") +
 	    + strlen(".debug") + strlen(" /usr/lib/debug/boot/ "))*10)
 	    + strlen(pc->namelist_debug ? pc->namelist_debug : " "))) == NULL)
 		error(FATAL, "debuginfo file name malloc: %s\n",
 			strerror(errno));

-	dirname = GETBUF(strlen(pc->namelist)+1);
-	strcpy(dirname, pc->namelist);
+	dirname = GETBUF(strlen(namelist)+1);
+	strcpy(dirname, namelist);

   	for (i = strlen(dirname)-1; i >= 0; i--)
     	{


[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

main.c |    8 +-------

## Package
crash

## Files to modify
- b/main.c

## Target Source Code

### main.c

#### setup_environment() [lines 1080-1245]
```c

static void
setup_environment(int argc, char **argv)
{
	int i;
	char *p1;
	char buf[BUFSIZE];
	char homerc[BUFSIZE];
	char localrc[BUFSIZE];
	FILE *afp;
	char *program;

	program = argv[0];

	/*
	 *  Program output typically goes via "fprintf(fp, ...)", but the
	 *  contents of fp are modified on the fly to handle redirection
	 *  to pipes or output files.
	 */
	fp = stdout;

	if (!set_error("default")) {
		fprintf(stderr, "crash: cannot malloc error() path string\n");
		clean_exit(1);
	}

	/*
	 *  Start populating the program_context structure.  It's used so
	 *  frequently that "pc" has been declared globally to point to the
	 *  "program_context" structure.
	 */
        pc->program_name = (char *)basename(program);
	pc->program_path = program;
        pc->program_version = build_version;
	pc->program_pid = (ulong)getpid();
        pc->curcmd = pc->program_name;
        pc->flags = (HASH|SCROLL);
	pc->flags |= DATADEBUG;          /* default until unnecessary */
	pc->flags2 |= REDZONE;
/* ... 114 lines omitted ... */
	    !(pc->flags & NOCRASHRC) && file_exists(localrc, NULL)) {
		if ((afp = fopen(localrc, "r")) == NULL)
                        error(INFO, "cannot open %s: %s\n",
				localrc, strerror(errno));
		else if (untrusted_file(afp, localrc))
			fclose(afp);
		else {
			while (fgets(buf, BUFSIZE, afp))
				resolve_rc_cmd(buf, ALIAS_RCLOCAL);
			fclose(afp);
		}
	}

	if (STREQ(pc->editing_mode, "no_mode"))
		pc->editing_mode = "vi";

	machdep_init(SETUP_ENV);
}

```

## Upstream Fix
```diff
---
 main.c |    8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

Index: b/main.c
===================================================================
--- a/main.c
+++ b/main.c
@@ -1037,12 +1037,6 @@ setup_environment(int argc, char **argv)
 	pc->flags |= READLINE;
 	pc->editing_mode = "no_mode";

-	if ((p1 = getenv("EDITOR"))) {
-		if (strstr(p1, "vi"))
-			pc->editing_mode = "vi";
-		if (strstr(p1, "emacs"))
-			pc->editing_mode = "emacs";
-	}

 	/*
 	 *  Resolve $HOME .rc file first, then the one in the local directory.
@@ -1092,7 +1086,7 @@ setup_environment(int argc, char **argv)
 	}

 	if (STREQ(pc->editing_mode, "no_mode"))
-		pc->editing_mode = "vi";
+		pc->editing_mode = "emacs";

 	machdep_init(SETUP_ENV);
 }

```

Generate a backported patch for the SUSE target version.

[Assistant]
---
 main.c |    8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

Index: b/main.c
===================================================================
--- a/main.c
+++ b/main.c
@@ -1037,12 +1037,6 @@ setup_environment(int argc, char **argv)
 	pc->flags |= READLINE;
 	pc->editing_mode = "no_mode";

-	if ((p1 = getenv("EDITOR"))) {
-		if (strstr(p1, "vi"))
-			pc->editing_mode = "vi";
-		if (strstr(p1, "emacs"))
-			pc->editing_mode = "emacs";
-	}

 	/*
 	 *  Resolve $HOME .rc file first, then the one in the local directory.
@@ -1092,7 +1086,7 @@ setup_environment(int argc, char **argv)
 	}

 	if (STREQ(pc->editing_mode, "no_mode"))
-		pc->editing_mode = "vi";
+		pc->editing_mode = "emacs";

 	machdep_init(SETUP_ENV);
 }


[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
- b/gdb-7.6.patch

## Upstream Fix
```diff
From: Petr Tesarik <ptesarik@suse.cz>
Subject: Add missing includes

This fixes a compilation failure on ppc64.

---
 gdb-7.6.patch |   10 ++++++++++
 1 file changed, 10 insertions(+)

Index: b/gdb-7.6.patch
===================================================================
--- a/gdb-7.6.patch
+++ b/gdb-7.6.patch
@@ -17,6 +17,16 @@
  	./pex-djgpp.$(objext) ./pex-msdos.$(objext)			\
  	 ./pex-unix.$(objext) ./pex-win32.$(objext)			\
  	 ./putenv.$(objext)						\
+--- gdb-7.6/sim/common/gentmap.c.orig
++++ gdb-7.6/sim/common/gentmap.c
+@@ -2,6 +2,7 @@
+
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <string.h>
+
+ struct tdefs {
+   char *symbol;
 --- gdb-7.6/opcodes/i386-dis.c.orig
 +++ gdb-7.6/opcodes/i386-dis.c
 @@ -11510,6 +11510,10 @@ print_insn (bfd_vma pc, disassemble_info

```

Generate a backported patch for the SUSE target version.

[Assistant]
From: Petr Tesarik <ptesarik@suse.cz>
Subject: Add missing includes

This fixes a compilation failure on ppc64.

---
 gdb-7.6.patch |   10 ++++++++++
 1 file changed, 10 insertions(+)

Index: b/gdb-7.6.patch
===================================================================
--- a/gdb-7.6.patch
+++ b/gdb-7.6.patch
@@ -17,6 +17,16 @@
  	./pex-djgpp.$(objext) ./pex-msdos.$(objext)			\
  	 ./pex-unix.$(objext) ./pex-win32.$(objext)			\
  	 ./putenv.$(objext)						\
+--- gdb-7.6/sim/common/gentmap.c.orig
++++ gdb-7.6/sim/common/gentmap.c
+@@ -2,6 +2,7 @@
+
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <string.h>
+
+ struct tdefs {
+   char *symbol;
 --- gdb-7.6/opcodes/i386-dis.c.orig
 +++ gdb-7.6/opcodes/i386-dis.c
 @@ -11510,6 +11510,10 @@ print_insn (bfd_vma pc, disassemble_info


[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

printf("%p %7d %7d %7d 0x%02x 0x%08x %5d:%-5d %s\n"

## Package
crash

## Upstream Fix
```diff
diff -Nurp sial-scripts-2008-02-08.orig//ps.c sial-scripts-2008-02-08/ps.c
--- sial-scripts-2008-02-08.orig//ps.c	2010-03-12 19:59:03.227788951 +0100
+++ sial-scripts-2008-02-08/ps.c	2010-03-12 19:59:16.690665574 +0100
@@ -192,7 +192,11 @@ string cmd;

 	printf("%p %7d %7d %7d 0x%02x 0x%08x %5d:%-5d %s\n"
 		, t
+#if LINUX_RELEASE > 0x02061d
+		, t->real_cred->uid
+#else
 		, t->uid
+#endif
 		, t->pid
 #if LINUX_2_6_X
 		, t->parent->pid

```

Generate a backported patch for the SUSE target version.

[Assistant]
diff -Nurp sial-scripts-2008-02-08.orig//ps.c sial-scripts-2008-02-08/ps.c
--- sial-scripts-2008-02-08.orig//ps.c	2010-03-12 19:59:03.227788951 +0100
+++ sial-scripts-2008-02-08/ps.c	2010-03-12 19:59:16.690665574 +0100
@@ -192,7 +192,11 @@ string cmd;

 	printf("%p %7d %7d %7d 0x%02x 0x%08x %5d:%-5d %s\n"
 		, t
+#if LINUX_RELEASE > 0x02061d
+		, t->real_cred->uid
+#else
 		, t->uid
+#endif
 		, t->pid
 #if LINUX_2_6_X
 		, t->parent->pid


[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

Add quirk for SLES9 LKCD header

## Package
crash

## Files to modify
- b/lkcd_v8.c

## Target Source Code

### lkcd_v8.c

#### lkcd_dump_init_v8_arch() [lines 90-195]
```c

#ifndef HAVE_NO_DUMP_HEADER_ASM
int
lkcd_dump_init_v8_arch(dump_header_t *dh)
{
	off_t 			ret_of;
	ssize_t 		ret_sz;
	uint32_t 		hdr_size, offset, nr_cpus;
	dump_header_asm_t 	arch_hdr;
	char 			*hdr_buf = NULL;

	ret_of = lseek(lkcd->fd, dh->dh_header_size +
			offsetof(dump_header_asm_t, dha_header_size),
			SEEK_SET);
	if (ret_of < 0) {
		perror("lseek failed in " __FILE__ ":" STR(__LINE__));
		goto err;
	}

	ret_sz = read(lkcd->fd, (char *)&hdr_size, sizeof(hdr_size));
	if (ret_sz != sizeof(hdr_size)) {
		perror("Reading hdr_size failed in " __FILE__ ":" STR(__LINE__));
		goto err;
	}

	ret_of = lseek(lkcd->fd, dh->dh_header_size, SEEK_SET);
	if (ret_of < 0) {
		perror("lseek failed in " __FILE__ ":" STR(__LINE__));
		goto err;
	}

	hdr_buf = (char *)malloc(hdr_size);
	if (!hdr_buf) {
		perror("Could not allocate memory for dump header\n");
		goto err;
	}

	ret_sz = read(lkcd->fd, (char *)hdr_buf, hdr_size);
	if (ret_sz != hdr_size) {
		perror("Could not read header " __FILE__ ":" STR(__LINE__));
		goto err;
	}

	/*
         * Though we have KL_NR_CPUS is 128, the header size is different
         * CONFIG_NR_CPUS might be different in the kernel. Hence, need
         * to find out how many CPUs are configured.
         */
        offset = offsetof(dump_header_asm_t, dha_smp_regs[0]);
        nr_cpus = (hdr_size - offset) / sizeof(dump_CPU_info_t);

	/* check for CPU overflow */
	if (nr_cpus > NR_CPUS) {
		fprintf(stderr, "CPU number too high %d (%s:%d)\n",
				nr_cpus, __FILE__, __LINE__);
		goto err;
	}

	/* parts that don't depend on the number of CPUs */
	memcpy(&arch_hdr, (void *)hdr_buf, offset);

	/* registers */
	memcpy(&arch_hdr.dha_smp_regs, (void *)&hdr_buf[offset],
			nr_cpus * sizeof(struct pt_regs));
	offset += nr_cpus * sizeof(struct pt_regs);

	/* current task */
	memcpy(&arch_hdr.dha_smp_current_task, (void *)&hdr_buf[offset],
			nr_cpus * sizeof(&arch_hdr.dha_smp_current_task[0]));
	offset += nr_cpus * sizeof(&arch_hdr.dha_smp_current_task[0]);

	/* stack */
	memcpy(&arch_hdr.dha_stack, (void *)&hdr_buf[offset],
			nr_cpus * sizeof(&arch_hdr.dha_stack[0]));
	offset += nr_cpus * sizeof(&arch_hdr.dha_stack[0]);

	/* stack_ptr */
	memcpy(&arch_hdr.dha_stack_ptr, (void *)&hdr_buf[offset],
			nr_cpus * sizeof(&arch_hdr.dha_stack_ptr[0]));
	offset += nr_cpus * sizeof(&arch_hdr.dha_stack_ptr[0]);

	if (arch_hdr.dha_magic_number != DUMP_ASM_MAGIC_NUMBER) {
		fprintf(stderr, "Invalid magic number for x86_64\n");
		goto err;
	}

	/*
	 * read the kernel load address on IA64 -- other architectures have
	 * no relocatable kernel at the lifetime of LKCD
	 */
#ifdef IA64
	memcpy(&arch_hdr.dha_kernel_addr, (void *)&hdr_buf[offset], sizeof(uint64_t));
#endif

	memcpy(&dump_header_asm_v8, &arch_hdr, sizeof(dump_header_asm_t));

	free(hdr_buf);
	return 0;

err:
	free(hdr_buf);
	return -1;
}

#else /* architecture that has no lkcd_dump_init_v8 */
```

### Type definitions

```c
/* from lkcd_dump_v8.h */
struct pt_regs {
	long ebx;
	long ecx;
	long edx;
	long esi;
	long edi;
	long ebp;
	long eax;
	int  xds;
	int  xes;
	long orig_eax;
	long eip;
	int  xcs;
	long eflags;
	long esp;
	int  xss;
};
```

## Upstream Fix
```diff
From: Bernhard Walle <bwalle@suse.de>
Subject: [PATCH] Add quirk for SLES9 LKCD header
Patch-mainline: never

On SLES9, we have a different header on IA64:

    SLES 10:

    typedef struct __dump_header_asm {
            uint64_t            dha_magic_number;
            uint32_t            dha_version;
            uint32_t            dha_header_size;
            uint64_t            dha_pt_regs;
            struct pt_regs      dha_regs;
            uint64_t            dha_rnat;
            uint64_t            dha_pfs;
            uint64_t            dha_bspstore;
            uint32_t	        dha_smp_num_cpus;
            uint32_t	        dha_dumping_cpu;
            struct pt_regs	dha_smp_regs[NR_CPUS];
            uint64_t	        dha_smp_current_task[NR_CPUS];
            uint64_t	        dha_stack[NR_CPUS];
            uint64_t	        dha_stack_ptr[NR_CPUS];
            uint64_t            dha_kernel_addr;
    } __attribute__((packed)) dump_header_asm_t;

    SLES 9:
    typedef struct __dump_header_asm {
            uint64_t            dha_magic_number;
            uint32_t            dha_version;
            uint32_t            dha_header_size;
            uint64_t            dha_kernel_addr;
            uint64_t            dha_pt_regs;
            struct pt_regs      dha_regs;
            uint64_t            dha_rnat;
            uint64_t            dha_pfs;
            uint64_t            dha_bspstore;
            uint32_t	        dha_smp_num_cpus;
            uint32_t	        dha_dumping_cpu;
            struct pt_regs	dha_smp_regs[NR_CPUS];
            uint64_t	        dha_smp_current_task[NR_CPUS];
            uint64_t	        dha_stack[NR_CPUS];
            uint64_t	        dha_stack_ptr[NR_CPUS];
    } __attribute__((packed)) dump_header_asm_t;

That patch tries to guess if it's a SLES 9 or a SLES 10 header
at runtime.

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

---
 lkcd_v8.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

Index: b/lkcd_v8.c
===================================================================
--- a/lkcd_v8.c
+++ b/lkcd_v8.c
@@ -130,6 +130,17 @@ lkcd_dump_init_v8_arch(dump_header_t *dh
 		goto err;
 	}

+#if IA64
+	/* SLES9 on IA64? */
+	if ( *((uint64_t *)(hdr_buf + hdr_size - sizeof(uint64_t))) <= NR_CPUS) {
+		uint64_t kernel_addr;
+		kernel_addr = ((dump_header_asm_t *)hdr_buf)->dha_pt_regs;
+		memmove(hdr_buf + offsetof(dump_header_asm_t, dha_pt_regs),
+				hdr_buf + offsetof(dump_header_asm_t, dha_regs),
+				hdr_size - offsetof(dump_header_asm_t, dha_regs));
+		*((uint64_t *)(hdr_buf + hdr_size - sizeof(uint64_t))) = kernel_addr;
+	}
+#endif

 	/*
          * Though we have KL_NR_CPUS is 128, the header size is different

```

Generate a backported patch for the SUSE target version.

[Assistant]
From: Bernhard Walle <bwalle@suse.de>
Subject: [PATCH] Add quirk for SLES9 LKCD header
Patch-mainline: never

On SLES9, we have a different header on IA64:

    SLES 10:

    typedef struct __dump_header_asm {
            uint64_t            dha_magic_number;
            uint32_t            dha_version;
            uint32_t            dha_header_size;
            uint64_t            dha_pt_regs;
            struct pt_regs      dha_regs;
            uint64_t            dha_rnat;
            uint64_t            dha_pfs;
            uint64_t            dha_bspstore;
            uint32_t	        dha_smp_num_cpus;
            uint32_t	        dha_dumping_cpu;
            struct pt_regs	dha_smp_regs[NR_CPUS];
            uint64_t	        dha_smp_current_task[NR_CPUS];
            uint64_t	        dha_stack[NR_CPUS];
            uint64_t	        dha_stack_ptr[NR_CPUS];
            uint64_t            dha_kernel_addr;
    } __attribute__((packed)) dump_header_asm_t;

    SLES 9:
    typedef struct __dump_header_asm {
            uint64_t            dha_magic_number;
            uint32_t            dha_version;
            uint32_t            dha_header_size;
            uint64_t            dha_kernel_addr;
            uint64_t            dha_pt_regs;
            struct pt_regs      dha_regs;
            uint64_t            dha_rnat;
            uint64_t            dha_pfs;
            uint64_t            dha_bspstore;
            uint32_t	        dha_smp_num_cpus;
            uint32_t	        dha_dumping_cpu;
            struct pt_regs	dha_smp_regs[NR_CPUS];
            uint64_t	        dha_smp_current_task[NR_CPUS];
            uint64_t	        dha_stack[NR_CPUS];
            uint64_t	        dha_stack_ptr[NR_CPUS];
    } __attribute__((packed)) dump_header_asm_t;

That patch tries to guess if it's a SLES 9 or a SLES 10 header
at runtime.

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

---
 lkcd_v8.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

Index: b/lkcd_v8.c
===================================================================
--- a/lkcd_v8.c
+++ b/lkcd_v8.c
@@ -130,6 +130,17 @@ lkcd_dump_init_v8_arch(dump_header_t *dh
 		goto err;
 	}

+#if IA64
+	/* SLES9 on IA64? */
+	if ( *((uint64_t *)(hdr_buf + hdr_size - sizeof(uint64_t))) <= NR_CPUS) {
+		uint64_t kernel_addr;
+		kernel_addr = ((dump_header_asm_t *)hdr_buf)->dha_pt_regs;
+		memmove(hdr_buf + offsetof(dump_header_asm_t, dha_pt_regs),
+				hdr_buf + offsetof(dump_header_asm_t, dha_regs),
+				hdr_size - offsetof(dump_header_asm_t, dha_regs));
+		*((uint64_t *)(hdr_buf + hdr_size - sizeof(uint64_t))) = kernel_addr;
+	}
+#endif

 	/*
          * Though we have KL_NR_CPUS is 128, the header size is different