Blame s390dbf.c

Packit Service 501009
/*
Packit Service 501009
 *    s390 debug feature command for crash
Packit Service 501009
 *
Packit Service 501009
 *    Copyright (C) IBM Corp. 2006
Packit Service 501009
 *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
Packit Service 501009
 *
Packit Service 501009
 * This program is free software; you can redistribute it and/or modify
Packit Service 501009
 * it under the terms of the GNU General Public License as published by
Packit Service 501009
 * the Free Software Foundation; either version 2 of the License, or
Packit Service 501009
 * (at your option) any later version.
Packit Service 501009
 *
Packit Service 501009
 * This program is distributed in the hope that it will be useful,
Packit Service 501009
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 501009
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 501009
 * GNU General Public License for more details.
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
#if defined(S390) || defined(S390X)
Packit Service 501009
Packit Service 501009
#include "defs.h"
Packit Service 501009
#include <iconv.h>
Packit Service 501009
#include <ctype.h>
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * Compat layer to integrate lcrash commands into crash
Packit Service 501009
 * Maps lcrash API to crash functions
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
#define KL_NBPW sizeof(long)
Packit Service 501009
#define KL_ERRORFP stderr
Packit Service 501009
#define MAX_ARGS 128
Packit Service 501009
#define MAX_CMDLINE 256
Packit Service 501009
Packit Service 501009
#define C_FALSE         0x00000001   /* Command takes no arguments */
Packit Service 501009
#define C_TRUE          0x00000002   /* Command requires arguments */
Packit Service 501009
#define C_ALL           0x00000004   /* All elements */
Packit Service 501009
#define C_PERM          0x00000008   /* Allocate perminant blocks */
Packit Service 501009
#define C_TEMP          0x00000000   /* For completeness */
Packit Service 501009
#define C_FULL          0x00000010   /* Full output */
Packit Service 501009
#define C_LIST          0x00000020   /* List items */
Packit Service 501009
#define C_NEXT          0x00000040   /* Follow links */
Packit Service 501009
#define C_WRITE         0x00000080   /* Write output to file */
Packit Service 501009
#define C_NO_OPCHECK    0x00000100   /* Don't reject bad cmd line options */
Packit Service 501009
#define C_ITER          0x00000200   /* set iteration threshold */
Packit Service 501009
Packit Service 501009
#define C_LFLG_SHFT 12
Packit Service 501009
Packit Service 501009
#define KL_ARCH_S390 0
Packit Service 501009
#define KL_ARCH_S390X 1
Packit Service 501009
#ifdef __s390x__
Packit Service 501009
#define KL_ARCH KL_ARCH_S390X
Packit Service 501009
#define FMTPTR "l"
Packit Service 501009
#define KL_PTRSZ 8
Packit Service 501009
#else
Packit Service 501009
#define KL_ARCH KL_ARCH_S390
Packit Service 501009
#define FMTPTR "ll"
Packit Service 501009
#define KL_PTRSZ 4
Packit Service 501009
#endif
Packit Service 501009
Packit Service 501009
/* Start TOD time of kernel in usecs for relative time stamps */
Packit Service 501009
static uint64_t tod_clock_base_us;
Packit Service 501009
Packit Service 501009
typedef unsigned long uaddr_t;
Packit Service 501009
typedef unsigned long kaddr_t;
Packit Service 501009
Packit Service 501009
typedef struct _syment {
Packit Service 501009
	char *s_name;
Packit Service 501009
	kaddr_t s_addr;
Packit Service 501009
} syment_t;
Packit Service 501009
Packit Service 501009
typedef struct option_s {
Packit Service 501009
	struct option_s	*op_next;
Packit Service 501009
	char		op_char;
Packit Service 501009
	char		*op_arg;
Packit Service 501009
} option_t;
Packit Service 501009
Packit Service 501009
typedef struct command_s {
Packit Service 501009
	int		flags;
Packit Service 501009
	char		cmdstr[MAX_CMDLINE];
Packit Service 501009
	char		*command;
Packit Service 501009
	char		*cmdline;
Packit Service 501009
	option_t	*options;
Packit Service 501009
	int		nargs;
Packit Service 501009
	char		*args[MAX_ARGS];
Packit Service 501009
	char		*pipe_cmd;
Packit Service 501009
	FILE		*ofp;
Packit Service 501009
	FILE		*efp;
Packit Service 501009
} command_t;
Packit Service 501009
Packit Service 501009
static inline syment_t* kl_lkup_symaddr(kaddr_t addr)
Packit Service 501009
{
Packit Service 501009
	static syment_t sym;
Packit Service 501009
	struct syment *crash_sym;
Packit Service 501009
Packit Service 501009
	crash_sym = value_search(addr, &sym.s_addr);
Packit Service 501009
	if (!crash_sym)
Packit Service 501009
		return NULL;
Packit Service 501009
	sym.s_name = crash_sym->name;
Packit Service 501009
	return &sy;;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline syment_t* kl_lkup_symname(char* name)
Packit Service 501009
{
Packit Service 501009
	static syment_t sym;
Packit Service 501009
	sym.s_addr = symbol_value(name);
Packit Service 501009
	sym.s_name = NULL;
Packit Service 501009
	if(!sym.s_addr)
Packit Service 501009
		return NULL;
Packit Service 501009
	else
Packit Service 501009
		return &sy;;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline void GET_BLOCK(kaddr_t addr, int size, void* ptr)
Packit Service 501009
{
Packit Service 501009
	readmem(addr, KVADDR,ptr,size,"GET_BLOCK",FAULT_ON_ERROR);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline kaddr_t KL_VREAD_PTR(kaddr_t addr)
Packit Service 501009
{
Packit Service 501009
	unsigned long ptr;
Packit Service 501009
	readmem(addr, KVADDR,&ptr,sizeof(ptr),"GET_BLOCK",FAULT_ON_ERROR);
Packit Service 501009
	return (kaddr_t)ptr;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline uint32_t KL_GET_UINT32(void* ptr)
Packit Service 501009
{
Packit Service 501009
	return *((uint32_t*)ptr);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline uint64_t KL_GET_UINT64(void* ptr)
Packit Service 501009
{
Packit Service 501009
	return *((uint64_t*)ptr);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline kaddr_t KL_GET_PTR(void* ptr)
Packit Service 501009
{
Packit Service 501009
	return *((kaddr_t*)ptr);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline void* K_PTR(void* addr, char* struct_name, char* member_name)
Packit Service 501009
{
Packit Service 501009
	return addr+MEMBER_OFFSET(struct_name,member_name);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline unsigned long KL_ULONG(void* ptr, char* struct_name, char*
Packit Service 501009
				     member_name)
Packit Service 501009
{
Packit Service 501009
	return ULONG(ptr+MEMBER_OFFSET(struct_name,member_name));
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline uint32_t KL_VREAD_UINT32(kaddr_t addr)
Packit Service 501009
{
Packit Service 501009
	uint32_t rc;
Packit Service 501009
	readmem(addr, KVADDR,&rc,sizeof(rc),"KL_VREAD_UINT32",FAULT_ON_ERROR);
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline uint32_t KL_INT(void* ptr, char* struct_name, char* member_name)
Packit Service 501009
{
Packit Service 501009
	return UINT(ptr+MEMBER_OFFSET(struct_name,member_name));
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline int set_cmd_flags(command_t *cmd, int flags, char *extraops)
Packit Service 501009
{
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/* Time of day clock value for 1970/01/01 */
Packit Service 501009
#define TOD_UNIX_EPOCH (0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096))
Packit Service 501009
/* Time of day clock value for 1970/01/01 in usecs */
Packit Service 501009
#define TOD_UNIX_EPOCH_US (TOD_UNIX_EPOCH >> 12)
Packit Service 501009
Packit Service 501009
static inline void kl_s390tod_to_timeval(uint64_t todval, struct timeval *xtime)
Packit Service 501009
{
Packit Service 501009
	uint64_t todval_us;
Packit Service 501009
Packit Service 501009
	/* Convert TOD to usec (51th bit of TOD is us) */
Packit Service 501009
	todval_us = todval >> 12;
Packit Service 501009
	/* Add base if we have relative time stamps */
Packit Service 501009
	todval_us += tod_clock_base_us;
Packit Service 501009
	/* Subtract EPOCH that we get time in usec since 1970 */
Packit Service 501009
	todval_us -= TOD_UNIX_EPOCH_US;
Packit Service 501009
	xtime->tv_sec  = todval_us / 1000000;
Packit Service 501009
	xtime->tv_usec = todval_us % 1000000;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline int kl_struct_len(char* struct_name)
Packit Service 501009
{
Packit Service 501009
	return STRUCT_SIZE(struct_name);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static inline kaddr_t kl_funcaddr(kaddr_t addr)
Packit Service 501009
{
Packit Service 501009
	struct syment *crash_sym;
Packit Service 501009
Packit Service 501009
	crash_sym = value_search(addr, &addr);
Packit Service 501009
	if (!crash_sym)
Packit Service 501009
		return -1;
Packit Service 501009
	else
Packit Service 501009
		return crash_sym->value;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
#define CMD_USAGE(cmd, s) \
Packit Service 501009
	fprintf(cmd->ofp, "Usage: %s %s\n", cmd->command, s); \
Packit Service 501009
	fprintf(cmd->ofp, "Enter \"help %s\" for details.\n",cmd->command);
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * s390 debug feature implementation
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
#ifdef DBF_DYNAMIC_VIEWS	/* views defined in shared libs */
Packit Service 501009
#include <dlfcn.h>
Packit Service 501009
#endif
Packit Service 501009
Packit Service 501009
/* Local flags
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
#define LOAD_FLAG (1 << C_LFLG_SHFT)
Packit Service 501009
#define VIEWS_FLAG (2 << C_LFLG_SHFT)
Packit Service 501009
#define SAVE_DBF_FLAG (4 << C_LFLG_SHFT)
Packit Service 501009
Packit Service 501009
#ifndef MIN
Packit Service 501009
#define MIN(a,b) (((a)<(b))?(a):(b))
Packit Service 501009
#endif
Packit Service 501009
Packit Service 501009
/* Stuff which has to match with include/asm-s390/debug.h */
Packit Service 501009
Packit Service 501009
#define DBF_VERSION_V1 1
Packit Service 501009
#define DBF_VERSION_V2 2
Packit Service 501009
#define PAGE_SIZE 4096
Packit Service 501009
#define DEBUG_MAX_VIEWS	    10 /* max number of views in proc fs */
Packit Service 501009
#define DEBUG_MAX_PROCF_LEN	64 /* max length for a proc file name */
Packit Service 501009
#define DEBUG_SPRINTF_MAX_ARGS 10
Packit Service 501009
Packit Service 501009
/* define debug-structures for lcrash */
Packit Service 501009
#define DEBUG_DATA(entry) (char*)(entry + 1)
Packit Service 501009
Packit Service 501009
typedef struct debug_view_s debug_view_t;
Packit Service 501009
Packit Service 501009
/* struct to hold contents of struct __debug_entry from dump
Packit Service 501009
 */
Packit Service 501009
typedef struct debug_entry_s{
Packit Service 501009
	union {
Packit Service 501009
		struct {
Packit Service 501009
			unsigned long long clock:52;
Packit Service 501009
			unsigned long long exception:1;
Packit Service 501009
			unsigned long long level:3;
Packit Service 501009
			unsigned long long cpuid:8;
Packit Service 501009
		} fields;
Packit Service 501009
Packit Service 501009
		unsigned long long stck;
Packit Service 501009
	} id;
Packit Service 501009
	kaddr_t caller; /* changed from void* to kaddr_t */
Packit Service 501009
} __attribute__((packed)) debug_entry_t;
Packit Service 501009
/* typedef struct __debug_entry debug_entry_t; */
Packit Service 501009
Packit Service 501009
Packit Service 501009
static unsigned int dbf_version;
Packit Service 501009
Packit Service 501009
/* struct is used to manage contents of structs debug_info from dump
Packit Service 501009
 * in lcrash
Packit Service 501009
 */
Packit Service 501009
typedef struct debug_info_s {
Packit Service 501009
	struct debug_info_s *next;
Packit Service 501009
	struct debug_info_s *prev;
Packit Service 501009
	kaddr_t next_dbi;   /* store next ptr of struct in dump */
Packit Service 501009
	kaddr_t prev_dbi;   /* store prev ptr of struct in dump */
Packit Service 501009
	int level;
Packit Service 501009
	int nr_areas;
Packit Service 501009
	int page_order;
Packit Service 501009
	int buf_size;
Packit Service 501009
	int entry_size;
Packit Service 501009
	void **areas; /* contents of debug areas from dump */
Packit Service 501009
	int active_area;
Packit Service 501009
	int *active_entry; /* change to uint32_t ? */
Packit Service 501009
	debug_view_t *views[DEBUG_MAX_VIEWS];
Packit Service 501009
	char name[DEBUG_MAX_PROCF_LEN];
Packit Service 501009
	kaddr_t addr;
Packit Service 501009
	int pages_per_area_v2;
Packit Service 501009
	void ***areas_v2;
Packit Service 501009
} debug_info_t;
Packit Service 501009
Packit Service 501009
Packit Service 501009
/* functions to generate dbf output
Packit Service 501009
 */
Packit Service 501009
typedef int (debug_header_proc_t) (debug_info_t* id, debug_view_t* view,
Packit Service 501009
				   int area, debug_entry_t* entry,
Packit Service 501009
				   char* out_buf);
Packit Service 501009
typedef int (debug_format_proc_t) (debug_info_t* id, debug_view_t* view,
Packit Service 501009
				   char* out_buf, const char* in_buf);
Packit Service 501009
typedef int (debug_prolog_proc_t) (debug_info_t* id, debug_view_t* view,
Packit Service 501009
				   char* out_buf);
Packit Service 501009
Packit Service 501009
struct debug_view_s {
Packit Service 501009
	char name[DEBUG_MAX_PROCF_LEN];
Packit Service 501009
	debug_prolog_proc_t* prolog_proc;
Packit Service 501009
	debug_header_proc_t* header_proc;
Packit Service 501009
	debug_format_proc_t* format_proc;
Packit Service 501009
	void*		private_data;
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
#define LCRASH_DB_VIEWS 1000
Packit Service 501009
Packit Service 501009
static debug_info_t *debug_area_first = NULL;
Packit Service 501009
static debug_info_t *debug_area_last  = NULL;
Packit Service 501009
static debug_view_t *debug_views[LCRASH_DB_VIEWS];
Packit Service 501009
static int initialized = 0;
Packit Service 501009
static iconv_t ebcdic_ascii_conv = 0;
Packit Service 501009
Packit Service 501009
void s390dbf_usage(command_t * cmd);
Packit Service 501009
static int add_lcrash_debug_view(debug_view_t *);
Packit Service 501009
static int dbe_size = 0;
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
EBCASC(char *inout, size_t len)
Packit Service 501009
{
Packit Service 501009
	iconv(ebcdic_ascii_conv, &inout, &len, &inout, &len;;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints header for debug entry
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
dflt_header_fn(debug_info_t * id, debug_view_t *view,
Packit Service 501009
	       int area, debug_entry_t * entry, char *out_buf)
Packit Service 501009
{
Packit Service 501009
	struct timeval time_val;
Packit Service 501009
	unsigned long long time;
Packit Service 501009
	char *except_str;
Packit Service 501009
	kaddr_t caller;
Packit Service 501009
	int rc = 0;
Packit Service 501009
	char *caller_name;
Packit Service 501009
	int offset;
Packit Service 501009
	char caller_buf[30];
Packit Service 501009
	unsigned int level;
Packit Service 501009
	syment_t *caller_sym;
Packit Service 501009
	debug_entry_t lentry; /* store byte swapped values of entry */
Packit Service 501009
Packit Service 501009
	lentry.id.stck = KL_GET_UINT64(&entry->id);
Packit Service 501009
	lentry.caller = KL_GET_PTR(&entry->caller);
Packit Service 501009
	level = lentry.id.fields.level;
Packit Service 501009
	time = lentry.id.stck;
Packit Service 501009
Packit Service 501009
	kl_s390tod_to_timeval(time, &time_val);
Packit Service 501009
Packit Service 501009
	if (lentry.id.fields.exception)
Packit Service 501009
		except_str = "*";
Packit Service 501009
	else
Packit Service 501009
		except_str = "-";
Packit Service 501009
	caller = lentry.caller;
Packit Service 501009
	if(KL_ARCH == KL_ARCH_S390){
Packit Service 501009
		caller &= 0x7fffffff;
Packit Service 501009
	}
Packit Service 501009
	caller_sym = kl_lkup_symaddr(caller);
Packit Service 501009
	if(caller_sym){
Packit Service 501009
		caller_name = caller_sym->s_name;
Packit Service 501009
		offset = caller - kl_funcaddr(caller);
Packit Service 501009
	}
Packit Service 501009
	else {
Packit Service 501009
		sprintf(caller_buf, "%llx", (unsigned long long)caller);
Packit Service 501009
		caller_name = caller_buf;
Packit Service 501009
		offset = 0;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if(KL_ARCH == KL_ARCH_S390X){
Packit Service 501009
		rc += sprintf(out_buf, 
Packit Service 501009
			      "%02i %011lu:%06lu %1u %1s %02i <%20s+%04i>  ",
Packit Service 501009
			      area, time_val.tv_sec, time_val.tv_usec, level,
Packit Service 501009
			      except_str, entry->id.fields.cpuid, caller_name,
Packit Service 501009
			      offset);
Packit Service 501009
	} else {
Packit Service 501009
		rc += sprintf(out_buf,
Packit Service 501009
			      "%02i %011lu:%06lu %1u %1s %02i <%-20s+%04i>  ",
Packit Service 501009
			      area, time_val.tv_sec, time_val.tv_usec, level,
Packit Service 501009
			      except_str, lentry.id.fields.cpuid, caller_name,
Packit Service 501009
			      offset);
Packit Service 501009
	}
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints debug header in raw format
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
raw_header_fn(debug_info_t * id, debug_view_t *view,
Packit Service 501009
	      int area, debug_entry_t * entry, char *out_buf)
Packit Service 501009
{
Packit Service 501009
	int rc;
Packit Service 501009
Packit Service 501009
	rc = sizeof(debug_entry_t);
Packit Service 501009
	if (out_buf == NULL)
Packit Service 501009
		goto out;
Packit Service 501009
	memcpy(out_buf,entry,sizeof(debug_entry_t));
Packit Service 501009
      out:
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints debug data in raw format
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
raw_format_fn(debug_info_t * id, debug_view_t *view,
Packit Service 501009
	      char *out_buf, const char *in_buf)
Packit Service 501009
{
Packit Service 501009
	int rc;
Packit Service 501009
Packit Service 501009
	rc = id->buf_size;
Packit Service 501009
	if (out_buf == NULL || in_buf == NULL)
Packit Service 501009
		goto out;
Packit Service 501009
	memcpy(out_buf, in_buf, id->buf_size);
Packit Service 501009
      out:
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints debug data in hex/ascii format
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
hex_ascii_format_fn(debug_info_t * id, debug_view_t *view,
Packit Service 501009
		    char *out_buf, const char *in_buf)
Packit Service 501009
{
Packit Service 501009
	int i, rc = 0;
Packit Service 501009
Packit Service 501009
	if (out_buf == NULL || in_buf == NULL) {
Packit Service 501009
		rc = id->buf_size * 4 + 3;
Packit Service 501009
		goto out;
Packit Service 501009
	}
Packit Service 501009
	for (i = 0; i < id->buf_size; i++) {
Packit Service 501009
		rc += sprintf(out_buf + rc, "%02x ",
Packit Service 501009
			      ((unsigned char *) in_buf)[i]);
Packit Service 501009
	}
Packit Service 501009
	rc += sprintf(out_buf + rc, "| ");
Packit Service 501009
	for (i = 0; i < id->buf_size; i++) {
Packit Service 501009
		unsigned char c = in_buf[i];
Packit Service 501009
		if (isascii(c) && isprint(c))
Packit Service 501009
			rc += sprintf(out_buf + rc, "%c", c);
Packit Service 501009
		else
Packit Service 501009
			rc += sprintf(out_buf + rc, ".");
Packit Service 501009
	}
Packit Service 501009
	rc += sprintf(out_buf + rc, "\n");
Packit Service 501009
      out:
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints debug data in sprintf format
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
sprintf_format_fn(debug_info_t * id, debug_view_t *view,
Packit Service 501009
		  char *out_buf, const char *in_buf)
Packit Service 501009
{
Packit Service 501009
#define _BUFSIZE 1024
Packit Service 501009
	char buf[_BUFSIZE];
Packit Service 501009
	int i, k, rc = 0, num_longs = 0, num_strings = 0;
Packit Service 501009
	int num_used_args ATTRIBUTE_UNUSED;
Packit Service 501009
	/* use kaddr_t to store long values of 32bit and 64bit archs here */
Packit Service 501009
	kaddr_t inbuf_cpy[DEBUG_SPRINTF_MAX_ARGS];
Packit Service 501009
	/* store ptrs to strings to be deallocated at end of this function */
Packit Service 501009
	uaddr_t to_dealloc[DEBUG_SPRINTF_MAX_ARGS];
Packit Service 501009
	kaddr_t addr;
Packit Service 501009
Packit Service 501009
	memset(buf, 0, sizeof(buf));
Packit Service 501009
	memset(inbuf_cpy, 0, sizeof(inbuf_cpy));
Packit Service 501009
	memset(to_dealloc, 0, sizeof(to_dealloc));
Packit Service 501009
Packit Service 501009
	if (out_buf == NULL || in_buf == NULL) {
Packit Service 501009
	      rc = id->buf_size * 4 + 3;
Packit Service 501009
	      goto out;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	/* get the format string into buf */
Packit Service 501009
	addr = KL_GET_PTR((void*)in_buf);
Packit Service 501009
	GET_BLOCK(addr, _BUFSIZE, buf);
Packit Service 501009
Packit Service 501009
	k = 0;
Packit Service 501009
	for (i = 0; buf[i] && (buf[i] != '\n'); i++) {
Packit Service 501009
		if (buf[i] != '%')
Packit Service 501009
			continue;
Packit Service 501009
		if (k == DEBUG_SPRINTF_MAX_ARGS) {
Packit Service 501009
			fprintf(KL_ERRORFP,
Packit Service 501009
				"\nToo much parameters in sprinf view (%i)\n"
Packit Service 501009
				,k + 1);
Packit Service 501009
			fprintf(KL_ERRORFP, "Format String: %s)\n", buf);
Packit Service 501009
			break;
Packit Service 501009
		}
Packit Service 501009
		/* for sprintf we have only unsigned long values ... */
Packit Service 501009
		if (buf[i+1] != 's'){
Packit Service 501009
			/* we use KL_GET_PTR here to read ulong value */
Packit Service 501009
			addr = KL_GET_PTR((void*) in_buf + ((k + 1)* KL_NBPW));
Packit Service 501009
			inbuf_cpy[k] = addr;
Packit Service 501009
		} else { /* ... or ptrs to strings in debug areas */
Packit Service 501009
			inbuf_cpy[k] = (uaddr_t) malloc(_BUFSIZE);
Packit Service 501009
			to_dealloc[num_strings++] = inbuf_cpy[k];
Packit Service 501009
			addr = KL_GET_PTR((void*) in_buf + ((k + 1)* KL_NBPW));
Packit Service 501009
			GET_BLOCK(addr, _BUFSIZE,
Packit Service 501009
				  (void*)(uaddr_t)(inbuf_cpy[k]));
Packit Service 501009
		}
Packit Service 501009
		k++;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	/* count of longs fit into one entry */
Packit Service 501009
	num_longs = id->buf_size /  KL_NBPW; /* sizeof(long); */
Packit Service 501009
	if(num_longs < 1)	  /* bufsize of entry too small */
Packit Service 501009
		goto out;
Packit Service 501009
	if(num_longs == 1) {	  /* no args, just print the format string */
Packit Service 501009
		rc = sprintf(out_buf + rc, "%s", buf);
Packit Service 501009
		goto out;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	/* number of arguments used for sprintf (without the format string) */
Packit Service 501009
	num_used_args = MIN(DEBUG_SPRINTF_MAX_ARGS, (num_longs - 1));
Packit Service 501009
Packit Service 501009
	rc = sprintf(out_buf + rc, buf, (uaddr_t)(inbuf_cpy[0]),
Packit Service 501009
		     (uaddr_t)(inbuf_cpy[1]), (uaddr_t)(inbuf_cpy[2]),
Packit Service 501009
		     (uaddr_t)(inbuf_cpy[3]), (uaddr_t)(inbuf_cpy[4]),
Packit Service 501009
		     (uaddr_t)(inbuf_cpy[5]), (uaddr_t)(inbuf_cpy[6]),
Packit Service 501009
		     (uaddr_t)(inbuf_cpy[7]), (uaddr_t)(inbuf_cpy[8]),
Packit Service 501009
		     (uaddr_t)(inbuf_cpy[9]));
Packit Service 501009
 out:
Packit Service 501009
	while (num_strings--){
Packit Service 501009
		free((char*)(to_dealloc[num_strings]));
Packit Service 501009
	}
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
/***********************************
Packit Service 501009
 * functions for debug-views
Packit Service 501009
 ***********************************/
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints out actual debug level
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
prolog_level_fn(debug_info_t * id,
Packit Service 501009
		debug_view_t *view, char *out_buf)
Packit Service 501009
{
Packit Service 501009
	int rc = 0;
Packit Service 501009
Packit Service 501009
	if (out_buf == NULL) {
Packit Service 501009
		rc = 2;
Packit Service 501009
		goto out;
Packit Service 501009
	}
Packit Service 501009
	rc = sprintf(out_buf, "%i\n", id->level);
Packit Service 501009
      out:
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints out actual pages_per_area
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
prolog_pages_fn(debug_info_t * id,
Packit Service 501009
		debug_view_t *view, char *out_buf)
Packit Service 501009
{
Packit Service 501009
	int rc = 0;
Packit Service 501009
Packit Service 501009
	if (out_buf == NULL) {
Packit Service 501009
		rc = 2;
Packit Service 501009
		goto out;
Packit Service 501009
	}
Packit Service 501009
	rc = sprintf(out_buf, "%i\n", id->pages_per_area_v2);
Packit Service 501009
      out:
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints out prolog
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
prolog_fn(debug_info_t * id,
Packit Service 501009
	  debug_view_t *view, char *out_buf)
Packit Service 501009
{
Packit Service 501009
	int rc = 0;
Packit Service 501009
Packit Service 501009
	rc = sprintf(out_buf, "AREA TIME LEVEL EXCEPTION CP CALLING FUNCTION"
Packit Service 501009
		     "   + OFFSET  DATA\n==================================="
Packit Service 501009
		     "=======================================\n");
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints debug data in hex format
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
hex_format_fn(debug_info_t * id, debug_view_t *view,
Packit Service 501009
	      char *out_buf, const char *in_buf)
Packit Service 501009
{
Packit Service 501009
	int i, rc = 0;
Packit Service 501009
Packit Service 501009
	for (i = 0; i < id->buf_size; i++) {
Packit Service 501009
		rc += sprintf(out_buf + rc, "%02x ",
Packit Service 501009
			      ((unsigned char *) in_buf)[i]);
Packit Service 501009
	}
Packit Service 501009
	rc += sprintf(out_buf + rc, "\n");
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints debug data in ascii format
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
ascii_format_fn(debug_info_t * id, debug_view_t *view,
Packit Service 501009
		char *out_buf, const char *in_buf)
Packit Service 501009
{
Packit Service 501009
	int i, rc = 0;
Packit Service 501009
Packit Service 501009
	if (out_buf == NULL || in_buf == NULL) {
Packit Service 501009
		rc = id->buf_size + 1;
Packit Service 501009
		goto out;
Packit Service 501009
	}
Packit Service 501009
	for (i = 0; i < id->buf_size; i++) {
Packit Service 501009
		unsigned char c = in_buf[i];
Packit Service 501009
		if (!isprint(c))
Packit Service 501009
			rc += sprintf(out_buf + rc, ".");
Packit Service 501009
		else
Packit Service 501009
			rc += sprintf(out_buf + rc, "%c", c);
Packit Service 501009
	}
Packit Service 501009
	rc += sprintf(out_buf + rc, "\n");
Packit Service 501009
      out:
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * prints debug data in ebcdic format
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
ebcdic_format_fn(debug_info_t * id, debug_view_t *view,
Packit Service 501009
		 char *out_buf, const char *in_buf)
Packit Service 501009
{
Packit Service 501009
	int i, rc = 0;
Packit Service 501009
Packit Service 501009
	if (out_buf == NULL || in_buf == NULL) {
Packit Service 501009
		rc = id->buf_size + 1;
Packit Service 501009
		goto out;
Packit Service 501009
	}
Packit Service 501009
	for (i = 0; i < id->buf_size; i++) {
Packit Service 501009
		char c = in_buf[i];
Packit Service 501009
		EBCASC(&c, 1);
Packit Service 501009
		if (!isprint(c))
Packit Service 501009
			rc += sprintf(out_buf + rc, ".");
Packit Service 501009
		else
Packit Service 501009
			rc += sprintf(out_buf + rc, "%c", c);
Packit Service 501009
	}
Packit Service 501009
	rc += sprintf(out_buf + rc, "\n");
Packit Service 501009
      out:
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
debug_view_t ascii_view = {
Packit Service 501009
	"ascii",
Packit Service 501009
	&prolog_fn,
Packit Service 501009
	&dflt_header_fn,
Packit Service 501009
	&ascii_format_fn,
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
debug_view_t ebcdic_view = {
Packit Service 501009
	"ebcdic",
Packit Service 501009
	&prolog_fn,
Packit Service 501009
	&dflt_header_fn,
Packit Service 501009
	&ebcdic_format_fn,
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
debug_view_t hex_view = {
Packit Service 501009
	"hex",
Packit Service 501009
	&prolog_fn,
Packit Service 501009
	&dflt_header_fn,
Packit Service 501009
	&hex_format_fn,
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
debug_view_t level_view = {
Packit Service 501009
	"level",
Packit Service 501009
	&prolog_level_fn,
Packit Service 501009
	NULL,
Packit Service 501009
	NULL,
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
debug_view_t pages_view = {
Packit Service 501009
	"pages",
Packit Service 501009
	&prolog_pages_fn,
Packit Service 501009
	NULL,
Packit Service 501009
	NULL,
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
debug_view_t raw_view = {
Packit Service 501009
	"raw",
Packit Service 501009
	NULL,
Packit Service 501009
	&raw_header_fn,
Packit Service 501009
	&raw_format_fn,
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
debug_view_t hex_ascii_view = {
Packit Service 501009
	"hex_ascii",
Packit Service 501009
	&prolog_fn,
Packit Service 501009
	&dflt_header_fn,
Packit Service 501009
	&hex_ascii_format_fn,
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
debug_view_t sprintf_view = {
Packit Service 501009
	"sprintf",
Packit Service 501009
	&prolog_fn,
Packit Service 501009
	&dflt_header_fn,
Packit Service 501009
	&sprintf_format_fn,
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
Packit Service 501009
static debug_entry_t *
Packit Service 501009
debug_find_oldest_entry(debug_entry_t *entries, int num, int entry_size)
Packit Service 501009
{
Packit Service 501009
	debug_entry_t *result, *current;
Packit Service 501009
	int i;
Packit Service 501009
	uint64_t clock1, clock2;
Packit Service 501009
Packit Service 501009
	result = entries;
Packit Service 501009
	current = entries;
Packit Service 501009
	for (i=0; i < num; i++) {
Packit Service 501009
		if (current->id.stck == 0)
Packit Service 501009
			break;
Packit Service 501009
		clock1 = current->id.fields.clock;
Packit Service 501009
		clock2 = result->id.fields.clock;
Packit Service 501009
		clock1 = KL_GET_UINT64(&clock1);
Packit Service 501009
		clock2 = KL_GET_UINT64(&clock2);
Packit Service 501009
		if (clock1 < clock2)
Packit Service 501009
			result = current;
Packit Service 501009
		current = (debug_entry_t *) ((char *) current + entry_size);
Packit Service 501009
	}
Packit Service 501009
	return result;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * debug_format_output:
Packit Service 501009
 * - calls prolog, header and format functions of view to format output
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
debug_format_output_v1(debug_info_t * debug_area, debug_view_t *view, 
Packit Service 501009
			FILE * ofp)
Packit Service 501009
{
Packit Service 501009
	int i, j, len;
Packit Service 501009
	int nr_of_entries;
Packit Service 501009
	debug_entry_t *act_entry, *last_entry;
Packit Service 501009
	char *act_entry_data;
Packit Service 501009
	char buf[2048];
Packit Service 501009
	size_t items ATTRIBUTE_UNUSED;
Packit Service 501009
Packit Service 501009
	/* print prolog */
Packit Service 501009
	if (view->prolog_proc) {
Packit Service 501009
		len = view->prolog_proc(debug_area, view, buf);
Packit Service 501009
		items = fwrite(buf,len, 1, ofp);
Packit Service 501009
		memset(buf, 0, 2048);
Packit Service 501009
	}
Packit Service 501009
	/* print debug records */
Packit Service 501009
	if (!(view->format_proc) && !(view->header_proc))
Packit Service 501009
		goto out;
Packit Service 501009
	if(debug_area->entry_size <= 0){
Packit Service 501009
		fprintf(ofp, "Invalid entry_size: %i\n",debug_area->entry_size);
Packit Service 501009
		goto out;
Packit Service 501009
	}
Packit Service 501009
	nr_of_entries = (PAGE_SIZE << debug_area->page_order) / debug_area->entry_size;
Packit Service 501009
	for (i = 0; i < debug_area->nr_areas; i++) {
Packit Service 501009
		act_entry = debug_find_oldest_entry(debug_area->areas[i],
Packit Service 501009
						    nr_of_entries,
Packit Service 501009
						    debug_area->entry_size);
Packit Service 501009
		last_entry = (debug_entry_t *) ((char *) debug_area->areas[i] +
Packit Service 501009
			     (PAGE_SIZE << debug_area->page_order) -
Packit Service 501009
			     debug_area->entry_size);
Packit Service 501009
		for (j = 0; j < nr_of_entries; j++) {
Packit Service 501009
			act_entry_data = (char*)act_entry + dbe_size;
Packit Service 501009
			if (act_entry->id.stck == 0)
Packit Service 501009
				break;	/* empty entry */
Packit Service 501009
			if (view->header_proc) {
Packit Service 501009
				len = view->header_proc(debug_area, view, i,
Packit Service 501009
						  act_entry, buf);
Packit Service 501009
				items = fwrite(buf,len, 1, ofp);
Packit Service 501009
				memset(buf, 0, 2048);
Packit Service 501009
			}
Packit Service 501009
			if (view->format_proc) {
Packit Service 501009
				len = view->format_proc(debug_area, view,
Packit Service 501009
						  buf, act_entry_data);
Packit Service 501009
				items = fwrite(buf,len, 1, ofp);
Packit Service 501009
				memset(buf, 0, 2048); 
Packit Service 501009
			}
Packit Service 501009
			act_entry =
Packit Service 501009
			    (debug_entry_t *) (((char *) act_entry) +
Packit Service 501009
					       debug_area->entry_size);
Packit Service 501009
			if (act_entry > last_entry)
Packit Service 501009
				act_entry = debug_area->areas[i];
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
      out:
Packit Service 501009
	return 1;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * debug_format_output_v2:
Packit Service 501009
 * - calls prolog, header and format functions of view to format output
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
debug_format_output_v2(debug_info_t * debug_area,
Packit Service 501009
		    debug_view_t *view, FILE * ofp)
Packit Service 501009
{
Packit Service 501009
	int i, j, k, len;
Packit Service 501009
	debug_entry_t *act_entry;
Packit Service 501009
	char *act_entry_data;
Packit Service 501009
	char buf[2048];
Packit Service 501009
	size_t items ATTRIBUTE_UNUSED;
Packit Service 501009
Packit Service 501009
	/* print prolog */
Packit Service 501009
	if (view->prolog_proc) {
Packit Service 501009
		len = view->prolog_proc(debug_area, view, buf);
Packit Service 501009
		items = fwrite(buf,len, 1, ofp);
Packit Service 501009
		memset(buf, 0, 2048);
Packit Service 501009
	}
Packit Service 501009
	/* print debug records */
Packit Service 501009
	if (!(view->format_proc) && !(view->header_proc))
Packit Service 501009
		goto out;
Packit Service 501009
	if(debug_area->entry_size <= 0){
Packit Service 501009
		fprintf(ofp, "Invalid entry_size: %i\n",debug_area->entry_size);
Packit Service 501009
		goto out;
Packit Service 501009
	}
Packit Service 501009
	for (i = 0; i < debug_area->nr_areas; i++) {
Packit Service 501009
		int nr_entries_per_page = PAGE_SIZE/debug_area->entry_size;
Packit Service 501009
		for (j = 0; j < debug_area->pages_per_area_v2; j++) {
Packit Service 501009
			act_entry = debug_area->areas_v2[i][j];
Packit Service 501009
			for (k = 0; k < nr_entries_per_page; k++) {
Packit Service 501009
				act_entry_data = (char*)act_entry + dbe_size;
Packit Service 501009
				if (act_entry->id.stck == 0)
Packit Service 501009
					break;	/* empty entry */
Packit Service 501009
				if (view->header_proc) {
Packit Service 501009
					len = view->header_proc(debug_area, 
Packit Service 501009
						view, i, act_entry, buf);
Packit Service 501009
					items = fwrite(buf,len, 1, ofp);
Packit Service 501009
					memset(buf, 0, 2048);
Packit Service 501009
				}
Packit Service 501009
				if (view->format_proc) {
Packit Service 501009
					len = view->format_proc(debug_area, 
Packit Service 501009
						view, buf, act_entry_data);
Packit Service 501009
					items = fwrite(buf,len, 1, ofp);
Packit Service 501009
					memset(buf, 0, 2048); 
Packit Service 501009
				}
Packit Service 501009
				act_entry = (debug_entry_t *) (((char *) 
Packit Service 501009
					act_entry) + debug_area->entry_size);
Packit Service 501009
			}
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
out:
Packit Service 501009
	return 1;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static debug_info_t *
Packit Service 501009
find_debug_area(const char *area_name)
Packit Service 501009
{
Packit Service 501009
	debug_info_t* act_debug_info = debug_area_first;
Packit Service 501009
	while(act_debug_info != NULL){
Packit Service 501009
		if (strcmp(act_debug_info->name, area_name) == 0)
Packit Service 501009
				return act_debug_info;
Packit Service 501009
		act_debug_info = act_debug_info->next;
Packit Service 501009
	}
Packit Service 501009
	return NULL;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void tod_clock_base_init(void)
Packit Service 501009
{
Packit Service 501009
	if (kernel_symbol_exists("tod_clock_base")) {
Packit Service 501009
		/*
Packit Service 501009
		 * Kernels >= 4.14 that contain 6e2ef5e4f6cc5734 ("s390/time:
Packit Service 501009
		 * add support for the TOD clock epoch extension")
Packit Service 501009
		 */
Packit Service 501009
		get_symbol_data("tod_clock_base", sizeof(tod_clock_base_us),
Packit Service 501009
				&tod_clock_base_us);
Packit Service 501009
		/* Bit for usecs is at position 59 - therefore shift 4 */
Packit Service 501009
		tod_clock_base_us >>= 4;
Packit Service 501009
	} else if (kernel_symbol_exists("sched_clock_base_cc") &&
Packit Service 501009
		   !kernel_symbol_exists("tod_to_timeval")) {
Packit Service 501009
		/*
Packit Service 501009
		 * Kernels >= 4.11 that contain ea417aa8a38bc7db ("s390/debug:
Packit Service 501009
		 * make debug event time stamps relative to the boot TOD clock")
Packit Service 501009
		 */
Packit Service 501009
		get_symbol_data("sched_clock_base_cc",
Packit Service 501009
				sizeof(tod_clock_base_us), &tod_clock_base_us);
Packit Service 501009
		/* Bit for usecs is at position 51 - therefore shift 12 */
Packit Service 501009
		tod_clock_base_us >>= 12;
Packit Service 501009
	} else {
Packit Service 501009
		/* All older kernels use absolute time stamps */
Packit Service 501009
		tod_clock_base_us = 0;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
dbf_init(void)
Packit Service 501009
{
Packit Service 501009
	if (!initialized) {
Packit Service 501009
		tod_clock_base_init();
Packit Service 501009
		if(dbf_version >= DBF_VERSION_V2)
Packit Service 501009
			add_lcrash_debug_view(&pages_view);
Packit Service 501009
		add_lcrash_debug_view(&ascii_view);
Packit Service 501009
		add_lcrash_debug_view(&level_view);
Packit Service 501009
		add_lcrash_debug_view(&ebcdic_view);
Packit Service 501009
		add_lcrash_debug_view(&hex_view);
Packit Service 501009
		add_lcrash_debug_view(&hex_ascii_view);
Packit Service 501009
		add_lcrash_debug_view(&sprintf_view);
Packit Service 501009
		add_lcrash_debug_view(&raw_view);
Packit Service 501009
		ebcdic_ascii_conv = iconv_open("ISO-8859-1", "EBCDIC-US");
Packit Service 501009
		initialized = 1;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static debug_view_t*
Packit Service 501009
get_debug_view(kaddr_t addr)
Packit Service 501009
{
Packit Service 501009
	void* k_debug_view;
Packit Service 501009
	int   k_debug_view_size;
Packit Service 501009
	debug_view_t* rc;
Packit Service 501009
Packit Service 501009
	rc = (debug_view_t*)malloc(sizeof(debug_view_t));
Packit Service 501009
	memset(rc, 0, sizeof(debug_view_t));
Packit Service 501009
Packit Service 501009
	k_debug_view_size = kl_struct_len("debug_view");
Packit Service 501009
	k_debug_view      = malloc(k_debug_view_size);
Packit Service 501009
	GET_BLOCK(addr, k_debug_view_size, k_debug_view);		
Packit Service 501009
	strncpy(rc->name,K_PTR(k_debug_view,"debug_view","name"),
Packit Service 501009
		DEBUG_MAX_PROCF_LEN);
Packit Service 501009
Packit Service 501009
	free(k_debug_view);
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
free_debug_view(debug_view_t* view)
Packit Service 501009
{
Packit Service 501009
	if(view) 
Packit Service 501009
		free(view);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
debug_get_areas_v1(debug_info_t* db_info, void* k_dbi)
Packit Service 501009
{
Packit Service 501009
	kaddr_t mem_pos;
Packit Service 501009
	kaddr_t dbe_addr;
Packit Service 501009
	int area_size, i;
Packit Service 501009
Packit Service 501009
       	/* get areas */
Packit Service 501009
	/* place to hold ptrs to debug areas in lcrash */
Packit Service 501009
	area_size = PAGE_SIZE << db_info->page_order;
Packit Service 501009
       	db_info->areas = (void**)malloc(db_info->nr_areas * sizeof(void *));
Packit Service 501009
	memset(db_info->areas, 0, db_info->nr_areas * sizeof(void *));
Packit Service 501009
       	mem_pos = KL_ULONG(k_dbi,"debug_info","areas");
Packit Service 501009
       	for (i = 0; i < db_info->nr_areas; i++) {
Packit Service 501009
		dbe_addr = KL_VREAD_PTR(mem_pos);
Packit Service 501009
	       	db_info->areas[i] = (debug_entry_t *) malloc(area_size);
Packit Service 501009
		/* read raw data for debug area */
Packit Service 501009
	       	GET_BLOCK(dbe_addr, area_size, db_info->areas[i]);
Packit Service 501009
		mem_pos += KL_NBPW;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
debug_get_areas_v2(debug_info_t* db_info, void* k_dbi)
Packit Service 501009
{
Packit Service 501009
	kaddr_t area_ptr;
Packit Service 501009
	kaddr_t page_array_ptr;
Packit Service 501009
	kaddr_t page_ptr;
Packit Service 501009
	int i,j;
Packit Service 501009
       	db_info->areas_v2=(void***)malloc(db_info->nr_areas * sizeof(void **));
Packit Service 501009
       	area_ptr = KL_ULONG(k_dbi,"debug_info","areas");
Packit Service 501009
       	for (i = 0; i < db_info->nr_areas; i++) {
Packit Service 501009
		db_info->areas_v2[i] = (void**)malloc(db_info->pages_per_area_v2
Packit Service 501009
							* sizeof(void*));
Packit Service 501009
		page_array_ptr = KL_VREAD_PTR(area_ptr);
Packit Service 501009
		for(j=0; j < db_info->pages_per_area_v2; j++) {
Packit Service 501009
			page_ptr = KL_VREAD_PTR(page_array_ptr);
Packit Service 501009
			db_info->areas_v2[i][j] = (void*)malloc(PAGE_SIZE);
Packit Service 501009
			/* read raw data for debug area */
Packit Service 501009
	       		GET_BLOCK(page_ptr, PAGE_SIZE, db_info->areas_v2[i][j]);
Packit Service 501009
			page_array_ptr += KL_NBPW;
Packit Service 501009
		}
Packit Service 501009
		area_ptr += KL_NBPW;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static debug_info_t*
Packit Service 501009
get_debug_info(kaddr_t addr,int get_areas)
Packit Service 501009
{
Packit Service 501009
	void *k_dbi;
Packit Service 501009
	kaddr_t mem_pos;
Packit Service 501009
	kaddr_t view_addr;
Packit Service 501009
	debug_info_t* db_info;
Packit Service 501009
	int i;
Packit Service 501009
	int dbi_size;
Packit Service 501009
Packit Service 501009
	/* get sizes of kernel structures */
Packit Service 501009
	if(!(dbi_size = kl_struct_len("debug_info"))){
Packit Service 501009
		fprintf (KL_ERRORFP,
Packit Service 501009
			 "Could not determine sizeof(struct debug_info)\n");
Packit Service 501009
		return(NULL);
Packit Service 501009
	}
Packit Service 501009
	if(!(dbe_size = kl_struct_len("__debug_entry"))){
Packit Service 501009
		fprintf(KL_ERRORFP,
Packit Service 501009
			"Could not determine sizeof(struct __debug_entry)\n");
Packit Service 501009
		return(NULL);
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	/* get kernel debug_info structure */
Packit Service 501009
	k_dbi = malloc(dbi_size);
Packit Service 501009
	GET_BLOCK(addr, dbi_size, k_dbi);
Packit Service 501009
Packit Service 501009
	db_info = (debug_info_t*)malloc(sizeof(debug_info_t));
Packit Service 501009
	memset(db_info, 0, sizeof(debug_info_t));
Packit Service 501009
Packit Service 501009
	/* copy members */
Packit Service 501009
	db_info->level	    = KL_INT(k_dbi,"debug_info","level");
Packit Service 501009
	db_info->nr_areas	 = KL_INT(k_dbi,"debug_info","nr_areas");
Packit Service 501009
	db_info->pages_per_area_v2= KL_INT(k_dbi,"debug_info","pages_per_area");
Packit Service 501009
	db_info->page_order       = KL_INT(k_dbi,"debug_info","page_order");
Packit Service 501009
	db_info->buf_size	 = KL_INT(k_dbi,"debug_info","buf_size");
Packit Service 501009
	db_info->entry_size       = KL_INT(k_dbi,"debug_info","entry_size");
Packit Service 501009
	db_info->next_dbi	 = KL_ULONG(k_dbi,"debug_info","next");
Packit Service 501009
	db_info->prev_dbi	 = KL_ULONG(k_dbi,"debug_info","prev");
Packit Service 501009
	db_info->addr	     = addr;
Packit Service 501009
	strncpy(db_info->name,K_PTR(k_dbi,"debug_info","name"),
Packit Service 501009
		DEBUG_MAX_PROCF_LEN);
Packit Service 501009
Packit Service 501009
Packit Service 501009
	if(get_areas){
Packit Service 501009
		if(dbf_version == DBF_VERSION_V1)
Packit Service 501009
			debug_get_areas_v1(db_info,k_dbi);
Packit Service 501009
		else
Packit Service 501009
			debug_get_areas_v2(db_info,k_dbi);
Packit Service 501009
	} else {
Packit Service 501009
		db_info->areas = NULL;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	/* get views */
Packit Service 501009
	mem_pos = (uaddr_t) K_PTR(k_dbi,"debug_info","views");
Packit Service 501009
	memset(&db_info->views, 0, DEBUG_MAX_VIEWS * sizeof(void*));
Packit Service 501009
	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
Packit Service 501009
		view_addr = KL_GET_PTR((void*)(uaddr_t)mem_pos);
Packit Service 501009
		if(view_addr == 0){
Packit Service 501009
			break;
Packit Service 501009
		} else {
Packit Service 501009
			db_info->views[i] = get_debug_view(view_addr);
Packit Service 501009
		}
Packit Service 501009
		mem_pos += KL_NBPW;
Packit Service 501009
	}
Packit Service 501009
	free(k_dbi);
Packit Service 501009
	return db_info;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
free_debug_info_v1(debug_info_t * db_info)
Packit Service 501009
{
Packit Service 501009
	int i;
Packit Service 501009
	if(db_info->areas){
Packit Service 501009
		for (i = 0; i < db_info->nr_areas; i++) {
Packit Service 501009
			free(db_info->areas[i]);
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
Packit Service 501009
		free_debug_view(db_info->views[i]);
Packit Service 501009
	}
Packit Service 501009
	free(db_info->areas);
Packit Service 501009
	free(db_info);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
free_debug_info_v2(debug_info_t * db_info)
Packit Service 501009
{
Packit Service 501009
	int i,j;
Packit Service 501009
	if(db_info->areas) {
Packit Service 501009
		for (i = 0; i < db_info->nr_areas; i++) {
Packit Service 501009
			for(j = 0; j < db_info->pages_per_area_v2; j++) {
Packit Service 501009
				free(db_info->areas_v2[i][j]);
Packit Service 501009
			}
Packit Service 501009
			free(db_info->areas[i]);
Packit Service 501009
		}
Packit Service 501009
		free(db_info->areas);
Packit Service 501009
		db_info->areas = NULL;
Packit Service 501009
	}
Packit Service 501009
	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
Packit Service 501009
		free_debug_view(db_info->views[i]);
Packit Service 501009
	}
Packit Service 501009
	free(db_info);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
debug_write_output(debug_info_t *db_info, debug_view_t *db_view, FILE * fp)
Packit Service 501009
{
Packit Service 501009
	if (dbf_version == DBF_VERSION_V1) {
Packit Service 501009
		debug_format_output_v1(db_info, db_view, fp);
Packit Service 501009
		free_debug_info_v1(db_info);
Packit Service 501009
	} else {
Packit Service 501009
		debug_format_output_v2(db_info, db_view, fp);
Packit Service 501009
		free_debug_info_v2(db_info);
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static int
Packit Service 501009
get_debug_areas(void)
Packit Service 501009
{
Packit Service 501009
	kaddr_t act_debug_area;
Packit Service 501009
	syment_t *debug_sym;
Packit Service 501009
	debug_info_t *act_debug_area_cpy;
Packit Service 501009
Packit Service 501009
	if(!(debug_sym = kl_lkup_symname("debug_area_first"))){
Packit Service 501009
		printf("Did not find debug_areas");
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	act_debug_area = KL_VREAD_PTR(debug_sym->s_addr);
Packit Service 501009
	while(act_debug_area != 0){
Packit Service 501009
		act_debug_area_cpy = get_debug_info(act_debug_area,0);
Packit Service 501009
		act_debug_area     = act_debug_area_cpy->next_dbi;
Packit Service 501009
	 	if(debug_area_first == NULL){
Packit Service 501009
			debug_area_first = act_debug_area_cpy;
Packit Service 501009
		} else {
Packit Service 501009
			debug_area_last->next = act_debug_area_cpy;
Packit Service 501009
		}
Packit Service 501009
		debug_area_last = act_debug_area_cpy;
Packit Service 501009
	}
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
free_debug_areas(void)
Packit Service 501009
{
Packit Service 501009
	debug_info_t* next;
Packit Service 501009
	debug_info_t* act_debug_info = debug_area_first;
Packit Service 501009
Packit Service 501009
	while(act_debug_info != NULL){
Packit Service 501009
		next = act_debug_info->next;
Packit Service 501009
		if(dbf_version == DBF_VERSION_V1)
Packit Service 501009
			free_debug_info_v1(act_debug_info);
Packit Service 501009
		else
Packit Service 501009
			free_debug_info_v2(act_debug_info);
Packit Service 501009
		act_debug_info = next;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	debug_area_first = NULL;
Packit Service 501009
	debug_area_last  = NULL;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static debug_view_t *
Packit Service 501009
find_lcrash_debug_view(const char *name)
Packit Service 501009
{
Packit Service 501009
	int i;
Packit Service 501009
	for (i = 0; (i < LCRASH_DB_VIEWS) && (debug_views[i] != NULL); i++) {
Packit Service 501009
		if (strcmp(debug_views[i]->name, name) == 0)
Packit Service 501009
			return debug_views[i];
Packit Service 501009
	}
Packit Service 501009
	return NULL;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
print_lcrash_debug_views(FILE * ofp)
Packit Service 501009
{
Packit Service 501009
	int i;
Packit Service 501009
	fprintf(ofp, "REGISTERED VIEWS\n");
Packit Service 501009
	fprintf(ofp, "=====================\n");
Packit Service 501009
	for (i = 0; i < LCRASH_DB_VIEWS; i++) {
Packit Service 501009
		if (debug_views[i] == NULL) {
Packit Service 501009
			return;
Packit Service 501009
		}
Packit Service 501009
		fprintf(ofp, " - %s\n", debug_views[i]->name);
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static int
Packit Service 501009
add_lcrash_debug_view(debug_view_t *view)
Packit Service 501009
{
Packit Service 501009
	int i;
Packit Service 501009
	for (i = 0; i < LCRASH_DB_VIEWS; i++) {
Packit Service 501009
		if (debug_views[i] == NULL) {
Packit Service 501009
			debug_views[i] = view;
Packit Service 501009
			return 0;
Packit Service 501009
		}
Packit Service 501009
		if (strcmp(debug_views[i]->name, view->name) == 0)
Packit Service 501009
			return -1;
Packit Service 501009
	}
Packit Service 501009
	return -1;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static int
Packit Service 501009
list_one_view(char *area_name, char *view_name, command_t * cmd)
Packit Service 501009
{
Packit Service 501009
	debug_info_t *db_info;
Packit Service 501009
	debug_view_t *db_view;
Packit Service 501009
Packit Service 501009
	if ((db_info = find_debug_area(area_name)) == NULL) {
Packit Service 501009
		fprintf(cmd->efp, "Debug log '%s' not found!\n", area_name);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	db_info = get_debug_info(db_info->addr,1);
Packit Service 501009
Packit Service 501009
	if ((db_view = find_lcrash_debug_view(view_name)) == NULL) {
Packit Service 501009
		fprintf(cmd->efp, "View '%s' not registered!\n", view_name);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	debug_write_output(db_info, db_view, cmd->ofp);
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static int
Packit Service 501009
list_areas(FILE * ofp)
Packit Service 501009
{
Packit Service 501009
	debug_info_t* act_debug_info = debug_area_first;
Packit Service 501009
	fprintf(ofp, "Debug Logs:\n");
Packit Service 501009
	fprintf(ofp, "==================\n");
Packit Service 501009
	while(act_debug_info != NULL){
Packit Service 501009
		fprintf(ofp, " - %s\n", act_debug_info->name);
Packit Service 501009
		act_debug_info = act_debug_info->next;
Packit Service 501009
	}
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static int
Packit Service 501009
list_one_area(const char *area_name, command_t * cmd)
Packit Service 501009
{
Packit Service 501009
	debug_info_t *db_info;
Packit Service 501009
	int i;
Packit Service 501009
	if ((db_info = find_debug_area(area_name)) == NULL) {
Packit Service 501009
		fprintf(cmd->efp, "Debug log '%s' not found!\n", area_name);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	fprintf(cmd->ofp, "INSTALLED VIEWS FOR '%s':\n", area_name);
Packit Service 501009
	fprintf(cmd->ofp, "================================================"
Packit Service 501009
		"==============================\n");
Packit Service 501009
	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
Packit Service 501009
		if (db_info->views[i] != NULL) {
Packit Service 501009
			fprintf(cmd->ofp, " - %s ", db_info->views[i]->name);
Packit Service 501009
			if (find_lcrash_debug_view(db_info->views[i]->name))
Packit Service 501009
				fprintf(cmd->ofp, "(available)\n");
Packit Service 501009
			else
Packit Service 501009
				fprintf(cmd->ofp, "(not available)\n");
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
	fprintf(cmd->ofp, "================================================="
Packit Service 501009
		"=============================\n");
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
#ifdef DBF_DYNAMIC_VIEWS
Packit Service 501009
static int
Packit Service 501009
load_debug_view(const char *path, command_t * cmd)
Packit Service 501009
{
Packit Service 501009
	void *library;
Packit Service 501009
	const char *error;
Packit Service 501009
	debug_view_t *(*view_init_func) (void);
Packit Service 501009
Packit Service 501009
	library = dlopen(path, RTLD_LAZY);
Packit Service 501009
	if (library == NULL) {
Packit Service 501009
		fprintf(cmd->efp, "Could not open %s: %s\n", path, dlerror());
Packit Service 501009
		return (1);
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	dlerror();
Packit Service 501009
Packit Service 501009
	view_init_func = dlsym(library, "debug_view_init");
Packit Service 501009
	error = dlerror();
Packit Service 501009
Packit Service 501009
	if (error) {
Packit Service 501009
		fprintf(stderr, "could not find debug_view_init(): %s\n",
Packit Service 501009
			error);
Packit Service 501009
		exit(1);
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	add_lcrash_debug_view((*view_init_func) ());
Packit Service 501009
Packit Service 501009
	fprintf(cmd->ofp, "view %s loaded\n", path);
Packit Service 501009
	fflush(stdout);
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
#endif
Packit Service 501009
Packit Service 501009
static int
Packit Service 501009
save_one_view(const char *dbf_dir_name, const char *area_name,
Packit Service 501009
	      const char *view_name, command_t *cmd)
Packit Service 501009
{
Packit Service 501009
	char path_view[PATH_MAX];
Packit Service 501009
	debug_info_t *db_info;
Packit Service 501009
	debug_view_t *db_view;
Packit Service 501009
	FILE *view_fh;
Packit Service 501009
Packit Service 501009
	db_info = find_debug_area(area_name);
Packit Service 501009
	if (db_info == NULL) {
Packit Service 501009
		fprintf(cmd->efp, "Debug log '%s' not found!\n", area_name);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	db_info = get_debug_info(db_info->addr, 1);
Packit Service 501009
Packit Service 501009
	db_view = find_lcrash_debug_view(view_name);
Packit Service 501009
	if (db_view == NULL) {
Packit Service 501009
		fprintf(cmd->efp, "View '%s' not registered!\n", view_name);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	sprintf(path_view, "%s/%s/%s", dbf_dir_name, area_name, view_name);
Packit Service 501009
	view_fh = fopen(path_view, "w");
Packit Service 501009
	if (view_fh == NULL) {
Packit Service 501009
		fprintf(cmd->efp, "Could not create file: %s (%s)\n",
Packit Service 501009
			path_view, strerror(errno));
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	debug_write_output(db_info, db_view, view_fh);
Packit Service 501009
	fclose(view_fh);
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static int
Packit Service 501009
save_one_area(const char *dbf_dir_name, const char *area_name, command_t *cmd)
Packit Service 501009
{
Packit Service 501009
	char dir_name_area[PATH_MAX];
Packit Service 501009
	debug_info_t *db_info;
Packit Service 501009
	int i;
Packit Service 501009
Packit Service 501009
	db_info = find_debug_area(area_name);
Packit Service 501009
	if (db_info == NULL) {
Packit Service 501009
		fprintf(cmd->efp, "Debug log '%s' not found!\n", area_name);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	sprintf(dir_name_area, "%s/%s", dbf_dir_name, area_name);
Packit Service 501009
	if (mkdir(dir_name_area, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
Packit Service 501009
		fprintf(cmd->efp, "Could not create directory: %s (%s)\n",
Packit Service 501009
			dir_name_area, strerror(errno));
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
Packit Service 501009
		if (db_info->views[i] == NULL)
Packit Service 501009
			continue;
Packit Service 501009
		if (!find_lcrash_debug_view(db_info->views[i]->name))
Packit Service 501009
			continue;
Packit Service 501009
		save_one_view(dbf_dir_name, area_name, db_info->views[i]->name,
Packit Service 501009
			      cmd);
Packit Service 501009
	}
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
static void
Packit Service 501009
save_dbf(const char *dbf_dir_name, command_t *cmd)
Packit Service 501009
{
Packit Service 501009
	debug_info_t *act_debug_info = debug_area_first;
Packit Service 501009
	FILE *ofp = cmd->ofp;
Packit Service 501009
Packit Service 501009
	fprintf(ofp, "Saving s390dbf to directory \"%s\"\n", dbf_dir_name);
Packit Service 501009
	if (mkdir(dbf_dir_name, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
Packit Service 501009
		fprintf(cmd->efp, "Could not create directory: %s (%s)\n",
Packit Service 501009
			dbf_dir_name, strerror(errno));
Packit Service 501009
		return;
Packit Service 501009
	}
Packit Service 501009
	while (act_debug_info != NULL) {
Packit Service 501009
		save_one_area(dbf_dir_name, act_debug_info->name, cmd);
Packit Service 501009
		act_debug_info = act_debug_info->next;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/* 
Packit Service 501009
 * s390dbf_cmd() -- Run the 's390dbf' command.
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
s390dbf_cmd(command_t * cmd)
Packit Service 501009
{
Packit Service 501009
	syment_t *dbf_version_sym;
Packit Service 501009
	int rc = 0;
Packit Service 501009
Packit Service 501009
	/* check version */
Packit Service 501009
 
Packit Service 501009
	if(!(dbf_version_sym = kl_lkup_symname("debug_feature_version"))){
Packit Service 501009
		fprintf(KL_ERRORFP,
Packit Service 501009
			"Could not determine debug_feature_version\n");
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	dbf_version = KL_VREAD_UINT32(dbf_version_sym->s_addr);
Packit Service 501009
Packit Service 501009
	if ((dbf_version != DBF_VERSION_V1) && (dbf_version != DBF_VERSION_V2)){
Packit Service 501009
		fprintf(cmd->efp,"lcrash does not support the"
Packit Service 501009
			" debug feature version of the dump kernel:\n");
Packit Service 501009
		fprintf(cmd->efp,"DUMP: %i SUPPORTED: %i and %i\n",
Packit Service 501009
			dbf_version, DBF_VERSION_V1, DBF_VERSION_V2);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	dbf_init();
Packit Service 501009
Packit Service 501009
	if (cmd->flags & C_ALL) {
Packit Service 501009
		return (0);
Packit Service 501009
	}
Packit Service 501009
#ifdef DBF_DYNAMIC_VIEWS
Packit Service 501009
	if (cmd->flags & LOAD_FLAG) {
Packit Service 501009
		printf("loading: %s\n", cmd->args[0]);
Packit Service 501009
		return (load_debug_view(cmd->args[0], cmd));
Packit Service 501009
	}
Packit Service 501009
#endif
Packit Service 501009
	if (cmd->flags & VIEWS_FLAG) {
Packit Service 501009
		print_lcrash_debug_views(cmd->ofp);
Packit Service 501009
		return (0);
Packit Service 501009
	}
Packit Service 501009
	if (cmd->nargs > 2) {
Packit Service 501009
		s390dbf_usage(cmd);
Packit Service 501009
		return (1);
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if(get_debug_areas() == -1) 
Packit Service 501009
		return -1;
Packit Service 501009
Packit Service 501009
	if (cmd->flags & SAVE_DBF_FLAG) {
Packit Service 501009
		if (cmd->nargs != 2) {
Packit Service 501009
			fprintf(cmd->efp, "Specify directory name for -s\n");
Packit Service 501009
			return 1;
Packit Service 501009
		}
Packit Service 501009
		save_dbf(cmd->args[1], cmd);
Packit Service 501009
		return 0;
Packit Service 501009
	}
Packit Service 501009
	switch (cmd->nargs) {
Packit Service 501009
	case 0:
Packit Service 501009
		rc = list_areas(cmd->ofp);
Packit Service 501009
		break;
Packit Service 501009
	case 1:
Packit Service 501009
		rc = list_one_area(cmd->args[0], cmd);
Packit Service 501009
		break;
Packit Service 501009
	case 2:
Packit Service 501009
		rc = list_one_view(cmd->args[0], cmd->args[1], cmd);
Packit Service 501009
		break;	
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	free_debug_areas();
Packit Service 501009
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
#define _S390DBF_USAGE " [-v] [-s dirname] [debug log] [debug view]"
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * s390dbf_usage() -- Print the usage string for the 's390dbf' command.
Packit Service 501009
 */
Packit Service 501009
void
Packit Service 501009
s390dbf_usage(command_t * cmd)
Packit Service 501009
{
Packit Service 501009
	CMD_USAGE(cmd, _S390DBF_USAGE);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * s390 debug feature command for crash
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
char *help_s390dbf[] = {
Packit Service 501009
	"s390dbf",
Packit Service 501009
	"s390dbf prints out debug feature logs",
Packit Service 501009
	"[-v] [-s dirname] [debug log] [debug view]"
Packit Service 501009
	"",
Packit Service 501009
	"Display Debug logs:",
Packit Service 501009
	" + If called without parameters, all active debug logs are listed.",
Packit Service 501009
	" + If called with the name of a debug log, all debug-views for which",
Packit Service 501009
	"   the debug-log has registered are listed. It is possible thatsome",
Packit Service 501009
	"   of the debug views are not available to 'crash'.",
Packit Service 501009
	" + If called with the name of a debug-log and an available viewname,",
Packit Service 501009
	"   the specified view is printed.",
Packit Service 501009
	" + If called with '-s dirname', the s390dbf is saved to the specified",
Packit Service 501009
	"   directory",
Packit Service 501009
	" + If called with '-v', all debug views which are available to",
Packit Service 501009
	"   'crash' are listed",
Packit Service 501009
	NULL
Packit Service 501009
};
Packit Service 501009
Packit Service 501009
void cmd_s390dbf()
Packit Service 501009
{
Packit Service 501009
	int i,c;
Packit Service 501009
Packit Service 501009
	command_t cmd = {
Packit Service 501009
		.ofp = fp,
Packit Service 501009
		.efp = stderr,
Packit Service 501009
		.cmdstr = "s390dbf",
Packit Service 501009
		.command = "s390dbf",
Packit Service 501009
	};
Packit Service 501009
Packit Service 501009
	cmd.nargs=argcnt - 1;
Packit Service 501009
	for (i=1; i < argcnt; i++)
Packit Service 501009
		cmd.args[i-1] = args[i];
Packit Service 501009
	
Packit Service 501009
	while ((c = getopt(argcnt, args, "vs")) != EOF) {
Packit Service 501009
		switch(c) {
Packit Service 501009
		case 'v':
Packit Service 501009
			cmd.flags |= VIEWS_FLAG;
Packit Service 501009
			break;
Packit Service 501009
		case 's':
Packit Service 501009
			cmd.flags |= SAVE_DBF_FLAG;
Packit Service 501009
			break;
Packit Service 501009
		default:
Packit Service 501009
			s390dbf_usage(&cmd);
Packit Service 501009
			return;
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
	s390dbf_cmd(&cmd);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
#endif
Packit Service 501009