1. New debug_ch has new log levels.
SEVERE, WARN, INFO, CONFIG, FINE, TRACE
2. Use LOG_[LEVEL](...) instead of [LEVEL](...). Legacy macro names can conflict other macro names. Some weird compilation error is occured because of it.
(legacy ERR macro unset existing ERR macro)
2. Remove multi debug channel because it is not used.
3. "debug_ch.h" has legacy log levels for compatibility.
4. Remove ASSERT macro.
Use new debug_ch instead of legacy one when you modify your sources.
Change-Id: Ie2ce25a5222c479897c13473e25a1ee3b3fd5d52
Signed-off-by: Munkyu Im <munkyu.im@samsung.com>
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
# maru skin
obj-y += skin/
-# debug channel
-obj-y += debug_ch.o
-
# maru hardware
obj-y += hw/
+++ /dev/null
-/*
- * Management of the debugging channels
- *
- * Copyright 2000 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-/**
- * @file debug_ch.c
- * @brief Management of the debugging channels
- *
- * @author
- * @date
- * @attention
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <assert.h>
-#include <unistd.h>
-#include "qemu-common.h"
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <errno.h>
-#endif
-
-#include "emulator.h"
-#include "debug_ch.h"
-#include "util/osutil.h"
-
-static char debugchfile[512] = {0, };
-#ifdef _WIN32
-static HANDLE handle;
-#endif
-
-static inline int interlocked_xchg_add(int *dest, int incr)
-{
- int ret_val;
- __asm__ __volatile__("lock; xaddl %0,(%1)"
- : "=r" (ret_val) : "r" (dest), "0" (incr) : "memory");
-
- return ret_val;
-}
-
-static const char * const debug_classes[] = {"fixme", "err", "warn", "trace", "info"};
-
-#define MAX_DEBUG_OPTIONS 256
-
-//static unsigned char default_flags = (1 << __DBCL_ERR) | (1 << __DBCL_FIXME) | (1 << __DBCL_INFO);
-static unsigned char default_flags = (1 << __DBCL_ERR) | (1 << __DBCL_INFO);
-static int nb_debug_options = -1;
-static struct _debug_channel debug_options[MAX_DEBUG_OPTIONS];
-
-static void debug_init(void);
-
-static int cmp_name(const void *p1, const void *p2)
-{
- const char *name = p1;
- const struct _debug_channel *chan = p2;
-
- return strcmp(name, chan->name);
-}
-
-/* get the flags to use for a given channel, possibly setting them too in case of lazy init */
-unsigned char _dbg_get_channel_flags(struct _debug_channel *channel)
-{
- if (nb_debug_options == -1) {
- debug_init();
- }
-
- if (nb_debug_options) {
- struct _debug_channel *opt;
-
- /* first check for multi channel */
- opt = bsearch(channel->multiname,
- debug_options,
- nb_debug_options,
- sizeof(debug_options[0]), cmp_name);
- if (opt) {
- return opt->flags;
- }
-
- opt = bsearch(channel->name,
- debug_options,
- nb_debug_options,
- sizeof(debug_options[0]), cmp_name);
- if (opt) {
- return opt->flags;
- }
- }
-
- /* no option for this channel */
- if (channel->flags & (1 << __DBCL_INIT)) {
- channel->flags = default_flags;
- }
-
- return default_flags;
-}
-
-/* set the flags to use for a given channel; return 0 if the channel is not available to set */
-int _dbg_set_channel_flags(struct _debug_channel *channel,
- unsigned char set, unsigned char clear)
-{
- if (nb_debug_options == -1) {
- debug_init();
- }
-
- if (nb_debug_options) {
- struct _debug_channel *opt;
-
- /* first set for multi channel */
- opt = bsearch(channel->multiname,
- debug_options,
- nb_debug_options,
- sizeof(debug_options[0]), cmp_name);
- if (opt) {
- opt->flags = (opt->flags & ~clear) | set;
- return 1;
- }
-
- opt = bsearch(channel->name,
- debug_options,
- nb_debug_options,
- sizeof(debug_options[0]), cmp_name);
- if (opt) {
- opt->flags = (opt->flags & ~clear) | set;
- return 1;
- }
- }
-
- return 0;
-}
-
-/* add a new debug option at the end of the option list */
-static void add_option(const char *name, unsigned char set, unsigned char clear)
-{
- int min = 0, max = nb_debug_options - 1, pos, res;
-
- if (!name[0]) { /* "all" option */
- default_flags = (default_flags & ~clear) | set;
- return;
- }
-
- if (strlen(name) >= sizeof(debug_options[0].name)) {
- return;
- }
-
- while (min <= max) {
- pos = (min + max) / 2;
- res = strcmp(name, debug_options[pos].name);
- if (!res) {
- debug_options[pos].flags = (debug_options[pos].flags & ~clear) | set;
- return;
- }
-
- if (res < 0) {
- max = pos - 1;
- } else {
- min = pos + 1;
- }
- }
- if (nb_debug_options >= MAX_DEBUG_OPTIONS) {
- return;
- }
-
- pos = min;
- if (pos < nb_debug_options) {
- memmove(&debug_options[pos + 1],
- &debug_options[pos],
- (nb_debug_options - pos) * sizeof(debug_options[0]));
- }
-
- strcpy(debug_options[pos].name, name);
- debug_options[pos].flags = (default_flags & ~clear) | set;
- nb_debug_options++;
-}
-
-/* parse a set of debugging option specifications and add them to the option list */
-static void parse_options(const char *str)
-{
- char *opt, *next, *options;
- unsigned int i;
-
- if (!(options = strdup(str))) {
- return;
- }
-
- for (opt = options; opt; opt = next) {
- const char *p;
- unsigned char set = 0, clear = 0;
-
- if ((next = strchr( opt, ',' ))) {
- *next++ = 0;
- }
-
- p = opt + strcspn( opt, "+-" );
- if (!p[0]) {
- p = opt; /* assume it's a debug channel name */
- }
-
- if (p > opt) {
- for (i = 0; i < sizeof(debug_classes) / sizeof(debug_classes[0]); i++) {
- int len = strlen(debug_classes[i]);
- if (len != (p - opt)) {
- continue;
- }
-
- if (!memcmp( opt, debug_classes[i], len)) { /* found it */
- if (*p == '+') {
- set |= 1 << i;
- } else {
- clear |= 1 << i;
- }
- break;
- }
- }
-
- if (i == sizeof(debug_classes) / sizeof(debug_classes[0])) { /* bad class name, skip it */
- continue;
- }
- } else {
- if (*p == '-') {
- clear = ~0;
- } else {
- set = ~0;
- }
- }
-
- if (*p == '+' || *p == '-') {
- p++;
- }
- if (!p[0]) {
- continue;
- }
-
- if (!strcmp(p, "all")) {
- default_flags = (default_flags & ~clear) | set;
- } else {
- add_option(p, set, clear);
- }
- }
-
- free(options);
-}
-
-/* print the usage message */
-static void debug_usage(void)
-{
- static const char usage[] =
- "Syntax of the DEBUGCH variable:\n"
- " DEBUGCH=[class]+xxx,[class]-yyy,...\n\n"
- "Example: DEBUGCH=+all,warn-heap\n"
- " turns on all messages except warning heap messages\n"
- "Available message classes: err, warn, fixme, trace\n";
- const int ret = write(2, usage, sizeof(usage) - 1);
-
- assert(ret >= 0);
- exit(1);
-}
-
-/* initialize all options at startup */
-static void debug_init(void)
-{
- char *debug = NULL;
- FILE *fp = NULL;
- char *tmp = NULL;
-
- if (nb_debug_options != -1) {
- return; /* already initialized */
- }
-
- nb_debug_options = 0;
-
-#if 0
- strcpy(debugchfile, get_etc_path());
- strcat(debugchfile, "/DEBUGCH");
-#endif
-
- if (0 == strlen(bin_path)) {
- strcpy(debugchfile, "DEBUGCH");
- } else {
- strcat(debugchfile, bin_path);
- strcat(debugchfile, "DEBUGCH");
- }
-
- fp = fopen(debugchfile, "r");
- if (fp == NULL) {
- debug = getenv("DEBUGCH");
- } else {
- if ((tmp = (char *)malloc(1024 + 1)) == NULL){
- fclose(fp);
- return;
- }
-
- if(fseek(fp, 0, SEEK_SET) != 0) {
- fclose(fp);
- fprintf(stderr, "failed to fseek()\n");
-
- if (tmp != NULL)
- free(tmp);
-
- return;
- }
- const char* str = fgets(tmp, 1024, fp);
- if (str) {
- tmp[strlen(tmp) - 1] = 0;
- debug = tmp;
- }
-
- fclose(fp);
- }
-
- if (debug != NULL) {
- if (!strcmp(debug, "help")) {
- debug_usage();
- }
- parse_options(debug);
- }
-
- if (tmp != NULL) {
- free(tmp);
- }
-}
-
-/* allocate some tmp string space */
-/* FIXME: this is not 100% thread-safe */
-char *get_dbg_temp_buffer(size_t size)
-{
- static char *list[32];
- static int pos;
- char *ret;
- int idx;
-
- idx = interlocked_xchg_add(&pos, 1) % (sizeof(list) / sizeof(list[0]));
-
- if ((ret = realloc(list[idx], size))) {
- list[idx] = ret;
- }
-
- return ret;
-}
-
-/* release unused part of the buffer */
-void release_dbg_temp_buffer(char *buffer, size_t size)
-{
- /* don't bother doing anything */
- (void)(buffer);
- (void)(size);
-}
-
-static int dbg_vprintf(const char *format, va_list args)
-{
- char tmp[MSGSIZE_MAX] = { 0, };
- char txt[MSGSIZE_MAX] = { 0, };
-
- FILE *fp;
- // lock
-
- int ret = vsnprintf(tmp, MSGSIZE_MAX, format, args);
-
- tmp[MSGSIZE_MAX - 2] = '\n';
- tmp[MSGSIZE_MAX - 1] = 0;
-
- sprintf(txt, "%s", tmp);
-
- // unlock
- if ((fp = fopen(log_path, "a+")) == NULL) {
- fprintf(stdout, "Emulator can't open.\n"
- "Please check if "
- "this binary file is running on the right path.\n");
- exit(1);
- }
-
- fputs(txt, fp);
- fclose(fp);
-
- return ret;
-}
-
-int dbg_printf(const char *format, ...)
-{
- int ret;
- va_list valist;
-
- va_start(valist, format);
- ret = dbg_vprintf(format, valist);
- va_end(valist);
-
- return ret;
-}
-
-int dbg_printf_nonewline(const char *format, ...)
-{
- int ret;
- va_list valist;
-
- va_start(valist, format);
- ret = dbg_vprintf(format, valist);
- va_end(valist);
-
- return ret;
-}
-
-/* printf with temp buffer allocation */
-const char *dbg_sprintf(const char *format, ...)
-{
- static const int max_size = 200;
- char *ret;
- int len;
- va_list valist;
-
- va_start(valist, format);
- ret = get_dbg_temp_buffer(max_size);
- len = vsnprintf(ret, max_size, format, valist);
-
- if (len == -1 || len >= max_size) {
- ret[max_size-1] = 0;
- } else {
- release_dbg_temp_buffer(ret, len + 1);
- }
- va_end(valist);
-
- return ret;
-}
-
-int dbg_log(enum _debug_class cls, struct _debug_channel *channel,
- const char *format, ...)
-{
- int ret = 0;
- int ret_write = 0;
- char buf_msg[2048];
- va_list valist;
- int open_flags;
- int fd;
-
- if (!(_dbg_get_channel_flags(channel) & (1 << cls))) {
- return -1;
- }
-
- ret += snprintf(buf_msg, sizeof(buf_msg),"%s [%s:%s",
- get_timeofday(), debug_classes[cls], channel->name);
-
- if (*channel->multiname) {
- ret += snprintf(buf_msg + ret, sizeof(buf_msg) - ret, ":%s] ", channel->multiname);
- } else {
- ret += snprintf(buf_msg + ret, sizeof(buf_msg) - ret, "] ");
- }
-
- va_start(valist, format);
- ret += vsnprintf(buf_msg + ret, sizeof(buf_msg) - ret, format, valist);
- va_end(valist);
-
- // If "log_path" is not set, we use "stdout".
- if (log_path[0] == '\0') {
- fprintf(stdout, "%s", buf_msg);
- return ret;
- }
-
- open_flags = O_RDWR | O_APPEND | O_BINARY | O_CREAT;
-
- fd = qemu_open(log_path, open_flags, 0666);
- if (fd < 0) {
- fprintf(stderr, "Can't open logfile: %s\n", log_path);
- /* commented out for prevent shutdown when log directory is removed on runtime. */
- //exit(1);
- return -1;
- }
-
- ret_write = qemu_write_full(fd, buf_msg, ret);
- if (ret_write != ret) {
- // TODO: error handling...
- }
- close(fd);
-
- return ret;
-}
-
-void assert_fail(char *exp, const char *file, int line)
-{
- fprintf(stderr, "[%s][%d] Assert(%s) failed \n"
- , file, line, exp);
- fprintf(stdout, "[%s][%d] Assert(%s) failed \n"
- , file, line, exp);
- exit(0);
-}
-
-/* end of debug_ch.c */
/*
- * Wine debugging interface
+ * New debug channel
*
- * Copyright 1999 Patrik Stridvall
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Munkyu Im <munkyu.im@samsung.com>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
+ * 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.
*
- * This library is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-
-/**
- * @file debug_ch.h
- * @brief Management of the debugging channels
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ * refer to debug_ch.h
+ * Copyright 1999 Patrik Stridvall
*
- * @author
- * @date
- * @attention
*/
-#ifndef __DEBUGCHANNEL_H
-#define __DEBUGCHANNEL_H
-
-#include <sys/types.h>
-
-// #define NO_DEBUG
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum _debug_class
-{
- __DBCL_FIXME,
- __DBCL_ERR,
- __DBCL_WARN,
- __DBCL_TRACE,
- __DBCL_INFO,
-
- __DBCL_INIT = 7 /* lazy init flag */
-};
-
-struct _debug_channel
-{
- unsigned char flags;
- char name[15];
- char multiname[15];
-};
-
-#ifndef NO_DEBUG
-#define MSGSIZE_MAX 2048
-#define __GET_DEBUGGING_FIXME(dbch) ((dbch)->flags & (1 << __DBCL_FIXME))
-#define __GET_DEBUGGING_ERR(dbch) ((dbch)->flags & (1 << __DBCL_ERR))
-#define __GET_DEBUGGING_WARN(dbch) ((dbch)->flags & (1 << __DBCL_WARN))
-#define __GET_DEBUGGING_TRACE(dbch) ((dbch)->flags & (1 << __DBCL_TRACE))
-#define __GET_DEBUGGING_INFO(dbch) ((dbch)->flags & (1 << __DBCL_INFO))
-#else
-#define __GET_DEBUGGING_FIXME(dbch) 0
-#define __GET_DEBUGGING_ERR(dbch) 0
-#define __GET_DEBUGGING_WARN(dbch) 0
-#define __GET_DEBUGGING_TRACE(dbch) 0
-#define __GET_DEBUGGING_INFO(dbch) 0
-#endif
-
-#define __GET_DEBUGGING(dbcl,dbch) __GET_DEBUGGING##dbcl(dbch)
+// header file for legacy debug_ch compatibility
-#define __IS_DEBUG_ON(dbcl,dbch) \
- (__GET_DEBUGGING##dbcl(dbch) && \
- (_dbg_get_channel_flags(dbch) & (1 << __DBCL##dbcl)))
+#ifndef __DEBUG_CH_H
+#define __DEBUG_CH_H
-#define __DPRINTF(dbcl,dbch) \
- do{ if(__GET_DEBUGGING(dbcl,(dbch))){ \
- struct _debug_channel * const __dbch =(struct _debug_channel *)(dbch); \
- const enum _debug_class __dbcl = __DBCL##dbcl; \
- _DBG_LOG
+#include "util/new_debug_ch.h"
-#define _DBG_LOG(args...) \
- dbg_log(__dbcl, (struct _debug_channel *)(__dbch), args); } }while(0)
-/*
-
-#define __DPRINTF(dbcl,dbch) \
- (!__GET_DEBUGGING(dbcl,(dbch)) || \
- (dbg_log(__DBCL##dbcl,(dbch), "") == -1)) ? \
-(void)0 : (void)dbg_printf
-*/
-
-extern unsigned char _dbg_get_channel_flags(struct _debug_channel *channel);
-extern int _dbg_set_channel_flags(struct _debug_channel *channel,
- unsigned char set, unsigned char clear);
-
-extern const char *dbg_sprintf(const char *format, ...);
-extern int dbg_printf(const char *format, ...);
-extern int dbg_printf_nonewline(const char *format, ...);
-extern int dbg_log(enum _debug_class cls, struct _debug_channel *ch,
- const char *format, ...);
-
-extern char *get_dbg_temp_buffer(size_t size);
-extern void release_dbg_temp_buffer(char *buffer, size_t size);
+#undef ERR
+#define ERR LOG_SEVERE
-#ifndef TRACE
-#define TRACE __DPRINTF(_TRACE,_dbch___default)
-#define TRACE_(ch) __DPRINTF(_TRACE,&_dbch_##ch)
+#ifndef WARN
+#define WARN LOG_WARNING
#endif
-#define TRACE_ON(ch) __IS_DEBUG_ON(_TRACE,&_dbch_##ch)
-#ifndef WARN
-#define WARN __DPRINTF(_WARN,_dbch___default)
-#define WARN_(ch) __DPRINTF(_WARN,&_dbch_##ch)
+#ifndef INFO
+#define INFO LOG_INFO
#endif
-#define WARN_ON(ch) __IS_DEBUG_ON(_WARN,&_dbch_##ch)
#ifndef FIXME
-#define FIXME __DPRINTF(_FIXME,_dbch___default)
-#define FIXME_(ch) __DPRINTF(_FIXME,&_dbch_##ch)
+#define FIXME LOG_FINE
#endif
-#define FIXME_ON(ch) __IS_DEBUG_ON(_FIXME,&_dbch_##ch)
-#undef ERR
-#define ERR __DPRINTF(_ERR,_dbch___default)
-#define ERR_(ch) __DPRINTF(_ERR,&_dbch_##ch)
-#define ERR_ON(ch) __IS_DEBUG_ON(_ERR,&_dbch_##ch)
-
-#ifndef INFO
-#define INFO __DPRINTF(_INFO,_dbch___default)
-#define INFO_(ch) __DPRINTF(_INFO,&_dbch_##ch)
+#ifndef TRACE
+#define TRACE LOG_TRACE
#endif
-#define INFO_ON(ch) __IS_DEBUG_ON(_INFO,&_dbch_##ch)
-
-#define DECLARE_DEBUG_CHANNEL(ch) \
- static struct _debug_channel _dbch_##ch = { ~0, #ch, ""};
-#define DEFAULT_DEBUG_CHANNEL(ch) \
- static struct _debug_channel _dbch_##ch = { ~0, #ch, ""}; \
-static struct _debug_channel * const _dbch___default = &_dbch_##ch
-
-#define MULTI_DEBUG_CHANNEL(ch, chm) \
- static struct _debug_channel _dbch_##ch = { ~0, #ch , #chm}; \
-static struct _debug_channel * const _dbch___default = &_dbch_##ch
-#define DPRINTF dbg_printf
-#define MESSAGE dbg_printf
-
-void assert_fail(char *exp, const char *file, int line);
-
-#define ASSERT(exp) if (exp) ; \
- else assert_fail( (char *)#exp, __FILE__, __LINE__ )
-
-#ifdef __cplusplus
-}
-#endif
+#define MULTI_DEBUG_CHANNEL(ch, chm) DECLARE_DEBUG_CHANNEL(chm)
-#endif /* __DEBUGCHANNEL_H */
+#endif // __DEBUG_CH_H
return hr;
}
}
- ASSERT(This->m_pAllocator != NULL);
+ assert(This->m_pAllocator != NULL);
*ppAllocator = This->m_pAllocator;
IMemAllocator_AddRef(This->m_pAllocator);
# error table
obj-y += maru_err_table.o
+# debug channel
+obj-y += new_debug_ch.o
+
$(obj)/osutil.o: QEMU_CFLAGS += $(CURL_CFLAGS)
--- /dev/null
+/*
+ * New debug channel
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Munkyu Im <munkyu.im@samsung.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ * refer to debug_ch.c
+ * Copyright 2000 Alexandre Julliard
+ *
+ */
+
+#include <stdio.h>
+
+#include "qemu-common.h"
+
+#include "emulator.h"
+#include "util/new_debug_ch.h"
+#include "util/osutil.h"
+
+static char debugchfile[512] = {0, };
+static int fd = STDOUT_FILENO;
+
+static const char * const debug_classes[] =
+ {"SEVERE", "WARNING", "INFO", "CONFIG", "FINE", "TRACE"};
+
+#define MAX_DEBUG_OPTIONS 256
+
+static unsigned char default_flags =
+ (1 << __DBCL_SEVERE) | (1 << __DBCL_WARNING) | (1 << __DBCL_INFO);
+static int nb_debug_options = -1;
+static struct _debug_channel debug_options[MAX_DEBUG_OPTIONS];
+
+static void debug_init(void);
+
+static int cmp_name(const void *p1, const void *p2)
+{
+ const char *name = p1;
+ const struct _debug_channel *chan = p2;
+
+ return strcmp(name, chan->name);
+}
+
+/* get the flags to use for a given channel, possibly setting them too in case of lazy init */
+unsigned char _dbg_get_channel_flags(struct _debug_channel *channel)
+{
+ if (nb_debug_options == -1) {
+ debug_init();
+ }
+
+ if (nb_debug_options) {
+ struct _debug_channel *opt;
+
+ opt = bsearch(channel->name,
+ debug_options,
+ nb_debug_options,
+ sizeof(debug_options[0]), cmp_name);
+ if (opt) {
+ return opt->flags;
+ }
+ }
+
+ /* no option for this channel */
+ if (channel->flags & (1 << __DBCL_INIT)) {
+ channel->flags = default_flags;
+ }
+
+ return default_flags;
+}
+
+/* add a new debug option at the end of the option list */
+static void add_option(const char *name, unsigned char set, unsigned char clear)
+{
+ int min = 0, max = nb_debug_options - 1, pos, res;
+
+ if (!name[0]) { /* "all" option */
+ default_flags = (default_flags & ~clear) | set;
+ return;
+ }
+
+ if (strlen(name) >= sizeof(debug_options[0].name)) {
+ return;
+ }
+
+ while (min <= max) {
+ pos = (min + max) / 2;
+ res = strcmp(name, debug_options[pos].name);
+ if (!res) {
+ debug_options[pos].flags = (debug_options[pos].flags & ~clear) | set;
+ return;
+ }
+
+ if (res < 0) {
+ max = pos - 1;
+ } else {
+ min = pos + 1;
+ }
+ }
+ if (nb_debug_options >= MAX_DEBUG_OPTIONS) {
+ return;
+ }
+
+ pos = min;
+ if (pos < nb_debug_options) {
+ memmove(&debug_options[pos + 1],
+ &debug_options[pos],
+ (nb_debug_options - pos) * sizeof(debug_options[0]));
+ }
+
+ strcpy(debug_options[pos].name, name);
+ debug_options[pos].flags = (default_flags & ~clear) | set;
+ nb_debug_options++;
+}
+
+/* parse a set of debugging option specifications and add them to the option list */
+static void parse_options(const char *str)
+{
+ char *opt, *next, *options;
+ unsigned int i;
+
+ if (!(options = strdup(str))) {
+ return;
+ }
+
+ for (opt = options; opt; opt = next) {
+ const char *p;
+ unsigned char set = 0, clear = 0;
+
+ if ((next = strchr( opt, ',' ))) {
+ *next++ = 0;
+ }
+
+ p = opt + strcspn( opt, "+-" );
+ if (!p[0]) {
+ p = opt; /* assume it's a debug channel name */
+ }
+
+ if (p > opt) {
+ for (i = 0; i < sizeof(debug_classes) / sizeof(debug_classes[0]); i++) {
+ int len = strlen(debug_classes[i]);
+ if (len != (p - opt)) {
+ continue;
+ }
+
+ if (!memcmp( opt, debug_classes[i], len)) { /* found it */
+ if (*p == '+') {
+ set |= 1 << i;
+ } else {
+ clear |= 1 << i;
+ }
+ break;
+ }
+ }
+
+ if (i == sizeof(debug_classes) / sizeof(debug_classes[0])) { /* bad class name, skip it */
+ continue;
+ }
+ } else {
+ if (*p == '-') {
+ clear = ~0;
+ } else {
+ set = ~0;
+ }
+ }
+
+ if (*p == '+' || *p == '-') {
+ p++;
+ }
+ if (!p[0]) {
+ continue;
+ }
+
+ if (!strcmp(p, "all")) {
+ default_flags = (default_flags & ~clear) | set;
+ } else {
+ add_option(p, set, clear);
+ }
+ }
+
+ free(options);
+}
+
+/* print the usage message */
+static void debug_usage(void)
+{
+ static const char usage[] =
+ "Syntax of the DEBUGCH variable:\n"
+ " DEBUGCH=[class]+xxx,[class]-yyy,...\n\n"
+ "Example: DEBUGCH=+all,warn-heap\n"
+ " turns on all messages except warning heap messages\n"
+ "Available message classes: err, warn, fixme, trace\n";
+ const int ret = write(2, usage, sizeof(usage) - 1);
+
+ assert(ret >= 0);
+ exit(1);
+}
+
+/* initialize all options at startup */
+static void debug_init(void)
+{
+ char *debug = NULL;
+ FILE *fp = NULL;
+ char *tmp = NULL;
+
+ if (nb_debug_options != -1) {
+ return; /* already initialized */
+ }
+
+ if (0 == strlen(bin_path)) {
+ strcpy(debugchfile, "DEBUGCH");
+ } else {
+ strcat(debugchfile, bin_path);
+ strcat(debugchfile, "DEBUGCH");
+ }
+
+ fp = fopen(debugchfile, "r");
+ if (fp == NULL) {
+ debug = getenv("DEBUGCH");
+ } else {
+ if ((tmp = (char *)malloc(1024 + 1)) == NULL){
+ fclose(fp);
+ return;
+ }
+
+ if(fseek(fp, 0, SEEK_SET) != 0) {
+ fclose(fp);
+ fprintf(stderr, "failed to fseek()\n");
+
+ if (tmp != NULL)
+ free(tmp);
+
+ return;
+ }
+ const char* str = fgets(tmp, 1024, fp);
+ if (str) {
+ tmp[strlen(tmp) - 1] = 0;
+ debug = tmp;
+ }
+
+ fclose(fp);
+ }
+
+ if (debug != NULL) {
+ if (!strcmp(debug, "help")) {
+ debug_usage();
+ }
+ parse_options(debug);
+ }
+
+ if (tmp != NULL) {
+ free(tmp);
+ }
+
+ // If "log_path" is not set, we use "stdout".
+ if (log_path[0] != '\0') {
+ fd = qemu_open(log_path, O_RDWR | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ fprintf(stderr, "Can't open logfile: %s\n", log_path);
+ exit(1);
+ return;
+ }
+ }
+ nb_debug_options = 0;
+}
+
+int dbg_log(enum _debug_class cls, struct _debug_channel *channel,
+ const char *format, ...)
+{
+ int ret = 0;
+ int ret_write = 0;
+ char buf_msg[2048];
+ va_list valist;
+
+ if (!(_dbg_get_channel_flags(channel) & (1 << cls))) {
+ return -1;
+ }
+
+ ret = snprintf(buf_msg, sizeof(buf_msg), "%s [%s:%s] ",
+ get_timeofday(), debug_classes[cls], channel->name);
+
+ va_start(valist, format);
+ ret += vsnprintf(buf_msg + ret, sizeof(buf_msg) - ret, format, valist);
+ va_end(valist);
+
+ ret_write = qemu_write_full(fd, buf_msg, ret);
+
+ return ret_write;
+
+}
--- /dev/null
+/*
+ * New debug channel
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Munkyu Im <munkyu.im@samsung.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ * refer to debug_ch.h
+ * Copyright 1999 Patrik Stridvall
+ *
+ */
+
+#ifndef __NEW_DEBUG_CH_H
+#define __NEW_DEBUG_CH_H
+
+#include <sys/types.h>
+
+// #define NO_DEBUG
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum _debug_class
+{
+ __DBCL_SEVERE,
+ __DBCL_WARNING,
+ __DBCL_INFO,
+ __DBCL_CONFIG,
+ __DBCL_FINE,
+ __DBCL_TRACE,
+
+ __DBCL_INIT = 7 /* lazy init flag */
+};
+
+struct _debug_channel
+{
+ unsigned char flags;
+ char name[15];
+};
+
+#ifndef NO_DEBUG
+#define MSGSIZE_MAX 2048
+#define __GET_DEBUGGING_SEVERE(dbch) ((dbch)->flags & (1 << __DBCL_SEVERE))
+#define __GET_DEBUGGING_WARNING(dbch) ((dbch)->flags & (1 << __DBCL_WARNING))
+#define __GET_DEBUGGING_INFO(dbch) ((dbch)->flags & (1 << __DBCL_INFO))
+#define __GET_DEBUGGING_CONFIG(dbch) ((dbch)->flags & (1 << __DBCL_CONFIG))
+#define __GET_DEBUGGING_FINE(dbch) ((dbch)->flags & (1 << __DBCL_FINE))
+#define __GET_DEBUGGING_TRACE(dbch) ((dbch)->flags & (1 << __DBCL_TRACE))
+#else
+#define __GET_DEBUGGING_SEVERE(dbch) 0
+#define __GET_DEBUGGING_WARNING(dbch) 0
+#define __GET_DEBUGGING_INFO(dbch) 0
+#define __GET_DEBUGGING_CONFIG(dbch) 0
+#define __GET_DEBUGGING_FINE(dbch) 0
+#define __GET_DEBUGGING_TRACE(dbch) 0
+#endif
+
+#define __GET_DEBUGGING(dbcl,dbch) __GET_DEBUGGING##dbcl(dbch)
+
+#define __IS_DEBUG_ON(dbcl,dbch) \
+ (__GET_DEBUGGING##dbcl(dbch) && \
+ (_dbg_get_channel_flags(dbch) & (1 << __DBCL##dbcl)))
+
+#define __DPRINTF(dbcl,dbch) \
+ do{ if(__GET_DEBUGGING(dbcl,(dbch))){ \
+ struct _debug_channel * const __dbch =(struct _debug_channel *)(dbch); \
+ const enum _debug_class __dbcl = __DBCL##dbcl; \
+ _DBG_LOG
+
+#define _DBG_LOG(args...) \
+ dbg_log(__dbcl, (struct _debug_channel *)(__dbch), args); } }while(0)
+
+extern unsigned char _dbg_get_channel_flags(struct _debug_channel *channel);
+
+extern int dbg_log(enum _debug_class cls, struct _debug_channel *ch,
+ const char *format, ...);
+
+#ifndef LOG_SEVERE
+#define LOG_SEVERE __DPRINTF(_SEVERE,&_dbch_)
+#else
+#error
+#endif
+#define IS_SEVERE_ON __IS_DEBUG_ON(_SEVERE,&_dbch_)
+
+#ifndef LOG_WARNING
+#define LOG_WARNING __DPRINTF(_WARNING,&_dbch_)
+#else
+#error
+#endif
+#define IS_WARNING_ON __IS_DEBUG_ON(_WARNING,&_dbch_)
+
+#ifndef LOG_INFO
+#define LOG_INFO __DPRINTF(_INFO,&_dbch_)
+#else
+#error
+#endif
+#define IS_INFO_ON __IS_DEBUG_ON(_INFO,&_dbch_)
+
+#ifndef LOG_CONFIG
+#define LOG_CONFIG __DPRINTF(_CONFIG,&_dbch_)
+#else
+#error
+#endif
+#define IS_CONFIG_ON __IS_DEBUG_ON(_CONFIG,&_dbch_)
+
+#ifndef LOG_FINE
+#define LOG_FINE __DPRINTF(_FINE,&_dbch_)
+#else
+#error
+#endif
+#define IS_FINE_ON __IS_DEBUG_ON(_FINE,&_dbch_)
+
+#ifndef LOG_TRACE
+#define LOG_TRACE __DPRINTF(_TRACE,&_dbch_)
+#else
+#error
+#endif
+#define IS_TRACE_ON __IS_DEBUG_ON(_TRACE,&_dbch_)
+
+#define DECLARE_DEBUG_CHANNEL(ch) \
+ static struct _debug_channel _dbch_ = { ~0, #ch };
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __NEW_DEBUG_CH_H