From 33d49eb64654fc5dc5f617ce02ae3fffb6a75adb Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 4 May 2016 09:09:28 +0200
Subject: Created special instructions for real undefined behaviors.

---
 ChangeLog                  |  17 +++
 src/arch/Makefile.am       |   1 +
 src/arch/arm/v7/arm.c      |  34 ++---
 src/arch/arm/v7/thumb_32.c |  10 +-
 src/arch/raw.c             |  12 +-
 src/arch/raw.h             |   4 +-
 src/arch/undefined.c       | 319 +++++++++++++++++++++++++++++++++++++++++++++
 src/arch/undefined.h       |  73 +++++++++++
 8 files changed, 434 insertions(+), 36 deletions(-)
 create mode 100644 src/arch/undefined.c
 create mode 100644 src/arch/undefined.h

diff --git a/ChangeLog b/ChangeLog
index 4334226..87bf638 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+16-05-04  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/arch/Makefile.am:
+	Add the 'undefined.[ch]' files to libarch_la_SOURCES.
+
+	* src/arch/arm/v7/arm.c:
+	* src/arch/arm/v7/thumb_32.c:
+	Update code.
+
+	* src/arch/raw.c:
+	* src/arch/raw.h:
+	Typo.
+
+	* src/arch/undefined.c:
+	* src/arch/undefined.h:
+	Create special instructions for real undefined behaviors.
+
 16-05-03  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/glibext/gbufferline.c:
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index 82d63c9..f7508f4 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -19,6 +19,7 @@ libarch_la_SOURCES =					\
 	register.h register.c				\
 	target.h target.c					\
 	translate.h							\
+	undefined.h undefined.c				\
 	vmpa.h vmpa.c
 
 # libarch_la_LIBADD =						\
diff --git a/src/arch/arm/v7/arm.c b/src/arch/arm/v7/arm.c
index b536770..542d521 100644
--- a/src/arch/arm/v7/arm.c
+++ b/src/arch/arm/v7/arm.c
@@ -30,6 +30,7 @@
 
 #include "opcodes/arm_opcodes.h"
 #include "opcodes/opcodes_tmp_arm.h"
+#include "../../undefined.h"
 #include "../../../common/bconst.h"
 
 
@@ -2074,8 +2075,7 @@ static GArchInstruction *process_armv7_arm_coprocessor_instructions_and_supervis
     op = (raw >> 4) & 0x1;
 
     if ((op1 & b111110) == b000000)
-        /* UNDEFINED */
-        assert(false);
+        result = g_undef_instruction_new(IBS_UNDEFINED);
 
     else if ((op1 & b110000) == b110000)
         result = armv7_read_arm_instr_svc_previously_swi(raw);
@@ -2249,23 +2249,20 @@ static GArchInstruction *process_armv7_arm_memory_hints_advanced_simd_instructio
         assert(false);
 
     else if ((op1 & b1110111) == b1000001)
-        /* (treat as NOP */
-        assert(false);
+        result = g_undef_instruction_new(IBS_NOP);
 
     else if ((op1 & b1110111) == b1000101)
         result = armv7_read_arm_instr_pli_immediate_literal(raw);
 
     else if ((op1 & b1110011) == b1000011)
-        /* UNPREDICTABLE */
-        assert(false);
+        result = g_undef_instruction_new(IBS_UNPREDICTABLE);
 
     else if ((op1 & b1110111) == b1010101)
     {
         if (rn != b1111)
             result = armv7_read_arm_instr_pld_pldw_immediate(raw);
         else
-            /* UNPREDICTABLE */
-            assert(false);
+            result = g_undef_instruction_new(IBS_UNPREDICTABLE);
 
     }
 
@@ -2279,21 +2276,18 @@ static GArchInstruction *process_armv7_arm_memory_hints_advanced_simd_instructio
     }
 
     else if (op1 == b1010011)
-        /* UNPREDICTABLE */
-        assert(false);
+        result = g_undef_instruction_new(IBS_UNPREDICTABLE);
 
     else if (op1 == b1010111)
     {
         if (op2 == b0000)
-            /* UNPREDICTABLE */
-            assert(false);
+            result = g_undef_instruction_new(IBS_UNPREDICTABLE);
 
         else if (op2 == b0001)
             result = armv7_read_arm_instr_clrex(raw);
 
         else if ((op2 & b1110) == b0010)
-            /* UNPREDICTABLE */
-            assert(false);
+            result = g_undef_instruction_new(IBS_UNPREDICTABLE);
 
         else if (op2 == b0100)
             result = armv7_read_arm_instr_dsb(raw);
@@ -2305,22 +2299,18 @@ static GArchInstruction *process_armv7_arm_memory_hints_advanced_simd_instructio
             result = armv7_read_arm_instr_isb(raw);
 
         else if (op2 == b0111)
-            /* UNPREDICTABLE */
-            assert(false);
+            result = g_undef_instruction_new(IBS_UNPREDICTABLE);
 
         else if ((op2 & b1000) == b1000)
-            /* UNPREDICTABLE */
-            assert(false);
+            result = g_undef_instruction_new(IBS_UNPREDICTABLE);
 
     }
 
     else if ((op1 & b1111011) == b1011011)
-        /* UNPREDICTABLE */
-        assert(false);
+        result = g_undef_instruction_new(IBS_UNPREDICTABLE);
 
     else if ((op1 & b1110111) == b1100001 && (op2 & b0001) == b0000)
-        /* (treat as NOP */
-        assert(false);
+        result = g_undef_instruction_new(IBS_NOP);
 
     else if ((op1 & b1110111) == b1100101 && (op2 & b0001) == b0000)
         result = armv7_read_arm_instr_pli_register(raw);
diff --git a/src/arch/arm/v7/thumb_32.c b/src/arch/arm/v7/thumb_32.c
index c1e3f3c..9dbad13 100644
--- a/src/arch/arm/v7/thumb_32.c
+++ b/src/arch/arm/v7/thumb_32.c
@@ -30,6 +30,7 @@
 
 #include "opcodes/thumb_32_opcodes.h"
 #include "opcodes/opcodes_tmp_thumb_32.h"
+#include "../../undefined.h"
 #include "../../../common/bconst.h"
 
 
@@ -177,10 +178,8 @@ GArchInstruction *process_armv7_thumb_32_instruction_set_encoding(uint32_t raw)
             else if ((op2 & b1100111) == b0000101)
                 result = process_armv7_thumb_32_load_word(raw);
 
-            /*
-            else if ((op2 & b00xx111) == b00xx111)
-                undefined;
-            */
+            else if ((op2 & b1100111) == b0000111)
+                result = g_undef_instruction_new(IBS_UNDEFINED);
 
             else if ((op2 & b1110001) == b0010000)
                 /* Advanced SIMD element or structure load/store instructions on page A7-275 */
@@ -2213,8 +2212,7 @@ static GArchInstruction *process_armv7_thumb_32_coprocessor_advanced_simd_and_fl
     op = (raw >> 4) & 0x1;
 
     if ((op1 & b111110) == b000000)
-        /* UNDEFINED */
-        assert(false);
+        result = g_undef_instruction_new(IBS_UNDEFINED);
 
     else if ((op1 & b110000) == b110000)
         /* Advanced SIMD data-processing instructions on page A7-261 */
diff --git a/src/arch/raw.c b/src/arch/raw.c
index 0dfb566..dff0c27 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -41,7 +41,7 @@
 /* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */
 
 
-/* Définition générique d'une instruction d'architecture inconnue (instance) */
+/* Définition générique d'une instruction brute d'architecture (instance) */
 struct _GRawInstruction
 {
     GArchInstruction parent;                /* A laisser en premier        */
@@ -51,7 +51,7 @@ struct _GRawInstruction
 
 };
 
-/* Définition générique d'une instruction d'architecture inconnue (classe) */
+/* Définition générique d'une instruction brute d'architecture (classe) */
 struct _GRawInstructionClass
 {
     GArchInstructionClass parent;           /* A laisser en premier        */
@@ -59,10 +59,10 @@ struct _GRawInstructionClass
 };
 
 
-/* Initialise la classe générique des opérandes. */
+/* Initialise la classe des instructions brutes d'architecture. */
 static void g_raw_instruction_class_init(GRawInstructionClass *);
 
-/* Initialise une instance d'opérande d'architecture. */
+/* Initialise une instance d'instruction brute d'architecture. */
 static void g_raw_instruction_init(GRawInstruction *);
 
 /* Supprime toutes les références externes. */
@@ -95,7 +95,7 @@ G_DEFINE_TYPE(GRawInstruction, g_raw_instruction, G_TYPE_ARCH_INSTRUCTION);
 *                                                                             *
 *  Paramètres  : klass = classe à initialiser.                                *
 *                                                                             *
-*  Description : Initialise la classe générique des opérandes.                *
+*  Description : Initialise la classe des instructions brutes d'architecture. *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -126,7 +126,7 @@ static void g_raw_instruction_class_init(GRawInstructionClass *klass)
 *                                                                             *
 *  Paramètres  : instr = instance à initialiser.                              *
 *                                                                             *
-*  Description : Initialise une instance d'instruction d'architecture.        *
+*  Description : Initialise une instance d'instruction brute d'architecture.  *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
diff --git a/src/arch/raw.h b/src/arch/raw.h
index b40b411..18205ed 100644
--- a/src/arch/raw.h
+++ b/src/arch/raw.h
@@ -42,10 +42,10 @@
 #define G_RAW_INSTRUCTION_GET_IFACE(inst)        (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_raw_instruction_get_type(), GRawInstructionIface))
 
 
-/* Définition générique d'une instruction d'architecture inconnue (instance) */
+/* Définition générique d'une instruction brute d'architecture (instance) */
 typedef struct _GRawInstruction GRawInstruction;
 
-/* Définition générique d'une instruction d'architecture inconnue (classe) */
+/* Définition générique d'une instruction brute d'architecture (classe) */
 typedef struct _GRawInstructionClass GRawInstructionClass;
 
 
diff --git a/src/arch/undefined.c b/src/arch/undefined.c
new file mode 100644
index 0000000..251f1a6
--- /dev/null
+++ b/src/arch/undefined.c
@@ -0,0 +1,319 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * undefined.c - instructions au comportement non défini
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "undefined.h"
+
+
+#include <assert.h>
+
+
+#include <i18n.h>
+
+
+#include "instruction-int.h"
+
+
+
+/* Définition générique d'une instruction au comportement non défini (instance) */
+struct _GUndefInstruction
+{
+    GArchInstruction parent;                /* A laisser en premier        */
+
+    InstrBehaviorStatus status;             /* Conséquences réelles        */
+
+};
+
+/* Définition générique d'une instruction au comportement non défini (classe) */
+struct _GUndefInstructionClass
+{
+    GArchInstructionClass parent;           /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des instructions non définies. */
+static void g_undef_instruction_class_init(GUndefInstructionClass *);
+
+/* Initialise une instance d'instruction non définie. */
+static void g_undef_instruction_init(GUndefInstruction *);
+
+/* Supprime toutes les références externes. */
+static void g_undef_instruction_dispose(GUndefInstruction *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_undef_instruction_finalize(GUndefInstruction *);
+
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static const char *g_undef_instruction_get_encoding(const GUndefInstruction *);
+
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static GBufferLine *g_undef_instruction_print(const GUndefInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
+
+/* Reconstruit le cache complet d'une désignation d'instruction. */
+static void g_undef_instruction_build_keyword(const GUndefInstruction *, AsmSyntax);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           INSTRUCTION INCONNUE / DONNEES                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une instruction au comportement non défini. */
+G_DEFINE_TYPE(GUndefInstruction, g_undef_instruction, G_TYPE_ARCH_INSTRUCTION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des instructions non définies.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_undef_instruction_class_init(GUndefInstructionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GArchInstructionClass *instr;           /* Encore une autre vision...  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_undef_instruction_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_undef_instruction_finalize;
+
+    instr = G_ARCH_INSTRUCTION_CLASS(klass);
+
+    instr->get_encoding = (get_instruction_encoding_fc)g_undef_instruction_get_encoding;
+    instr->print = (print_instruction_fc)g_undef_instruction_print;
+    instr->build_key = (build_instruction_keyword_fc)g_undef_instruction_build_keyword;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance d'instruction non définie.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_undef_instruction_init(GUndefInstruction *instr)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_undef_instruction_dispose(GUndefInstruction *instr)
+{
+    G_OBJECT_CLASS(g_undef_instruction_parent_class)->dispose(G_OBJECT(instr));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_undef_instruction_finalize(GUndefInstruction *instr)
+{
+    G_OBJECT_CLASS(g_undef_instruction_parent_class)->finalize(G_OBJECT(instr));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : status = état réel du CPU après le passage de l'instruction. *
+*                                                                             *
+*  Description : Crée une instruction au comportement nominalement indéfini.  *
+*                                                                             *
+*  Retour      : Instruction mise en place.                                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *g_undef_instruction_new(InstrBehaviorStatus status)
+{
+    GArchInstruction *result;               /* Instruction à retourner     */
+
+    result = g_object_new(G_TYPE_UNDEF_INSTRUCTION, NULL);
+
+    G_UNDEF_INSTRUCTION(result)->status = status;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instruction quelconque à consulter.                  *
+*                                                                             *
+*  Description : Indique l'encodage d'une instruction de façon détaillée.     *
+*                                                                             *
+*  Retour      : Description humaine de l'encodage utilisé.                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const char *g_undef_instruction_get_encoding(const GUndefInstruction *instr)
+{
+    const char *result;                     /* Description à retourner     */
+
+    result = _("Undefined");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr  = instruction d'assemblage à représenter.             *
+*                buffer = espace où placer ledit contenu.                     *
+*                msize   = taille idéale des positions et adresses;           *
+*                content = contenu binaire global à venir lire.               *
+*                syntax = type de représentation demandée.                    *
+*                                                                             *
+*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GBufferLine *g_undef_instruction_print(const GUndefInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax)
+{
+    GBufferLine *result;                    /* Ligne de destination        */
+    GArchInstruction *base;                 /* Version de base             */
+    const char *key;                        /* Mot clef principal          */
+    size_t klen;                            /* Taille de ce mot clef       */
+
+    base = G_ARCH_INSTRUCTION(instr);
+
+    result = g_code_buffer_prepare_new_line(buffer, &base->range);
+
+    g_buffer_line_add_flag(result, BLF_HAS_CODE);
+
+    g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, base->max_displayed_len);
+
+    /* Instruction proprement dite */
+
+    key = g_arch_instruction_get_keyword(base, syntax);
+    klen = strlen(key);
+
+    g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr  = instruction à traiter.                              *
+*                format = format du binaire manipulé.                         *
+*                syntax = type de représentation demandée.                    *
+*                                                                             *
+*  Description : Reconstruit le cache complet d'une désignation d'instruction.*
+*                                                                             *
+*  Retour      : Mot clef de bas niveau.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_undef_instruction_build_keyword(const GUndefInstruction *instr, AsmSyntax syntax)
+{
+    switch (instr->status)
+    {
+        case IBS_NOP:
+            G_ARCH_INSTRUCTION(instr)->cached_keyword = strdup("nop");
+            break;
+
+        case IBS_UNDEFINED:
+            G_ARCH_INSTRUCTION(instr)->cached_keyword = strdup("undefined");
+            break;
+
+        case IBS_UNPREDICTABLE:
+            G_ARCH_INSTRUCTION(instr)->cached_keyword = strdup("unpredictable");
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr  = instruction à consulter.                            *
+*                                                                             *
+*  Description : Indique le type de conséquences réél de l'instruction.       *
+*                                                                             *
+*  Retour      : Etat réel du CPU après l'exécution de l'instruction.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+InstrBehaviorStatus g_undef_instruction_get_status(const GUndefInstruction *instr)
+{
+    return instr->status;
+
+}
diff --git a/src/arch/undefined.h b/src/arch/undefined.h
new file mode 100644
index 0000000..5ea8120
--- /dev/null
+++ b/src/arch/undefined.h
@@ -0,0 +1,73 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * undefined.h - prototypes pour les instructions au comportement non défini
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_UNDEFINED_H
+#define _ARCH_UNDEFINED_H
+
+
+#include <glib-object.h>
+
+
+#include "instruction.h"
+#include "vmpa.h"
+
+
+
+#define G_TYPE_UNDEF_INSTRUCTION                g_undef_instruction_get_type()
+#define G_UNDEF_INSTRUCTION(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), g_undef_instruction_get_type(), GUndefInstruction))
+#define G_IS_UNDEF_INSTRUCTION(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_undef_instruction_get_type()))
+#define G_UNDEF_INSTRUCTION_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_UNDEF_INSTRUCTION, GUndefInstructionClass))
+#define G_IS_UNDEF_INSTRUCTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_UNDEF_INSTRUCTION))
+#define G_UNDEF_INSTRUCTION_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_UNDEF_INSTRUCTION, GUndefInstructionClass))
+
+
+/* Définition générique d'une instruction au comportement non défini (instance) */
+typedef struct _GUndefInstruction GUndefInstruction;
+
+/* Définition générique d'une instruction au comportement non défini (classe) */
+typedef struct _GUndefInstructionClass GUndefInstructionClass;
+
+
+/* Etat précis de l'instruction */
+typedef enum _InstrBehaviorStatus
+{
+    IBS_NOP,
+    IBS_UNDEFINED,
+    IBS_UNPREDICTABLE,
+
+
+} InstrBehaviorStatus;
+
+
+/* Indique le type défini pour une instruction au comportement non défini. */
+GType g_undef_instruction_get_type(void);
+
+/* Crée une instruction au comportement nominalement indéfini. */
+GArchInstruction *g_undef_instruction_new(InstrBehaviorStatus);
+
+/* Indique le type de conséquences réél de l'instruction. */
+InstrBehaviorStatus g_undef_instruction_get_status(const GUndefInstruction *);
+
+
+
+#endif  /* _ARCH_UNDEFINED_H */
-- 
cgit v0.11.2-87-g4458