Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-dwarf')
-rw-r--r--tests/test-dwarf/Makefile30
-rw-r--r--tests/test-dwarf/dwarf-test.sln20
-rw-r--r--tests/test-dwarf/dwarf-test.vcproj692
-rw-r--r--tests/test-dwarf/tcf/backend/backend.c565
-rw-r--r--tests/test-dwarf/tcf/backend/backend.h31
-rw-r--r--tests/test-dwarf/tcf/config.h98
-rw-r--r--tests/test-dwarf/tcf/machine/cpudefs-ext.h114
7 files changed, 1550 insertions, 0 deletions
diff --git a/tests/test-dwarf/Makefile b/tests/test-dwarf/Makefile
new file mode 100644
index 00000000..657b0729
--- /dev/null
+++ b/tests/test-dwarf/Makefile
@@ -0,0 +1,30 @@
+TCF_AGENT_DIR=../../agent
+
+include $(TCF_AGENT_DIR)/Makefile.inc
+
+override CFLAGS += $(foreach dir,$(INCDIRS),-I$(dir)) $(OPTS)
+
+HFILES := $(foreach dir,$(SRCDIRS) tcf/backend,$(wildcard $(dir)/*.h)) $(HFILES)
+CFILES := $(sort $(foreach dir,$(SRCDIRS) tcf/backend,$(wildcard $(dir)/*.c)) $(CFILES))
+
+EXECS = $(BINDIR)/dwarf-test$(EXTEXE)
+
+all: $(EXECS)
+
+$(BINDIR)/libtcf$(EXTLIB) : $(OFILES)
+ $(AR) -rc $@ $^
+ $(RANLIB)
+
+$(BINDIR)/dwarf-test$(EXTEXE): $(BINDIR)/tcf/main/main$(EXTOBJ) $(BINDIR)/libtcf$(EXTLIB)
+ $(CC) $(CFLAGS) -o $@ $(BINDIR)/tcf/main/main$(EXTOBJ) $(BINDIR)/libtcf$(EXTLIB) $(LIBS)
+
+$(BINDIR)/%$(EXTOBJ): %.c $(HFILES) Makefile
+ @$(call MKDIR,$(dir $@))
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+$(BINDIR)/%$(EXTOBJ): $(TCF_AGENT_DIR)/%.c $(HFILES) Makefile
+ @$(call MKDIR,$(dir $@))
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+clean:
+ $(call RMDIR,$(BINDIR))
diff --git a/tests/test-dwarf/dwarf-test.sln b/tests/test-dwarf/dwarf-test.sln
new file mode 100644
index 00000000..5c46eb12
--- /dev/null
+++ b/tests/test-dwarf/dwarf-test.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dwarf-test", "dwarf-test.vcproj", "{D08FED31-38A6-4239-8D20-D4276FC2BAFA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D08FED31-38A6-4239-8D20-D4276FC2BAFA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D08FED31-38A6-4239-8D20-D4276FC2BAFA}.Debug|Win32.Build.0 = Debug|Win32
+ {D08FED31-38A6-4239-8D20-D4276FC2BAFA}.Release|Win32.ActiveCfg = Release|Win32
+ {D08FED31-38A6-4239-8D20-D4276FC2BAFA}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/tests/test-dwarf/dwarf-test.vcproj b/tests/test-dwarf/dwarf-test.vcproj
new file mode 100644
index 00000000..c4217bb1
--- /dev/null
+++ b/tests/test-dwarf/dwarf-test.vcproj
@@ -0,0 +1,692 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="dwarf-test"
+ ProjectGUID="{D08FED31-38A6-4239-8D20-D4276FC2BAFA}"
+ RootNamespace="symtest"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)\obj\MSVC\$(ConfigurationName)"
+ IntermediateDirectory="$(SolutionDir)\obj\MSVC\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".;..\..\agent"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WS2_32.lib Iphlpapi.lib"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)\obj\MSVC\$(ConfigurationName)"
+ IntermediateDirectory="$(SolutionDir)\obj\MSVC\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories=".;..\..\agent"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WS2_32.lib Iphlpapi.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="framework"
+ >
+ <File
+ RelativePath="..\..\agent\tcf\framework\asyncreq.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\asyncreq.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\base64.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\base64.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\cache.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\cache.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\channel.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\channel.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\channel_pipe.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\channel_pipe.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\channel_tcp.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\channel_tcp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\context.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\context.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\cpudefs.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\cpudefs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\errors.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\errors.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\events.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\events.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\exceptions.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\exceptions.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\inputbuf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\inputbuf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\ip_ifc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\ip_ifc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\json.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\json.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\link.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\mdep.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\mdep.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\myalloc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\myalloc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\outputbuf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\outputbuf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\peer.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\peer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\plugins.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\plugins.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\protocol.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\protocol.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\proxy.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\proxy.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\signames.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\signames.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\streams.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\streams.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\tcf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\trace.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\trace.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\waitpid.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\framework\waitpid.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="main"
+ >
+ <File
+ RelativePath="..\..\agent\tcf\main\main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\main\server.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\main\server.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\main\services-ext.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\main\services.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\main\services.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="services"
+ >
+ <File
+ RelativePath="..\..\agent\tcf\services\breakpoints.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\breakpoints.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\diagnostics.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\diagnostics.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\discovery.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\discovery.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\discovery_udp.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\discovery_udp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfcache.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfcache.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfexpr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfexpr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfframe.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfframe.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfio.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfio.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfreloc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\dwarfreloc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\expressions.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\expressions.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\filesystem.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\filesystem.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\linenumbers.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\linenumbers.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\linenumbers_elf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\linenumbers_proxy.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\linenumbers_win32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\memorymap.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\memorymap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\memoryservice.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\memoryservice.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\pathmap.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\pathmap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\processes.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\processes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\registers.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\registers.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\runctrl.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\runctrl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\stacktrace.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\stacktrace.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\streamsservice.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\streamsservice.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\symbols.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\symbols.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\symbols_alloc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\symbols_elf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\symbols_proxy.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\symbols_win32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\sysmon.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\sysmon.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\tcf_elf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\tcf_elf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\terminals.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\terminals.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\vm.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\agent\tcf\services\vm.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="machine"
+ >
+ <File
+ RelativePath=".\tcf\machine\cpudefs-ext.h"
+ >
+ </File>
+ <Filter
+ Name="i386"
+ >
+ <File
+ RelativePath="..\..\agent\tcf\machine\i386\elf-mdep.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="backend"
+ >
+ <File
+ RelativePath=".\tcf\backend\backend.c"
+ >
+ </File>
+ <File
+ RelativePath=".\tcf\backend\backend.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="system"
+ >
+ <File
+ RelativePath="..\..\agent\tcf\system\Windows\pthreads-win32.c"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\tcf\config.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/tests/test-dwarf/tcf/backend/backend.c b/tests/test-dwarf/tcf/backend/backend.c
new file mode 100644
index 00000000..3b54261b
--- /dev/null
+++ b/tests/test-dwarf/tcf/backend/backend.c
@@ -0,0 +1,565 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/* Fake debug context API implementation. It used for testing symbol services. */
+
+#include <tcf/config.h>
+
+#include <sys/stat.h>
+#include <assert.h>
+#include <stdio.h>
+#if !defined(WIN32) || defined(__CYGWIN__)
+# include <dirent.h>
+#endif
+
+#include <tcf/framework/context.h>
+#include <tcf/framework/events.h>
+#include <tcf/framework/myalloc.h>
+#include <tcf/framework/exceptions.h>
+
+#include <tcf/services/tcf_elf.h>
+#include <tcf/services/symbols.h>
+#include <tcf/services/linenumbers.h>
+#include <tcf/services/memorymap.h>
+#include <tcf/services/dwarfframe.h>
+
+#include <tcf/backend/backend.h>
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+static Context * elf_ctx = NULL;
+static MemoryMap mem_map;
+static RegisterDefinition reg_defs[MAX_REGS];
+static char reg_names[MAX_REGS][32];
+static uint8_t reg_vals[MAX_REGS * 8];
+static unsigned reg_size = 0;
+
+static uint8_t frame_data[0x1000];
+static ContextAddress frame_addr = 0x40000000u;
+
+static const char * elf_file_name = NULL;
+static int mem_region_pos = 0;
+static ContextAddress pc = 0;
+static unsigned pass_cnt = 0;
+static int test_posted = 0;
+static struct timespec time_start;
+
+static char ** files = NULL;
+static unsigned files_max = 0;
+static unsigned files_cnt = 0;
+
+RegisterDefinition * get_reg_definitions(Context * ctx) {
+ return reg_defs;
+}
+
+RegisterDefinition * get_PC_definition(Context * ctx) {
+ return reg_defs;
+}
+
+Context * id2ctx(const char * id) {
+ if (id != NULL && strcmp(id, elf_ctx->id) == 0) return elf_ctx;
+ return NULL;
+}
+
+unsigned context_word_size(Context * ctx) {
+ return get_PC_definition(ctx)->size;
+}
+
+int context_has_state(Context * ctx) {
+ return 1;
+}
+
+Context * context_get_group(Context * ctx, int group) {
+ return ctx;
+}
+
+int context_read_reg(Context * ctx, RegisterDefinition * def, unsigned offs, unsigned size, void * buf) {
+ if (ctx != elf_ctx) {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ memcpy(buf, reg_vals + def->offset + offs, size);
+ return 0;
+}
+
+int context_write_reg(Context * ctx, RegisterDefinition * def, unsigned offs, unsigned size, void * buf) {
+ if (ctx != elf_ctx) {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ memcpy(reg_vals + def->offset + offs, buf, size);
+ return 0;
+}
+
+int context_read_mem(Context * ctx, ContextAddress address, void * buf, size_t size) {
+ if (address >= frame_addr && address + size >= address && address + size <= frame_addr + sizeof(frame_data)) {
+ memcpy(buf, frame_data + (address - frame_addr), size);
+ return 0;
+ }
+ memset(buf, 0, size);
+ return 0;
+}
+
+int context_write_mem(Context * ctx, ContextAddress address, void * buf, size_t size) {
+ /* TODO: context_write_mem */
+ errno = ERR_UNSUPPORTED;
+ return -1;
+}
+
+int context_get_memory_map(Context * ctx, MemoryMap * map) {
+ unsigned i;
+ for (i = 0; i < mem_map.region_cnt; i++) {
+ MemoryRegion * r = NULL;
+ if (map->region_cnt >= map->region_max) {
+ map->region_max += 8;
+ map->regions = (MemoryRegion *)loc_realloc(map->regions, sizeof(MemoryRegion) * map->region_max);
+ }
+ r = map->regions + map->region_cnt++;
+ *r = mem_map.regions[i];
+ if (r->file_name) r->file_name = loc_strdup(r->file_name);
+ if (r->sect_name) r->sect_name = loc_strdup(r->sect_name);
+ }
+ return 0;
+}
+
+int crawl_stack_frame(StackFrame * frame, StackFrame * down) {
+ if (frame->is_top_frame) {
+ frame->fp = frame_addr;
+ return 0;
+ }
+ errno = ERR_INV_ADDRESS;
+ return -1;
+}
+
+static void error(const char * func) {
+ int err = errno;
+ printf("File : %s\n", elf_file_name);
+ printf("Address : 0x%" PRIX64 "\n", (uint64_t)pc);
+ printf("Function: %s\n", func);
+ printf("Error : %s\n", errno_to_str(err));
+ fflush(stdout);
+ exit(1);
+}
+
+static void line_numbers_callback(CodeArea * area, void * args) {
+ CodeArea * dst = (CodeArea *)args;
+ *dst = *area;
+}
+
+static void print_time(struct timespec time_start, int cnt) {
+ struct timespec time_now;
+ struct timespec time_diff;
+ if (cnt == 0) return;
+ clock_gettime(CLOCK_REALTIME, &time_now);
+ time_diff.tv_sec = time_now.tv_sec - time_start.tv_sec;
+ if (time_now.tv_nsec < time_start.tv_nsec) {
+ time_diff.tv_sec--;
+ time_diff.tv_nsec = time_now.tv_nsec + 1000000000 - time_start.tv_nsec;
+ }
+ else {
+ time_diff.tv_nsec = time_now.tv_nsec - time_start.tv_nsec;
+ }
+ time_diff.tv_nsec /= cnt;
+ time_diff.tv_nsec += (long)(((uint64_t)(time_diff.tv_sec % cnt) * 1000000000) / cnt);
+ time_diff.tv_sec /= cnt;
+ printf("search time: %ld.%06ld\n", (long)time_diff.tv_sec, time_diff.tv_nsec / 1000);
+ fflush(stdout);
+}
+
+static void test(void * args);
+
+static void loc_var_func(void * args, Symbol * sym) {
+ int frame = 0;
+ Context * ctx = NULL;
+ RegisterDefinition * reg = NULL;
+ ContextAddress addr = 0;
+ ContextAddress size = 0;
+ SYM_FLAGS flags = 0;
+ int symbol_class = 0;
+ int type_class = 0;
+ Symbol * type = NULL;
+ Symbol * index_type = NULL;
+ Symbol * base_type = NULL;
+ ContextAddress length = 0;
+ int64_t lower_bound = 0;
+ void * value = NULL;
+ size_t value_size = 0;
+ int value_big_endian = 0;
+
+ if (get_symbol_flags(sym, &flags) < 0) {
+ error("get_symbol_flags");
+ }
+
+ if (get_symbol_address(sym, &addr) < 0) {
+ int err = errno;
+ if ((get_symbol_register(sym, &ctx, &frame, &reg) < 0 || reg == NULL) &&
+ (get_symbol_value(sym, &value, &value_size, &value_big_endian) < 0 || value == NULL)) {
+ if (strncmp(errno_to_str(err), "No object location info found", 29) == 0) return;
+ if (strncmp(errno_to_str(err), "Object is not available", 23) == 0) return;
+ if (strncmp(errno_to_str(err), "Object has no RT address", 24) == 0) return;
+ errno = err;
+ error("get_symbol_address");
+ }
+ }
+ if (get_symbol_size(sym, &size) < 0) {
+ error("get_symbol_size");
+ }
+ if (get_symbol_class(sym, &symbol_class) < 0) {
+ error("get_symbol_class");
+ }
+ if (get_symbol_type(sym, &type) < 0) {
+ error("get_symbol_type");
+ }
+ if (type != NULL) {
+ if (get_symbol_type_class(sym, &type_class) < 0) {
+ error("get_symbol_type_class");
+ }
+ if (get_symbol_flags(type, &flags) < 0) {
+ error("get_symbol_flags");
+ }
+ if (type_class == TYPE_CLASS_ARRAY) {
+ if (get_symbol_index_type(type, &index_type) < 0) {
+ error("get_symbol_index_type");
+ }
+ if (get_symbol_base_type(type, &base_type) < 0) {
+ error("get_symbol_base_type");
+ }
+ if (get_symbol_length(type, &length) < 0) {
+ error("get_symbol_length");
+ }
+ if (get_symbol_lower_bound(type, &lower_bound) < 0) {
+ error("get_symbol_lower_bound");
+ }
+ }
+ else if (type_class == TYPE_CLASS_POINTER) {
+ if (get_symbol_base_type(type, &base_type) < 0) {
+ error("get_symbol_base_type");
+ }
+ }
+ else if (type_class == TYPE_CLASS_ENUMERATION) {
+ int i;
+ int count = 0;
+ Symbol ** children = NULL;
+ if (get_symbol_children(type, &children, &count) < 0) {
+ error("get_symbol_children");
+ }
+ for (i = 0; i < count; i++) {
+ void * value = NULL;
+ size_t value_size = 0;
+ int big_endian = 0;
+ if (get_symbol_value(children[i], &value, &value_size, &big_endian) < 0) {
+ error("get_symbol_value");
+ }
+ }
+ }
+ }
+}
+
+static void next_pc(void) {
+ Symbol * sym = NULL;
+ CodeArea area;
+ ContextAddress lt_addr;
+ ELF_File * lt_file;
+ ELF_Section * lt_sec;
+ struct timespec time_now;
+ Trap trap;
+ int test_cnt = 0;
+ int loaded = mem_region_pos < 0;
+
+ for (;;) {
+ if (mem_region_pos < 0) {
+ mem_region_pos = 0;
+ pc = mem_map.regions[mem_region_pos].addr;
+ }
+ else if (pc + 5 < mem_map.regions[mem_region_pos].addr + mem_map.regions[mem_region_pos].size) {
+ pc += 5;
+ }
+ else if (mem_region_pos + 1 < (int)mem_map.region_cnt) {
+ mem_region_pos++;
+ pc = mem_map.regions[mem_region_pos].addr;
+ }
+ else {
+ mem_region_pos++;
+ pc = 0;
+ print_time(time_start, test_cnt);
+ return;
+ }
+
+ while ((mem_map.regions[mem_region_pos].flags & MM_FLAG_X) == 0) {
+ if (mem_region_pos + 1 < (int)mem_map.region_cnt) {
+ mem_region_pos++;
+ pc = mem_map.regions[mem_region_pos].addr;
+ }
+ else {
+ mem_region_pos++;
+ pc = 0;
+ print_time(time_start, test_cnt);
+ return;
+ }
+ }
+
+ set_regs_PC(elf_ctx, pc);
+ send_context_changed_event(elf_ctx);
+
+ if (find_symbol_by_addr(elf_ctx, STACK_NO_FRAME, pc, &sym) < 0) {
+ if (get_error_code(errno) != ERR_SYM_NOT_FOUND) {
+ error("find_symbol_by_addr");
+ }
+ }
+ else {
+ char * name = NULL;
+ char name_buf[0x1000];
+ if (get_symbol_name(sym, &name) < 0) {
+ error("get_symbol_name");
+ }
+ if (name != NULL) {
+ strcpy(name_buf, name);
+ if (find_symbol_by_name(elf_ctx, STACK_TOP_FRAME, 0, name_buf, &sym) < 0) {
+ if (get_error_code(errno) != ERR_SYM_NOT_FOUND) {
+ error("find_symbol_by_name");
+ }
+ }
+ else {
+ if (get_symbol_name(sym, &name) < 0) {
+ error("get_symbol_name");
+ }
+ if (strcmp(name_buf, name) != 0) {
+ errno = ERR_OTHER;
+ error("strcmp(name_buf, name)");
+ }
+ }
+ }
+ }
+
+ if (find_symbol_by_name(elf_ctx, STACK_TOP_FRAME, 0, "@ non existing name @", &sym) < 0) {
+ if (get_error_code(errno) != ERR_SYM_NOT_FOUND) {
+ error("find_symbol_by_name");
+ }
+ }
+
+ memset(&area, 0, sizeof(area));
+ if (address_to_line(elf_ctx, pc, pc + 1, line_numbers_callback, &area) < 0) {
+ error("address_to_line");
+ }
+ else if (area.start_line > 0) {
+ char elf_file_name[0x1000];
+ strlcpy(elf_file_name, area.file, sizeof(elf_file_name));
+ if (line_to_address(elf_ctx, elf_file_name, area.start_line, area.start_column, line_numbers_callback, &area) < 0) {
+ error("line_to_address");
+ }
+ }
+
+ if (enumerate_symbols(elf_ctx, STACK_TOP_FRAME, loc_var_func, NULL) < 0) {
+ error("enumerate_symbols");
+ }
+
+ lt_file = NULL;
+ lt_sec = NULL;
+ lt_addr = elf_map_to_link_time_address(elf_ctx, pc, &lt_file, &lt_sec);
+ assert(lt_file != NULL);
+ assert(pc == elf_map_to_run_time_address(elf_ctx, lt_file, lt_sec, lt_addr));
+ if (set_trap(&trap)) {
+ get_dwarf_stack_frame_info(elf_ctx, lt_file, lt_sec, lt_addr);
+ clear_trap(&trap);
+ }
+ else {
+ error("get_dwarf_stack_frame_info");
+ }
+
+ test_cnt++;
+ if (loaded) {
+ struct timespec time_diff;
+ clock_gettime(CLOCK_REALTIME, &time_now);
+ time_diff.tv_sec = time_now.tv_sec - time_start.tv_sec;
+ if (time_now.tv_nsec < time_start.tv_nsec) {
+ time_diff.tv_sec--;
+ time_diff.tv_nsec = time_now.tv_nsec + 1000000000 - time_start.tv_nsec;
+ }
+ else {
+ time_diff.tv_nsec = time_now.tv_nsec - time_start.tv_nsec;
+ }
+ printf("load time: %ld.%06ld\n", (long)time_diff.tv_sec, time_diff.tv_nsec / 1000);
+ fflush(stdout);
+ time_start = time_now;
+ loaded = 0;
+ }
+ else if (test_cnt >= 100000) {
+ print_time(time_start, test_cnt);
+ clock_gettime(CLOCK_REALTIME, &time_start);
+ test_posted = 1;
+ post_event(test, NULL);
+ return;
+ }
+ }
+}
+
+static void next_file(void) {
+ unsigned j;
+ ELF_File * f = NULL;
+ struct stat st;
+
+ if (pass_cnt == files_cnt) exit(0);
+ elf_file_name = files[pass_cnt % files_cnt];
+
+ printf("File: %s\n", elf_file_name);
+ fflush(stdout);
+ if (stat(elf_file_name, &st) < 0) {
+ printf("Cannot stat ELF: %s\n", errno_to_str(errno));
+ exit(1);
+ }
+
+ clock_gettime(CLOCK_REALTIME, &time_start);
+
+ f = elf_open(elf_file_name);;
+ if (f == NULL) {
+ printf("Cannot open ELF: %s\n", errno_to_str(errno));
+ exit(1);
+ }
+
+ if (elf_ctx == NULL) {
+ elf_ctx = create_context("test");
+ elf_ctx->stopped = 1;
+ elf_ctx->pending_intercept = 1;
+ elf_ctx->mem = elf_ctx;
+ elf_ctx->big_endian = f->big_endian;
+ list_add_first(&elf_ctx->ctxl, &context_root);
+ elf_ctx->ref_count++;
+ }
+
+ context_clear_memory_map(&mem_map);
+ for (j = 0; j < f->pheader_cnt; j++) {
+ MemoryRegion * r = NULL;
+ ELF_PHeader * p = f->pheaders + j;
+ if (p->type != PT_LOAD) continue;
+ if (mem_map.region_cnt >= mem_map.region_max) {
+ mem_map.region_max += 8;
+ mem_map.regions = (MemoryRegion *)loc_realloc(mem_map.regions, sizeof(MemoryRegion) * mem_map.region_max);
+ }
+ r = mem_map.regions + mem_map.region_cnt++;
+ memset(r, 0, sizeof(MemoryRegion));
+ r->addr = p->address;
+ r->file_name = loc_strdup(elf_file_name);
+ r->file_offs = p->offset;
+ r->size = p->file_size;
+ r->flags = MM_FLAG_R | MM_FLAG_W;
+ if (p->flags & PF_X) r->flags |= MM_FLAG_X;
+ r->dev = st.st_dev;
+ r->ino = st.st_ino;
+ }
+ if (mem_map.region_cnt == 0) {
+ for (j = 0; j < f->section_cnt; j++) {
+ ELF_Section * sec = f->sections + j;
+ if (sec->size == 0) continue;
+ if (sec->name == NULL) continue;
+ if (strcmp(sec->name, ".text") == 0 ||
+ strcmp(sec->name, ".data") == 0 ||
+ strcmp(sec->name, ".bss") == 0) {
+ MemoryRegion * r = NULL;
+ if (mem_map.region_cnt >= mem_map.region_max) {
+ mem_map.region_max += 8;
+ mem_map.regions = (MemoryRegion *)loc_realloc(mem_map.regions, sizeof(MemoryRegion) * mem_map.region_max);
+ }
+ r = mem_map.regions + mem_map.region_cnt++;
+ memset(r, 0, sizeof(MemoryRegion));
+ r->addr = sec->addr + 0x10000;
+ r->size = sec->size;
+ r->file_offs = sec->offset;
+ r->bss = strcmp(sec->name, ".bss") == 0;
+ r->dev = st.st_dev;
+ r->ino = st.st_ino;
+ r->file_name = loc_strdup(elf_file_name);
+ r->sect_name = loc_strdup(sec->name);
+ r->flags = MM_FLAG_R | MM_FLAG_W;
+ if (strcmp(sec->name, ".text") == 0) r->flags |= MM_FLAG_X;
+ }
+ }
+ }
+ if (mem_map.region_cnt == 0) {
+ printf("File has no program headers.\n");
+ exit(1);
+ }
+ memory_map_event_module_loaded(elf_ctx);
+ mem_region_pos = -1;
+
+ reg_size = 0;
+ memset(reg_defs, 0, sizeof(reg_defs));
+ memset(reg_vals, 0, sizeof(reg_vals));
+ for (j = 0; j < MAX_REGS - 1; j++) {
+ RegisterDefinition * r = reg_defs + j;
+ r->big_endian = f->big_endian;
+ r->dwarf_id = (int16_t)(j == 0 ? -1 : j - 1);
+ r->eh_frame_id = -1;
+ r->name = reg_names[j];
+ snprintf(reg_names[j], sizeof(reg_names[j]), "R%d", j);
+ r->offset = reg_size;
+ r->size = f->elf64 ? 8 : 4;
+ if (j == 0) r->role = "PC";
+ reg_size += r->size;
+ }
+
+ pc = 0;
+ pass_cnt++;
+
+ test_posted = 1;
+ post_event(test, NULL);
+}
+
+static void test(void * args) {
+ assert(test_posted);
+ test_posted = 0;
+ if (elf_file_name == NULL || mem_region_pos >= (int)mem_map.region_cnt) {
+ next_file();
+ }
+ else {
+ next_pc();
+ }
+}
+
+static void on_elf_file_closed(ELF_File * f) {
+ if (!test_posted) {
+ test_posted = 1;
+ post_event(test, NULL);
+ }
+}
+
+void init_contexts_sys_dep(void) {
+ const char * dir_name = "files";
+ DIR * dir = opendir(dir_name);
+ if (dir == NULL) {
+ printf("Cannot open '%s' directory\n", dir_name);
+ fflush(stdout);
+ exit(1);
+ }
+ for (;;) {
+ struct dirent * e = readdir(dir);
+ char path[FILE_PATH_SIZE];
+ struct stat st;
+ if (e == NULL) break;
+ snprintf(path, sizeof(path), "%s/%s", dir_name, e->d_name);
+ if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode)) {
+ if (files_cnt >= files_max) {
+ files_max += 8;
+ files = (char **)loc_realloc(files, files_max * sizeof(char *));
+ }
+ files[files_cnt++] = loc_strdup(path);
+ }
+ }
+ closedir(dir);
+ elf_add_close_listener(on_elf_file_closed);
+ test_posted = 1;
+ post_event(test, NULL);
+}
diff --git a/tests/test-dwarf/tcf/backend/backend.h b/tests/test-dwarf/tcf/backend/backend.h
new file mode 100644
index 00000000..f9aaa0b2
--- /dev/null
+++ b/tests/test-dwarf/tcf/backend/backend.h
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/* Fake debug context API implementation. It used for testing symbol services. */
+
+#ifndef D_backend
+#define D_backend
+
+#include <tcf/config.h>
+#include <tcf/framework/channel.h>
+
+#define MAX_REGS 2000
+
+struct RegisterData {
+ uint8_t data[MAX_REGS * 8];
+ uint8_t mask[MAX_REGS * 8];
+};
+
+#endif /* D_backend */
diff --git a/tests/test-dwarf/tcf/config.h b/tests/test-dwarf/tcf/config.h
new file mode 100644
index 00000000..144cec5c
--- /dev/null
+++ b/tests/test-dwarf/tcf/config.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * This file contains "define" statements that control agent configuration.
+ * SERVICE_* definitions control which service implementations are included into the agent.
+ */
+
+#ifndef D_config
+#define D_config
+
+#include <tcf/framework/mdep.h>
+
+#if !defined(SERVICE_Locator)
+#define SERVICE_Locator 1
+#endif
+#if !defined(SERVICE_Registers)
+#define SERVICE_Registers 1
+#endif
+#if !defined(SERVICE_Memory)
+#define SERVICE_Memory 1
+#endif
+#if !defined(SERVICE_LineNumbers)
+#define SERVICE_LineNumbers 1
+#endif
+#if !defined(SERVICE_Symbols)
+#define SERVICE_Symbols 1
+#endif
+#if !defined(SERVICE_Expressions)
+#define SERVICE_Expressions 1
+#endif
+#if !defined(SERVICE_MemoryMap)
+#define SERVICE_MemoryMap 1
+#endif
+#if !defined(SERVICE_StackTrace)
+#define SERVICE_StackTrace 1
+#endif
+
+#if !defined(ENABLE_ZeroCopy)
+#define ENABLE_ZeroCopy 1
+#endif
+
+#if !defined(ENABLE_Trace)
+# define ENABLE_Trace 1
+#endif
+
+#if !defined(ENABLE_Discovery)
+# define ENABLE_Discovery 0
+#endif
+
+#if !defined(ENABLE_ContextProxy)
+# define ENABLE_ContextProxy 1
+#endif
+
+#if !defined(ENABLE_SymbolsProxy)
+# define ENABLE_SymbolsProxy 0
+#endif
+
+#if !defined(ENABLE_LineNumbersProxy)
+# define ENABLE_LineNumbersProxy 0
+#endif
+
+#if !defined(ENABLE_Symbols)
+# define ENABLE_Symbols (ENABLE_SymbolsProxy || SERVICE_Symbols)
+#endif
+
+#if !defined(ENABLE_LineNumbers)
+# define ENABLE_LineNumbers (ENABLE_LineNumbersProxy || SERVICE_LineNumbers)
+#endif
+
+#if !defined(ENABLE_DebugContext)
+# define ENABLE_DebugContext 1
+#endif
+
+#if !defined(ENABLE_ELF)
+# define ENABLE_ELF 1
+#endif
+
+#define ENABLE_SSL 0
+#define ENABLE_Unix_Domain 0
+
+#if !defined(ENABLE_STREAM_MACROS)
+#define ENABLE_STREAM_MACROS 1
+#endif
+
+#endif /* D_config */
diff --git a/tests/test-dwarf/tcf/machine/cpudefs-ext.h b/tests/test-dwarf/tcf/machine/cpudefs-ext.h
new file mode 100644
index 00000000..18cb5704
--- /dev/null
+++ b/tests/test-dwarf/tcf/machine/cpudefs-ext.h
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+#include <tcf/backend/backend.h>
+
+static RegisterDefinition * get_reg_by_dwarf_id(unsigned id) {
+ static RegisterDefinition ** map = NULL;
+ static unsigned map_length = 0;
+
+ if (map == NULL) {
+ RegisterDefinition * r;
+ RegisterDefinition * regs_index = get_reg_definitions(NULL);
+ for (r = regs_index; r->name != NULL; r++) {
+ if (r->dwarf_id >= (int)map_length) map_length = r->dwarf_id + 1;
+ }
+ map = (RegisterDefinition **)loc_alloc_zero(sizeof(RegisterDefinition *) * map_length);
+ for (r = regs_index; r->name != NULL; r++) {
+ if (r->dwarf_id >= 0) map[r->dwarf_id] = r;
+ }
+ }
+ return id < map_length ? map[id] : NULL;
+}
+
+static RegisterDefinition * get_reg_by_eh_frame_id(unsigned id) {
+ static RegisterDefinition ** map = NULL;
+ static unsigned map_length = 0;
+
+ if (map == NULL) {
+ RegisterDefinition * r;
+ RegisterDefinition * regs_index = get_reg_definitions(NULL);
+ for (r = regs_index; r->name != NULL; r++) {
+ if (r->eh_frame_id >= (int)map_length) map_length = r->eh_frame_id + 1;
+ }
+ map = (RegisterDefinition **)loc_alloc_zero(sizeof(RegisterDefinition *) * map_length);
+ for (r = regs_index; r->name != NULL; r++) {
+ if (r->eh_frame_id >= 0) map[r->eh_frame_id] = r;
+ }
+ }
+ return id < map_length ? map[id] : NULL;
+}
+
+RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, RegisterIdScope * scope) {
+ RegisterDefinition * def = NULL;
+ switch (scope->id_type) {
+ case REGNUM_DWARF: def = get_reg_by_dwarf_id(id); break;
+ case REGNUM_EH_FRAME: def = get_reg_by_eh_frame_id(id); break;
+ }
+ if (def == NULL) set_errno(ERR_OTHER, "Invalid register ID");
+ return def;
+}
+
+int read_reg_bytes(StackFrame * frame, RegisterDefinition * reg_def, unsigned offs, unsigned size, uint8_t * buf) {
+ if (reg_def != NULL && frame != NULL) {
+ if (frame->is_top_frame) {
+ return context_read_reg(frame->ctx, reg_def, offs, size, buf);
+ }
+ if (frame->regs != NULL) {
+ size_t i;
+ uint8_t * r_addr = (uint8_t *)&frame->regs->data + reg_def->offset;
+ uint8_t * m_addr = (uint8_t *)&frame->regs->mask + reg_def->offset;
+ for (i = 0; i < size; i++) {
+ if (m_addr[offs + i] != 0xff) {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ }
+ if (offs + size > reg_def->size) {
+ errno = ERR_INV_DATA_SIZE;
+ return -1;
+ }
+ memcpy(buf, r_addr + offs, size);
+ return 0;
+ }
+ }
+ errno = ERR_INV_CONTEXT;
+ return -1;
+}
+
+int write_reg_bytes(StackFrame * frame, RegisterDefinition * reg_def, unsigned offs, unsigned size, uint8_t * buf) {
+ if (reg_def != NULL && frame != NULL) {
+ if (frame->is_top_frame) {
+ return context_write_reg(frame->ctx, reg_def, offs, size, buf);
+ }
+ if (frame->regs == NULL && context_has_state(frame->ctx)) {
+ frame->regs = (RegisterData *)loc_alloc_zero(sizeof(RegisterData));
+ }
+ if (frame->regs != NULL) {
+ uint8_t * r_addr = (uint8_t *)&frame->regs->data + reg_def->offset;
+ uint8_t * m_addr = (uint8_t *)&frame->regs->mask + reg_def->offset;
+
+ if (offs + size > reg_def->size) {
+ errno = ERR_INV_DATA_SIZE;
+ return -1;
+ }
+ memcpy(r_addr + offs, buf, size);
+ memset(m_addr + offs, 0xff, size);
+ return 0;
+ }
+ }
+ errno = ERR_INV_CONTEXT;
+ return -1;
+}

Back to the top