[Vm-dev] [commit][3046] add files to make the GdbArmPlugin unde
linux; can' t actually add them to 'cross'
because of permissions so this is best we can do for now
commits at squeakvm.org
commits at squeakvm.org
Wed Jul 16 23:23:03 UTC 2014
Revision: 3046
Author: rowledge
Date: 2014-07-16 16:23:03 -0700 (Wed, 16 Jul 2014)
Log Message:
-----------
add files to make the GdbArmPlugin unde linux; can't actually add them to 'cross' because of permissions so this is best we can do for now
Added Paths:
-----------
branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h
branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild
branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile
branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix
branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32
branches/Cog/platforms/unix/plugins/GdbARMPlugin/README
branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c
branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c
Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h 2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,74 @@
+/* heavily based on BochsIA32Plugin.h */
+/* Bochs seems to use error code 1 for execution errors.
+ * So we use > 1 for various errors
+ */
+
+/* TPR - added MemoryWriteBoundsError */
+#define NoError 0
+#define ExecutionError 1
+#define BadCPUInstance 2
+#define MemoryLoadBoundsError 3
+#define MemoryWriteBoundsError 4
+#define InstructionPrefetchError 5
+#define PanicError 6
+#define UnsupportedOperationError 7
+#define SomethingLoggedError 8
+
+// TPR - The library is compiled with TFlag, therefore, we also need to set it.
+#define MODET
+
+#if !defined(ulong)
+typedef unsigned long ulong;
+#endif
+
+extern ulong minReadAddress, minWriteAddress;
+extern int gdb_log_printf(void* stream, const char * format, ...);
+
+
+/*
+ * Answer a pointer to a new ARMulator CPU (an instance of typedef ARMul_State)
+ */
+extern void *newCPU();
+/*
+ * reset the cpu to register contents 0, protected 32-bit mode.
+ */
+extern int resetCPU(void *cpu);
+/*
+ * Single-step *cpu (an ARMul_state instance) using memory as its memory.
+ * Answer 0 on success, or an integer error code if something went awry.
+ */
+extern int singleStepCPUInSizeMinAddrReadWrite(void *cpu, void *memory,
+ ulong byteSize, ulong minReadAddr, ulong minWriteAddr);
+/*
+ * Run *cpu (an ARMul_state instance) using memory as its memory.
+ * Answer an integer error code when the processor hits some exception.
+ * Answer 0 when it is interrupted.
+ */
+extern int runCPUInSizeMinAddrReadWrite(void *cpu, void *memory,
+ ulong byteSize, ulong minReadAddr, ulong minWriteAddr);
+/*
+ * Flush any icache entries from start to end
+ */
+extern void flushICacheFromTo(void *cpu, ulong strt, ulong nd);
+/*
+ * force runCPUInSize to exit asap. Used by interrupts.
+ */
+extern void forceStopRunning();
+/*
+ * The previous entry in the interruptCheckChain so forceStopRunning can chain.
+ */
+extern void (*prevInterruptCheckChain)();
+/*
+ * Disassemble the instruction at address in memory, writing the output to the
+ * log.
+ */
+extern int disassembleForAtInSize(void *cpu, ulong laddr,
+ void *memory, ulong byteSize);
+/*
+ * The saved error if the previous singleStepIn failed.
+ */
+extern int errorAcorn();
+/*
+ * The current log (if singleStep failed with SomethingLoggedError).
+ */
+extern char *getlog(long *len);
Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild 2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,81 @@
+Building the GdbARMPlugin
+------------------------------
+
+Build the normal VM on your Platform. Consult Cog/{cygwinbuild|unixbuild|macbuild}/HowToBuild
+for additional information.
+When generating sources, update to the latest
+versions of Cog and VMMaker.oscog.
+You might want/need to change VMMaker
+class>generateSqueakCogVM to point to the right
+directories and remove FT2Plugin from the plugin-
+list (even if skipped, generates a messageNotUnderstood).
+You can also change VMMaker>plugins:do: removing
+the return in the false block, in order to skip
+when a plugin is not found, instead of aborting
+the generation process.
+
+Building on Windows
+------------------------------
+(so far tried with Windows 7 64bit unsing mingw/MSYS 32bit)
+
+Besides the normal build environment, you need the package gettext.
+Also, downgrade your mingwrt package to 3.20 (not 3.20-2) by unpacking
+the respective -dev tarball into your mingw-folder.
+
+When compiling the Squeak VM you need a version 3 gcc/g++.
+For configuration of gdb, you need a version 4 gcc (you don't need
+to switch g++). For switching between compilers in mingw,
+you may use
+ mingw-get install/remove gcc/gcc-v3/g++/gcc-v3-g++.
+
+Compile gdb/bfd and gdb/opcodes with a gcc 4.*.
+ cd <gdb>/bfd
+ ./configure --enable-targets=arm-linux
+ make
+ cd <gdb>/opcodes
+ ./configure --enable-targets=arm-linux
+ make
+Then switch to gcc-v3.
+ cd <gdb>/bfd
+ make clean && make
+ cd <gdb>/opcodes
+ make clean && make
+
+For libsim.a, the gcc version is not important.
+ cd sim/common
+ ./configure
+ cd ../arm
+ ./configure && make libsim.a
+
+Change Makefile.win32 to point to your gdb folder.
+Then copy the plugin files to your svn-checkout,
+for example changing <plugin>/Makefile and running it.
+Change <cog>/cygwinbuild/plugins.ext to include GdbARMPlugin.
+Change to gcc 3, then build the VM (again).
+
+Building on Linux
+------------------------------
+(so far tried on Ubuntu 12.04 LTS 32bit)
+
+Download the gdb sources (http://ftp.gnu.org/gnu/gdb) and
+unpack them. Change Makefile and Makefile.unix, setting
+GDBBUILDFOLDER to the correct place.
+
+Compile libopcodes.a:
+ cd GDBBUILDFOLDER
+ ./configure --enable-targets=arm-linux
+Making gdb takes quite some time. It may fail, as long as
+it generates <gdb>/bfd/bfd.h and <gdb>/opcodes/libopcodes.a.
+ make
+Compile libsim.a
+ cd sim/common
+ ./configure
+ cd ../arm
+ ./configure
+ make
+Ensure libsim.a exists in <gdb>/sim/arm.
+
+Make the plugin which just copies the plugin-files
+to the appropriate directories. Then change
+Cog/unixbuild/bld/plugins.ext to include GdbARMPlugin.
+Build the VM (again).
Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile 2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,26 @@
+# edit this to suit your system; it really ought to use relative paths
+# or some other convenience
+GDBBUILDFOLDER = /home/tim/Documents/Raspbian-Cog/gdb-arm/gdb-7.6
+
+CC = gcc
+CFLAGS = -I$(GBDBUILDFOLDER)/bfd
+LDFLAGS = $(GDBBUILDFOLDER)/sim/arm/libsim.a $(GDBBUILDFOLDER)/opcodes/libopcodes.a -lbfd -lintl -liberty -Wl,-wrap,ARMul_OSHandleSWI -L$(GDBBUILDFOLDER)/bfd/
+SHAREDLIBRARYFLAGS =
+
+all:
+# another test on linux:
+# $(CC) $(CFLAGS) armulmem.c -c -I$(GDBBUILDFOLDER)/sim/arm/ -I$(GDBBUILDFOLDER)/include/
+# $(CC) $(CFLAGS) sqGdbARMPlugin.c -c -fPIC -I$(GDBBUILDFOLDER)/sim/arm/ -I$(GDBBUILDFOLDER)/include/ -I$(GDBBUILDFOLDER)/bfd/
+# $(CC) -shared $(SHAREDLIBRARYFLAGS) -o GdbARMPlugin.dll sqGdbARMPlugin.o armulmem.o $(LDFLAGS)
+
+ mkdir -p ../cog/platforms/Cross/plugins/GdbARMPlugin
+ mkdir -p ../cog/platforms/win32/plugins/GdbARMPlugin
+ mkdir -p ../cog/platforms/unix/plugins/GdbARMPlugin
+
+ cp sqGdbARMPlugin.c GdbARMPlugin.h armulmem.c ../cog/platforms/Cross/plugins/GdbARMPlugin/
+ cp Makefile.win32 ../cog/platforms/win32/plugins/GdbARMPlugin/Makefile
+ cp Makefile.unix ../cog/platforms/unix/plugins/GdbARMPlugin/Makefile.inc
+#unix
+# cd ../cog/unixbuild/bld; make install #prefix=
+#windows
+ cd ../cog/cygwinbuild/;make
Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix 2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,12 @@
+# edit this to suit your system; it really ought to use relative paths
+# or some other convenience
+GDBBUILDFOLDER = /mnt/hgfs/tim/Documents/Squeak/Raspbian-Cog/gdb-arm/gdb-7.6
+XCFLAGS = -m32 -DNEED_UI_LOOP_HOOK
+
+XINCLUDES += -I$(GDBBUILDFOLDER)/sim/arm
+XINCLUDES := -I$(GDBBUILDFOLDER)/bfd $(XINCLUDES)
+
+XLDFLAGS= $(GDBBUILDFOLDER)/sim/arm/libsim.a \
+ $(GDBBUILDFOLDER)/opcodes/libopcodes.a \
+ -lbfd -liberty \
+ -Wl,-wrap,ARMul_OSHandleSWI
Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32 (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32 2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,13 @@
+GDBBUILDFOLDER = /d/Programming/cog/gdb
+
+LINK_WITH_GPP := yes
+EXTRALIBS:= -L$(GDBBUILDFOLDER)/opcodes \
+ -L$(GDBBUILDFOLDER)/sim/arm \
+ -lsim -lopcodes -lbfd -lintl -liberty -Wl,-wrap,ARMul_OSHandleSWI
+
+include ../../Makefile.plugin
+
+INCLUDES:= $(INCLUDES) -I$(GDBBUILDFOLDER)/sim/arm
+
+# Copy libgcc_s_dw2-1.dll, libiconv-2.dll and libintl-8.dll from your MinGW/bin
+# folder to the VM folder, to make it work on other Windows (7?) systems
Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/README
===================================================================
Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c 2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,508 @@
+/*
+ This file is a compy of armvirt.c, which is part of the ARMulator distributed e.g. with gdb and skyeye.
+ In order to overwrite GetWord and PutWord, I (lars wasserman) had to copy the whole file and alter the Make to use it instead of the default ARM armvirt.c.
+ Also changed: ReLoadInstr.
+ TPR - changed the errors returned in PutWord & GetWord to discriminate between read & write bounds errors for better simulation
+ TPR - changed Get/PutWord to ensure address used is an actual word address ie bottom two bits are zeros. Without that, fetching bytes becomes... fun
+*/
+#include "GdbARMPlugin.h"
+
+/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator.
+ Copyright (C) 1994 Advanced RISC Machines Ltd.
+
+ 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. */
+
+/* This file contains a complete ARMulator memory model, modelling a
+"virtual memory" system. A much simpler model can be found in armfast.c,
+and that model goes faster too, but has a fixed amount of memory. This
+model's memory has 64K pages, allocated on demand from a 64K entry page
+table. The routines PutWord and GetWord implement this. Pages are never
+freed as they might be needed again. A single area of memory may be
+defined to generate aborts. */
+
+#include "armopts.h"
+#include "armos.h"
+#include "armdefs.h"
+#include "ansidecl.h"
+
+#ifdef VALIDATE /* for running the validate suite */
+#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
+#define ABORTS 1
+#endif
+
+/* #define ABORTS */
+
+#ifdef ABORTS /* the memory system will abort */
+/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
+ For the new test suite Abort between 8 Mbytes and 26 Mbytes */
+/* #define LOWABORT 32 * 1024
+#define HIGHABORT 32 * 1024 * 1024 */
+#define LOWABORT 8 * 1024 * 1024
+#define HIGHABORT 26 * 1024 * 1024
+
+#endif
+
+#define NUMPAGES 64 * 1024
+#define PAGESIZE 64 * 1024
+#define PAGEBITS 16
+#define OFFSETBITS 0xffff
+
+int SWI_vector_installed = FALSE;
+
+#include <stdio.h>
+
+/***************************************************************************\
+* Get a Word from Memory *
+\***************************************************************************/
+
+static ARMword
+GetWord (ARMul_State * state, ARMword address, int check)
+{
+ if(address < minReadAddress || address + 4 > (state->MemSize))
+ {
+ //raise memory access error
+ state->EndCondition = MemoryLoadBoundsError;
+ state->Emulate = FALSE;
+ gdb_log_printf(NULL, "Illegal memory read at %#p. ", address);
+ return 0;
+ }
+ else
+ {
+ return *((ARMword*) (state->MemDataPtr + (address & ~3)));
+ }
+}
+
+/***************************************************************************\
+* Put a Word into Memory *
+\***************************************************************************/
+
+static void
+PutWord (ARMul_State * state, ARMword address, ARMword data, int check)
+{
+ if(address < minWriteAddress || address + 4 > (state->MemSize))
+ {
+ state->Emulate = FALSE;
+ state->EndCondition = MemoryWriteBoundsError;
+ gdb_log_printf(NULL, "Illegal memory write at %#p. ", address);
+ }
+ else
+ {
+ *((ARMword*) (state->MemDataPtr + (address & ~3))) = data;
+ }
+}
+
+/***************************************************************************\
+* ReLoad Instruction *
+\***************************************************************************/
+
+ARMword
+ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
+{
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT)
+ {
+ ARMul_PREFETCHABORT (address);
+ return ARMul_ABORTWORD;
+ }
+ else
+ {
+ ARMul_CLEARABORT;
+ }
+#endif
+
+ if (address < minReadAddress
+ || address >= (state->MemSize)
+ || (address >= minWriteAddress && minWriteAddress != 0))
+ {
+ // Custom SWI, defined in the wrapper of ARMul_OSHandleSWI
+ return 0xEF000000 | 0x200000;
+ // ^ SWI ^ SWI number
+ }
+
+ if ((isize == 2) && (address & 0x2))
+ {
+ /* We return the next two halfwords: */
+ ARMword lo = GetWord (state, address, FALSE);
+ ARMword hi = GetWord (state, address + 4, FALSE);
+
+ if (state->bigendSig == HIGH)
+ return (lo << 16) | (hi >> 16);
+ else
+ return ((hi & 0xFFFF) << 16) | (lo >> 16);
+ }
+
+ return GetWord (state, address, TRUE);
+}
+
+/***************************************************************************\
+* Initialise the memory interface *
+\***************************************************************************/
+
+unsigned
+ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize)
+{
+ ARMword **pagetable;
+ unsigned page;
+
+ if (initmemsize)
+ state->MemSize = initmemsize;
+
+ pagetable = (ARMword **) malloc (sizeof (ARMword *) * NUMPAGES);
+
+ if (pagetable == NULL)
+ return FALSE;
+
+ for (page = 0; page < NUMPAGES; page++)
+ *(pagetable + page) = NULL;
+
+ state->MemDataPtr = (unsigned char *) pagetable;
+
+ ARMul_ConsolePrint (state, ", 4 Gb memory");
+
+ return TRUE;
+}
+
+/***************************************************************************\
+* Remove the memory interface *
+\***************************************************************************/
+
+void
+ARMul_MemoryExit (ARMul_State * state)
+{
+ ARMword page;
+ ARMword **pagetable;
+ ARMword *pageptr;
+
+ pagetable = (ARMword **) state->MemDataPtr;
+ for (page = 0; page < NUMPAGES; page++)
+ {
+ pageptr = *(pagetable + page);
+ if (pageptr != NULL)
+ free ((char *) pageptr);
+ }
+ free ((char *) pagetable);
+ return;
+}
+
+/***************************************************************************\
+* Load Instruction, Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
+{
+ state->NumScycles++;
+
+#ifdef HOURGLASS
+ if ((state->NumScycles & HOURGLASS_RATE) == 0)
+ {
+ HOURGLASS;
+ }
+#endif
+
+ return ARMul_ReLoadInstr (state, address, isize);
+}
+
+/***************************************************************************\
+* Load Instruction, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
+{
+ state->NumNcycles++;
+
+ return ARMul_ReLoadInstr (state, address, isize);
+}
+
+/***************************************************************************\
+* Read Word (but don't tell anyone!) *
+\***************************************************************************/
+
+ARMword ARMul_ReadWord (ARMul_State * state, ARMword address)
+{
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT)
+ {
+ ARMul_DATAABORT (address);
+ return ARMul_ABORTWORD;
+ }
+ else
+ {
+ ARMul_CLEARABORT;
+ }
+#endif
+
+ return GetWord (state, address, TRUE);
+}
+
+/***************************************************************************\
+* Load Word, Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address)
+{
+ state->NumScycles++;
+
+ return ARMul_ReadWord (state, address);
+}
+
+/***************************************************************************\
+* Load Word, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address)
+{
+ state->NumNcycles++;
+
+ return ARMul_ReadWord (state, address);
+}
+
+/***************************************************************************\
+* Load Halfword, (Non Sequential Cycle) *
+\***************************************************************************/
+
+ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
+{
+ ARMword temp, offset;
+
+ state->NumNcycles++;
+
+ temp = ARMul_ReadWord (state, address);
+ offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */
+
+ return (temp >> offset) & 0xffff;
+}
+
+/***************************************************************************\
+* Read Byte (but don't tell anyone!) *
+\***************************************************************************/
+
+ARMword ARMul_ReadByte (ARMul_State * state, ARMword address)
+{
+ ARMword temp, offset;
+
+ temp = ARMul_ReadWord (state, address);
+ offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */
+
+ return (temp >> offset & 0xffL);
+}
+
+/***************************************************************************\
+* Load Byte, (Non Sequential Cycle) *
+\***************************************************************************/
+
+ARMword ARMul_LoadByte (ARMul_State * state, ARMword address)
+{
+ state->NumNcycles++;
+
+ return ARMul_ReadByte (state, address);
+}
+
+/***************************************************************************\
+* Write Word (but don't tell anyone!) *
+\***************************************************************************/
+
+void
+ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
+{
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT)
+ {
+ ARMul_DATAABORT (address);
+ return;
+ }
+ else
+ {
+ ARMul_CLEARABORT;
+ }
+#endif
+
+ PutWord (state, address, data, TRUE);
+}
+
+/***************************************************************************\
+* Store Word, Sequential Cycle *
+\***************************************************************************/
+
+void
+ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
+{
+ state->NumScycles++;
+
+ ARMul_WriteWord (state, address, data);
+}
+
+/***************************************************************************\
+* Store Word, Non Sequential Cycle *
+\***************************************************************************/
+
+void
+ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
+{
+ state->NumNcycles++;
+
+ ARMul_WriteWord (state, address, data);
+}
+
+/***************************************************************************\
+* Store HalfWord, (Non Sequential Cycle) *
+\***************************************************************************/
+
+void
+ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
+{
+ ARMword temp, offset;
+
+ state->NumNcycles++;
+
+#ifdef VALIDATE
+ if (address == TUBE)
+ {
+ if (data == 4)
+ state->Emulate = FALSE;
+ else
+ (void) putc ((char) data, stderr); /* Write Char */
+ return;
+ }
+#endif
+
+ temp = ARMul_ReadWord (state, address);
+ offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */
+
+ PutWord (state, address,
+ (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset),
+ TRUE);
+}
+
+/***************************************************************************\
+* Write Byte (but don't tell anyone!) *
+\***************************************************************************/
+
+void
+ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
+{
+ ARMword temp, offset;
+
+ temp = ARMul_ReadWord (state, address);
+ offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */
+
+ PutWord (state, address,
+ (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
+ TRUE);
+}
+
+/***************************************************************************\
+* Store Byte, (Non Sequential Cycle) *
+\***************************************************************************/
+
+void
+ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
+{
+ state->NumNcycles++;
+
+#ifdef VALIDATE
+ if (address == TUBE)
+ {
+ if (data == 4)
+ state->Emulate = FALSE;
+ else
+ (void) putc ((char) data, stderr); /* Write Char */
+ return;
+ }
+#endif
+
+ ARMul_WriteByte (state, address, data);
+}
+
+/***************************************************************************\
+* Swap Word, (Two Non Sequential Cycles) *
+\***************************************************************************/
+
+ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
+{
+ ARMword temp;
+
+ state->NumNcycles++;
+
+ temp = ARMul_ReadWord (state, address);
+
+ state->NumNcycles++;
+
+ PutWord (state, address, data, TRUE);
+
+ return temp;
+}
+
+/***************************************************************************\
+* Swap Byte, (Two Non Sequential Cycles) *
+\***************************************************************************/
+
+ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
+{
+ ARMword temp;
+
+ temp = ARMul_LoadByte (state, address);
+ ARMul_StoreByte (state, address, data);
+
+ return temp;
+}
+
+/***************************************************************************\
+* Count I Cycles *
+\***************************************************************************/
+
+void
+ARMul_Icycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
+{
+ state->NumIcycles += number;
+ ARMul_CLEARABORT;
+}
+
+/***************************************************************************\
+* Count C Cycles *
+\***************************************************************************/
+
+void
+ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
+{
+ state->NumCcycles += number;
+ ARMul_CLEARABORT;
+}
+
+
+/* Read a byte. Do not check for alignment or access errors. */
+
+ARMword
+ARMul_SafeReadByte (ARMul_State * state, ARMword address)
+{
+ ARMword temp, offset;
+
+ temp = GetWord (state, address, FALSE);
+ offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
+
+ return (temp >> offset & 0xffL);
+}
+
+void
+ARMul_SafeWriteByte (ARMul_State * state, ARMword address, ARMword data)
+{
+ ARMword temp, offset;
+
+ temp = GetWord (state, address, FALSE);
+ offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
+
+ PutWord (state, address,
+ (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
+ FALSE);
+}
Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c 2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,215 @@
+#define COG 1
+#define FOR_COG_PLUGIN 1
+
+#include "GdbARMPlugin.h"
+//disassembler
+#include <gdbconfig.h> /* TPR - <---- this is actually a *link* to the gdb gdb-7.6/bfd/config.h because it otherwise clashes with the Squeak one also in the assorted include paths. Must be a proper way to handle this case; it must happen elsewhere */
+#include <bfd.h>
+#include <dis-asm.h>
+
+#include <stdarg.h>
+
+//emulator
+#include <armdefs.h>
+#include <armemu.h>
+
+ARMul_State* lastCPU = NULL;
+
+/* When compiling armulator, it generally sets NEED_UI_LOOP_HOOK, which
+ makes the main emulation step require this symbol to be set. */
+extern int (*deprecated_ui_loop_hook) (int) = NULL;
+
+// These two variables exist, in case there are library-functions which write to a stream.
+// In that case, we would write functions which print to that stream instead of stderr or similar
+#define LOGSIZE 4096
+static char gdb_log[LOGSIZE+1];
+static int gdblog_index = 0;
+
+ulong minReadAddress, minWriteAddress;
+
+// what is that for?
+ void (*prevInterruptCheckChain)() = 0;
+
+void
+print_state(ARMul_State* state)
+{
+ printf("NextInstr: %i\ttheMemory: 0x%p\tNumInstrs: 0x%p\tPC: 0x%p\tmode: %i\tEndCondition: %i\tEmulate: %i\n",
+ state->NextInstr, state->MemDataPtr,
+ state->NumInstrs, state->Reg[15],
+ state->Mode, state->EndCondition,
+ state->Emulate);
+}
+
+void*
+newCPU()
+{
+ if(lastCPU == NULL) ARMul_EmulateInit();
+ lastCPU = ARMul_NewState();
+ ARMul_SelectProcessor (lastCPU, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
+ return lastCPU;
+}
+
+int
+resetCPU(void* cpu)
+{
+ unsigned int i, j;
+ ARMul_State* state = (ARMul_State*) cpu;
+ // test whether the supplied instance is an ARMul type?
+
+ gdblog_index = 0;
+
+ // reset registers in all modes
+ for (i = 0; i < 16; i++)
+ {
+ state->Reg[i] = 0;
+ for (j = 0; j < 7; j++)
+ state->RegBank[j][i] = 0;
+ }
+ for (i = 0; i < 7; i++)
+ state->Spsr[i] = 0;
+
+ ARMul_Reset(state);
+ return 0;
+}
+
+int
+runOnCPU(void *cpu, void *memory,
+ ulong byteSize, ulong minAddr, ulong minWriteMaxExecAddr, ARMword (*run)(ARMul_State*))
+{
+ ARMul_State* state = (ARMul_State*) cpu;
+ lastCPU = state;
+
+ // test whether the supplied instance is an ARMul type?
+ state->MemDataPtr = (unsigned char*) memory;
+ state->MemSize = byteSize;
+ minReadAddress = minAddr;
+ minWriteAddress = minWriteMaxExecAddr;
+
+ gdblog_index = 0;
+
+ state->EndCondition = NoError;
+ state->NextInstr = RESUME;
+
+ state->Reg[15] = run(state);
+
+ // collect the PSR from their dedicated flags to have easy access from the image.
+ ARMul_SetCPSR(state, ARMul_GetCPSR(state));
+
+ if(state->EndCondition != NoError){
+ return state->EndCondition;
+ }
+
+ return gdblog_index == 0 ? 0 : SomethingLoggedError;
+}
+
+int
+singleStepCPUInSizeMinAddressReadWrite(void *cpu, void *memory,
+ ulong byteSize, ulong minAddr, ulong minWriteMaxExecAddr)
+{
+ return runOnCPU(cpu, memory, byteSize, minAddr, minWriteMaxExecAddr, ARMul_DoInstr);
+}
+
+int
+runCPUInSizeMinAddressReadWrite(void *cpu, void *memory,
+ ulong byteSize, ulong minAddr, ulong minWriteMaxExecAddr)
+{
+ return runOnCPU(cpu, memory, byteSize, minAddr, minWriteMaxExecAddr, ARMul_DoProg);
+}
+
+/*
+ * Currently a dummy for ARM Processor Alien.
+ */
+void
+flushICacheFromTo(void *cpu, ulong saddr, ulong eaddr)
+{
+#if 0
+# error not yet implemented
+#endif
+}
+
+int
+gdb_log_printf(void* stream, const char * format, ...)
+{
+ va_list arg;
+ int n;
+ va_start(arg,format);
+
+ if(stream == NULL){
+ n = vsnprintf((char*) (&gdb_log) + gdblog_index, LOGSIZE-gdblog_index, format, arg);
+ gdblog_index = gdblog_index + n;
+ } else {
+ vfprintf(stream, format, arg);
+ }
+ return 0;
+}
+
+int
+disassembleForAtInSize(void *cpu, ulong laddr,
+ void *memory, ulong byteSize)
+{
+ gdblog_index = 0;
+ // ignore the cpu
+ // start disassembling at laddr relative to memory
+ // stop disassembling at memory+byteSize
+
+ disassemble_info* dis = (disassemble_info*) calloc(1, sizeof(disassemble_info));
+ // void init_disassemble_info (struct disassemble_info *dinfo, void *stream, fprintf_ftype fprintf_func)
+ init_disassemble_info ( dis, NULL, gdb_log_printf);
+
+ dis->arch = bfd_arch_arm;
+ dis->mach = bfd_mach_arm_unknown;
+
+ // sets some fields in the structure dis to architecture specific values
+ disassemble_init_for_target( dis );
+
+ dis->buffer_vma = 0;
+ dis->buffer = memory;
+ dis->buffer_length = byteSize;
+
+ // first print the address
+ gdb_log_printf( NULL, "%08lx: ", laddr);
+ //other possible functions are listed in opcodes/dissassemble.c
+ unsigned int size = print_insn_little_arm((bfd_vma) laddr, dis);
+
+ free(dis);
+ gdb_log[gdblog_index+1] = 0;
+
+ return size;
+}
+
+void
+forceStopRunning()
+{
+ lastCPU->Emulate = STOP;
+}
+
+int
+errorAcorn(void) { return 0; }
+
+char *
+getlog(long *len)
+{
+ *len = gdblog_index;
+ return gdb_log;
+}
+
+// adding custom Software Interrupts to the ARMulator
+unsigned __real_ARMul_OSHandleSWI(ARMul_State*, ARMword);
+
+unsigned
+__wrap_ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
+{
+ switch(number)
+ {
+ case 0x200000:
+ // This is the SWI number which is returned by our memory interface
+ // if there is an instruction fetch for an illegal address.
+ state->Emulate = STOP;
+ state->EndCondition = InstructionPrefetchError;
+
+ // during execution, the pc points the next fetch address, which is 8 byte after the current instruction.
+ gdb_log_printf(NULL, "Illegal Instruction fetch address (%#p).", state->Reg[15]-8);
+ return TRUE;
+ }
+ return __real_ARMul_OSHandleSWI(state, number);
+}
Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c
___________________________________________________________________
Added: svn:executable
+ *
More information about the Vm-dev
mailing list