Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2009-11-12 00:40:13 +0000
committereutarass2009-11-12 00:40:13 +0000
commit19550fa598e785d40b1e38c3299f0baa84e8bf42 (patch)
tree1e9633ba398df2734a380e3b325634aefbd1ef37
parent28522ca4e290e13668d5cd6628410c2908d3aa16 (diff)
downloadorg.eclipse.tcf.agent-19550fa598e785d40b1e38c3299f0baa84e8bf42.tar.gz
org.eclipse.tcf.agent-19550fa598e785d40b1e38c3299f0baa84e8bf42.tar.xz
org.eclipse.tcf.agent-19550fa598e785d40b1e38c3299f0baa84e8bf42.zip
TCF Agent:
1. CPU registers and stack frame basic handling is moved to a new separate module cpudefs.c 2. Architecture dependent CPU registers and stack frame definitions are moved into separate header files - cpudefs-mdep.h 3. Implemented stack unwinding using DWARF sections .debug_frame and .eh_frame 4. Changed year in copyright notices to 2009 TCF Debugger: 1. Fixed elements order in registers view. 2. Changed source level stepping logic to better support stepping over function epilogue.
-rw-r--r--agent.vcproj988
-rw-r--r--framework/context.c4
-rw-r--r--framework/context.h55
-rw-r--r--framework/cpudefs.c193
-rw-r--r--framework/cpudefs.h109
-rw-r--r--framework/errors.c14
-rw-r--r--framework/errors.h4
-rw-r--r--framework/exceptions.c6
-rw-r--r--framework/exceptions.h2
-rw-r--r--framework/ip_ifc.c2
-rw-r--r--framework/ip_ifc.h2
-rw-r--r--framework/json.c2
-rw-r--r--framework/json.h2
-rw-r--r--framework/mdep.c14
-rw-r--r--framework/mdep.h12
-rw-r--r--framework/myalloc.c2
-rw-r--r--framework/myalloc.h2
-rw-r--r--framework/peer.c2
-rw-r--r--framework/peer.h2
-rw-r--r--framework/protocol.c2
-rw-r--r--framework/protocol.h2
-rw-r--r--framework/proxy.h2
-rw-r--r--framework/streams.c2
-rw-r--r--framework/streams.h2
-rw-r--r--framework/tcf.h2
-rw-r--r--framework/trace.c2
-rw-r--r--framework/trace.h2
-rw-r--r--machine/i386/cpudefs-mdep.h2
-rw-r--r--machine/i686/cpudefs-mdep.h1
-rw-r--r--machine/x86_64/cpudefs-mdep.h328
-rw-r--r--main/cmdline.h2
-rw-r--r--main/main.c2
-rw-r--r--main/main_client.c2
-rw-r--r--main/main_lua.c2
-rw-r--r--main/main_reg.c2
-rw-r--r--main/test.c2
-rw-r--r--main/test.h2
-rw-r--r--services/breakpoints.c6
-rw-r--r--services/breakpoints.h2
-rw-r--r--services/diagnostics.c2
-rw-r--r--services/diagnostics.h2
-rw-r--r--services/discovery.h2
-rw-r--r--services/discovery_udp.c2
-rw-r--r--services/discovery_udp.h2
-rw-r--r--services/dwarf.h2
-rw-r--r--services/dwarfcache.c66
-rw-r--r--services/dwarfcache.h12
-rw-r--r--services/dwarfexpr.c434
-rw-r--r--services/dwarfframe.c554
-rw-r--r--services/dwarfframe.h49
-rw-r--r--services/dwarfio.c31
-rw-r--r--services/dwarfio.h4
-rw-r--r--services/expressions.c1
-rw-r--r--services/expressions.h2
-rw-r--r--services/filesystem.c1
-rw-r--r--services/filesystem.h2
-rw-r--r--services/linenumbers.h2
-rw-r--r--services/linenumbers_elf.c2
-rw-r--r--services/linenumbers_win32.c4
-rw-r--r--services/memoryservice.c2
-rw-r--r--services/memoryservice.h2
-rw-r--r--services/processes.c2
-rw-r--r--services/processes.h2
-rw-r--r--services/registers.c250
-rw-r--r--services/registers.h2
-rw-r--r--services/runctrl.c2
-rw-r--r--services/runctrl.h2
-rw-r--r--services/stacktrace.c388
-rw-r--r--services/stacktrace.h14
-rw-r--r--services/symbols_elf.c155
-rw-r--r--services/symbols_win32.c18
-rw-r--r--services/sysmon.c2
-rw-r--r--services/sysmon.h2
-rw-r--r--services/tcf_elf.c25
-rw-r--r--services/tcf_elf.h10
75 files changed, 2276 insertions, 1564 deletions
diff --git a/agent.vcproj b/agent.vcproj
index c140f697..256bd0ef 100644
--- a/agent.vcproj
+++ b/agent.vcproj
@@ -45,7 +45,7 @@
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories=".,framework,services,system/Windows,main"
+ AdditionalIncludeDirectories=".,framework,services,system/Windows,machine/x86_64,main"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
@@ -134,7 +134,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".,framework,services,system/Windows,main"
+ AdditionalIncludeDirectories=".,framework,services,system/Windows,machine/x86_64,main"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
RuntimeLibrary="1"
@@ -199,482 +199,530 @@
<References>
</References>
<Files>
- <File
- RelativePath=".\framework\asyncreq.c"
- >
- </File>
- <File
- RelativePath=".\framework\asyncreq.h"
- >
- </File>
- <File
- RelativePath=".\framework\base64.c"
- >
- </File>
- <File
- RelativePath=".\framework\base64.h"
- >
- </File>
- <File
- RelativePath=".\services\breakpoints.c"
- >
- </File>
- <File
- RelativePath=".\services\breakpoints.h"
- >
- </File>
- <File
- RelativePath=".\framework\channel.c"
- >
- </File>
- <File
- RelativePath=".\framework\channel.h"
- >
- </File>
- <File
- RelativePath=".\framework\channel_tcp.c"
+ <Filter
+ Name="framework"
>
- </File>
- <File
- RelativePath=".\framework\channel_tcp.h"
+ <File
+ RelativePath=".\framework\asyncreq.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\asyncreq.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\base64.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\base64.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\channel.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\channel.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\channel_tcp.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\channel_tcp.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\context.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\context.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\cpudefs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\cpudefs.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\errors.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\errors.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\events.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\events.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\exceptions.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\exceptions.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\expressions.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\expressions.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\inputbuf.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\inputbuf.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\ip_ifc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\ip_ifc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\json.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\json.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\link.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\mdep.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\mdep.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\myalloc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\myalloc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\peer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\peer.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\plugins.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\plugins.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\protocol.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\protocol.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\proxy.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\proxy.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\streams.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\streams.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\tcf.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\trace.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\trace.h"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\waitpid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\framework\waitpid.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="services"
>
- </File>
- <File
- RelativePath=".\main\cmdline.c"
+ <File
+ RelativePath=".\services\breakpoints.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\breakpoints.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\diagnostics.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\diagnostics.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\discovery.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\discovery.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\discovery_udp.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\discovery_udp.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\dwarf.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\dwarfcache.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\dwarfcache.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\dwarfexpr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\dwarfexpr.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\dwarfframe.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\dwarfframe.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\dwarfio.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\dwarfio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\filesystem.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\filesystem.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\linenumbers.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\linenumbers_elf.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\linenumbers_win32.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\memorymap.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\memorymap.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\memoryservice.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\memoryservice.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\processes.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\processes.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\registers.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\registers.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\runctrl.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\runctrl.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\stacktrace.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\stacktrace.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\streamsservice.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\streamsservice.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\symbols.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\symbols.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\symbols_elf.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\symbols_win32.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\sysmon.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\sysmon.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services\tcf_elf.c"
+ >
+ </File>
+ <File
+ RelativePath=".\services\tcf_elf.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="main"
>
- </File>
- <File
- RelativePath=".\main\cmdline.h"
+ <File
+ RelativePath=".\main\cmdline.c"
+ >
+ </File>
+ <File
+ RelativePath=".\main\cmdline.h"
+ >
+ </File>
+ <File
+ RelativePath=".\main\main.c"
+ >
+ </File>
+ <File
+ RelativePath=".\main\main_client.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\main\main_log.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\main\main_lua.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\main\main_reg.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\main\main_va.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\main\test.c"
+ >
+ </File>
+ <File
+ RelativePath=".\main\test.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="system"
>
- </File>
+ <Filter
+ Name="Windows"
+ >
+ <File
+ RelativePath=".\system\Windows\windbgcache.c"
+ >
+ </File>
+ <File
+ RelativePath=".\system\Windows\windbgcache.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="machine"
+ >
+ <Filter
+ Name="x86_64"
+ >
+ <File
+ RelativePath=".\machine\x86_64\cpudefs-mdep.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
<File
RelativePath=".\config.h"
>
</File>
- <File
- RelativePath=".\framework\context.c"
- >
- </File>
- <File
- RelativePath=".\framework\context.h"
- >
- </File>
- <File
- RelativePath=".\services\diagnostics.c"
- >
- </File>
- <File
- RelativePath=".\services\diagnostics.h"
- >
- </File>
- <File
- RelativePath=".\services\discovery.c"
- >
- </File>
- <File
- RelativePath=".\services\discovery.h"
- >
- </File>
- <File
- RelativePath=".\services\discovery_udp.c"
- >
- </File>
- <File
- RelativePath=".\services\discovery_udp.h"
- >
- </File>
- <File
- RelativePath=".\services\dwarf.h"
- >
- </File>
- <File
- RelativePath=".\services\dwarfcache.c"
- >
- </File>
- <File
- RelativePath=".\services\dwarfcache.h"
- >
- </File>
- <File
- RelativePath=".\services\dwarfexpr.c"
- >
- </File>
- <File
- RelativePath=".\services\dwarfexpr.h"
- >
- </File>
- <File
- RelativePath=".\services\dwarfio.c"
- >
- </File>
- <File
- RelativePath=".\services\dwarfio.h"
- >
- </File>
- <File
- RelativePath=".\framework\errors.c"
- >
- </File>
- <File
- RelativePath=".\framework\errors.h"
- >
- </File>
- <File
- RelativePath=".\framework\events.c"
- >
- </File>
- <File
- RelativePath=".\framework\events.h"
- >
- </File>
- <File
- RelativePath=".\framework\exceptions.c"
- >
- </File>
- <File
- RelativePath=".\framework\exceptions.h"
- >
- </File>
- <File
- RelativePath=".\services\expressions.c"
- >
- </File>
- <File
- RelativePath=".\services\expressions.h"
- >
- </File>
- <File
- RelativePath=".\services\filesystem.c"
- >
- </File>
- <File
- RelativePath=".\services\filesystem.h"
- >
- </File>
- <File
- RelativePath=".\framework\inputbuf.c"
- >
- </File>
- <File
- RelativePath=".\framework\inputbuf.h"
- >
- </File>
- <File
- RelativePath=".\framework\ip_ifc.c"
- >
- </File>
- <File
- RelativePath=".\framework\ip_ifc.h"
- >
- </File>
- <File
- RelativePath=".\framework\json.c"
- >
- </File>
- <File
- RelativePath=".\framework\json.h"
- >
- </File>
- <File
- RelativePath=".\services\linenumbers.h"
- >
- </File>
- <File
- RelativePath=".\services\linenumbers_elf.c"
- >
- </File>
- <File
- RelativePath=".\services\linenumbers_win32.c"
- >
- </File>
- <File
- RelativePath=".\framework\link.h"
- >
- </File>
- <File
- RelativePath=".\main\main.c"
- >
- </File>
- <File
- RelativePath=".\main\main_client.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\main\main_log.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\main\main_lua.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\main\main_reg.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\main\main_va.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\framework\mdep.c"
- >
- </File>
- <File
- RelativePath=".\framework\mdep.h"
- >
- </File>
- <File
- RelativePath=".\services\memorymap.c"
- >
- </File>
- <File
- RelativePath=".\services\memorymap.h"
- >
- </File>
- <File
- RelativePath=".\services\memoryservice.c"
- >
- </File>
- <File
- RelativePath=".\services\memoryservice.h"
- >
- </File>
- <File
- RelativePath=".\framework\myalloc.c"
- >
- </File>
- <File
- RelativePath=".\framework\myalloc.h"
- >
- </File>
- <File
- RelativePath=".\framework\peer.c"
- >
- </File>
- <File
- RelativePath=".\framework\peer.h"
- >
- </File>
- <File
- RelativePath=".\framework\plugins.c"
- >
- </File>
- <File
- RelativePath=".\framework\plugins.h"
- >
- </File>
- <File
- RelativePath=".\services\processes.c"
- >
- </File>
- <File
- RelativePath=".\services\processes.h"
- >
- </File>
- <File
- RelativePath=".\framework\protocol.c"
- >
- </File>
- <File
- RelativePath=".\framework\protocol.h"
- >
- </File>
- <File
- RelativePath=".\framework\proxy.c"
- >
- </File>
- <File
- RelativePath=".\framework\proxy.h"
- >
- </File>
- <File
- RelativePath=".\services\registers.c"
- >
- </File>
- <File
- RelativePath=".\services\registers.h"
- >
- </File>
- <File
- RelativePath=".\services\runctrl.c"
- >
- </File>
- <File
- RelativePath=".\services\runctrl.h"
- >
- </File>
- <File
- RelativePath=".\services\stacktrace.c"
- >
- </File>
- <File
- RelativePath=".\services\stacktrace.h"
- >
- </File>
- <File
- RelativePath=".\framework\streams.c"
- >
- </File>
- <File
- RelativePath=".\framework\streams.h"
- >
- </File>
- <File
- RelativePath=".\services\streamsservice.c"
- >
- </File>
- <File
- RelativePath=".\services\streamsservice.h"
- >
- </File>
- <File
- RelativePath=".\services\symbols.c"
- >
- </File>
- <File
- RelativePath=".\services\symbols.h"
- >
- </File>
- <File
- RelativePath=".\services\symbols_elf.c"
- >
- </File>
- <File
- RelativePath=".\services\symbols_win32.c"
- >
- </File>
- <File
- RelativePath=".\services\sysmon.c"
- >
- </File>
- <File
- RelativePath=".\services\sysmon.h"
- >
- </File>
- <File
- RelativePath=".\framework\tcf.h"
- >
- </File>
- <File
- RelativePath=".\services\tcf_elf.c"
- >
- </File>
- <File
- RelativePath=".\services\tcf_elf.h"
- >
- </File>
- <File
- RelativePath=".\main\test.c"
- >
- </File>
- <File
- RelativePath=".\main\test.h"
- >
- </File>
- <File
- RelativePath=".\framework\trace.c"
- >
- </File>
- <File
- RelativePath=".\framework\trace.h"
- >
- </File>
- <File
- RelativePath=".\framework\waitpid.c"
- >
- </File>
- <File
- RelativePath=".\framework\waitpid.h"
- >
- </File>
- <File
- RelativePath=".\system\Windows\windbgcache.c"
- >
- </File>
- <File
- RelativePath=".\system\Windows\windbgcache.h"
- >
- </File>
</Files>
<Globals>
</Globals>
diff --git a/framework/context.c b/framework/context.c
index fdc98f29..313de06e 100644
--- a/framework/context.c
+++ b/framework/context.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -990,8 +990,6 @@ int context_single_step(Context * ctx) {
#if defined(__i386__) || defined(__x86_64__)
ctx->regs.EFlags |= 0x100;
ctx->regs_dirty = 1;
-#else
-# error "context_single_step() is not implemented for CPU other then X86"
#endif
ctx->pending_step = 1;
return win32_resume(ctx);
diff --git a/framework/context.h b/framework/context.h
index 24777462..e570f430 100644
--- a/framework/context.h
+++ b/framework/context.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -20,60 +20,9 @@
#define D_context
#include "config.h"
+#include "cpudefs.h"
#include "link.h"
-typedef uintptr_t ContextAddress; /* Type to represent byted address inside context memory */
-
-#if ENABLE_DebugContext
-#if defined(WIN32) || defined(__CYGWIN__)
-
-typedef CONTEXT REG_SET;
-#define get_regs_SP(x) ((x).Esp)
-#define get_regs_BP(x) ((x).Ebp)
-#define get_regs_PC(x) ((x).Eip)
-#define set_regs_PC(x,y) (x).Eip = (y)
-
-#elif defined(_WRS_KERNEL)
-
-#include <regs.h>
-
-#elif defined(__APPLE__)
-
-#include <mach/thread_status.h>
-typedef x86_thread_state32_t REG_SET;
-#define get_regs_SP(x) ((x).__esp)
-#define get_regs_BP(x) ((x).__ebp)
-#define get_regs_PC(x) ((x).__eip)
-#define set_regs_PC(x,y) (x).__eip = (unsigned long)(y)
-
-#elif defined(__FreeBSD__) || defined(__NetBSD__)
-
-#include <machine/reg.h>
-typedef struct reg REG_SET;
-#define get_regs_SP(x) ((x).r_esp)
-#define get_regs_BP(x) ((x).r_ebp)
-#define get_regs_PC(x) ((x).r_eip)
-#define set_regs_PC(x,y) (x).r_eip = (unsigned int)(y)
-
-#else
-
-#include <sys/user.h>
-typedef struct user_regs_struct REG_SET;
-#if __WORDSIZE == 64
-# define get_regs_SP(x) ((x).rsp)
-# define get_regs_BP(x) ((x).rbp)
-# define get_regs_PC(x) ((x).rip)
-# define set_regs_PC(x,y) (x).rip = (unsigned long)(y)
-#else
-# define get_regs_SP(x) ((x).esp)
-# define get_regs_BP(x) ((x).ebp)
-# define get_regs_PC(x) ((x).eip)
-# define set_regs_PC(x,y) (x).eip = (unsigned long)(y)
-#endif
-
-#endif
-#endif /* ENABLE_DebugContext */
-
extern LINK context_root;
#define ctxl2ctxp(A) ((Context *)((char *)(A) - offsetof(Context, ctxl)))
diff --git a/framework/cpudefs.c b/framework/cpudefs.c
new file mode 100644
index 00000000..06957434
--- /dev/null
+++ b/framework/cpudefs.c
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * This module contains definitions of target CPU registers.
+ */
+
+#include "config.h"
+
+#if ENABLE_DebugContext
+
+#include <stddef.h>
+#include <stdio.h>
+#include <assert.h>
+#include "cpudefs.h"
+#include "errors.h"
+#include "context.h"
+#include "myalloc.h"
+#include "breakpoints.h"
+#include "symbols.h"
+
+#if defined(_WRS_KERNEL)
+
+/* VxWork has its own register definitions and stack crawling function */
+
+static RegisterDefinition * regs_index = NULL;
+
+RegisterDefinition * get_reg_definitions(void) {
+ if (regs_index == NULL) {
+ int cnt = 0;
+ REG_INDEX * r;
+ for (r = taskRegName; r->regName; r++) cnt++;
+ regs_index = loc_alloc_zero(sizeof(RegisterDefinition) * (cnt + 1));
+ cnt = 0;
+ for (r = taskRegName; r->regName; r++) {
+ regs_index[cnt].name = r->regName;
+ regs_index[cnt].offset = r->regOff;
+#if defined(_WRS_REG_INDEX_REGWIDTH) || (CPU_FAMILY == COLDFIRE)
+ regs_index[cnt].size = regWidth;
+#else
+ regs_index[cnt].size = 4;
+#endif
+ regs_index[cnt].dwarf_id = -1;
+ regs_index[cnt].eh_frame_id = -1;
+ cnt++;
+ }
+ }
+ return regs_index;
+}
+
+RegisterDefinition * get_PC_definition(void) {
+ static RegisterDefinition * reg_def = NULL;
+ if (reg_def == NULL) {
+ RegisterDefinition * r;
+ for (r = get_reg_definitions(); r->name != NULL; r++) {
+ if (r->offset == offsetof(REG_SET, reg_pc)) {
+ reg_def = r;
+ break;
+ }
+ }
+ }
+ return reg_def;
+}
+
+
+ContextAddress get_regs_PC_func(REG_SET * regs) {
+ return (ContextAddress)regs->reg_pc;
+}
+
+void set_regs_PC_func(REG_SET * regs, ContextAddress pc) {
+ regs->reg_pc = (void *)pc;
+}
+
+#else /* _WRS_KERNEL */
+
+#include "cpudefs-mdep.h"
+
+RegisterDefinition * get_reg_definitions(void) {
+ return regs_index;
+}
+
+#endif /* _WRS_KERNEL */
+
+RegisterDefinition * get_reg_by_dwarf_id(int id) {
+#if !ENABLE_ELF
+ return NULL;
+#else
+ static RegisterDefinition ** map = NULL;
+ static int map_length = 0;
+
+ if (map == NULL) {
+ RegisterDefinition * r;
+ for (r = get_reg_definitions(); r->name != NULL; r++) {
+ if (r->dwarf_id >= map_length) map_length = r->dwarf_id + 1;
+ }
+ map = loc_alloc_zero(sizeof(RegisterDefinition *) * map_length);
+ for (r = get_reg_definitions(); r->name != NULL; r++) {
+ if (r->dwarf_id >= 0) map[r->dwarf_id] = r;
+ }
+ }
+ return id >= 0 && id < map_length ? map[id] : NULL;
+#endif
+}
+
+RegisterDefinition * get_reg_by_eh_frame_id(int id) {
+#if !ENABLE_ELF
+ return NULL;
+#else
+ static RegisterDefinition ** map = NULL;
+ static int map_length = 0;
+
+ if (map == NULL) {
+ RegisterDefinition * r;
+ for (r = get_reg_definitions(); r->name != NULL; r++) {
+ if (r->eh_frame_id >= map_length) map_length = r->eh_frame_id + 1;
+ }
+ map = loc_alloc_zero(sizeof(RegisterDefinition *) * map_length);
+ for (r = get_reg_definitions(); r->name != NULL; r++) {
+ if (r->eh_frame_id >= 0) map[r->eh_frame_id] = r;
+ }
+ }
+ return id >= 0 && id < map_length ? map[id] : NULL;
+#endif
+}
+
+int read_reg_value(RegisterDefinition * reg_def, StackFrame * frame, uint64_t * value) {
+ if (reg_def != NULL) {
+ size_t size = reg_def->size;
+ if (size <= 8) {
+ static uint8_t ones[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ uint8_t * r_addr = (uint8_t *)&frame->regs + reg_def->offset;
+ uint8_t * m_addr = (uint8_t *)&frame->mask + reg_def->offset;
+ if (memcmp(m_addr, ones, size) == 0) {
+ if (value != NULL) {
+ switch (size) {
+ case 1: *value = *(uint8_t *)r_addr; break;
+ case 2: *value = *(uint16_t *)r_addr; break;
+ case 4: *value = *(uint32_t *)r_addr; break;
+ case 8: *value = *(uint64_t *)r_addr; break;
+ }
+ }
+ return 0;
+ }
+ }
+ else {
+ errno = ERR_INV_DATA_SIZE;
+ return -1;
+ }
+ }
+ errno = ERR_INV_CONTEXT;
+ return -1;
+}
+
+int write_reg_value(RegisterDefinition * reg_def, StackFrame * frame, uint64_t value) {
+ if (reg_def != NULL) {
+ size_t size = reg_def->size;
+ if (size <= 8) {
+ uint8_t * r_addr = (uint8_t *)&frame->regs + reg_def->offset;
+ uint8_t * m_addr = (uint8_t *)&frame->mask + reg_def->offset;
+ memset(m_addr, 0xff, size);
+ switch (size) {
+ case 1: *(uint8_t *)r_addr = (uint8_t)value; break;
+ case 2: *(uint16_t *)r_addr = (uint16_t)value; break;
+ case 4: *(uint32_t *)r_addr = (uint32_t)value; break;
+ case 8: *(uint64_t *)r_addr = (uint64_t)value; break;
+ }
+ return 0;
+ }
+ else {
+ errno = ERR_INV_DATA_SIZE;
+ return -1;
+ }
+ }
+ errno = ERR_INV_CONTEXT;
+ return -1;
+}
+
+size_t get_break_size(void) {
+ return sizeof(BREAK_INST);
+}
+
+#endif /* ENABLE_DebugContext */
diff --git a/framework/cpudefs.h b/framework/cpudefs.h
new file mode 100644
index 00000000..a45155f2
--- /dev/null
+++ b/framework/cpudefs.h
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * This module contains definitions of target CPU registers.
+ */
+
+#ifndef D_cpudefs
+#define D_cpudefs
+
+#include "config.h"
+
+typedef uintptr_t ContextAddress; /* Type to represent byte address inside context memory */
+
+#if ENABLE_DebugContext
+
+#if defined(WIN32) || defined(__CYGWIN__)
+ typedef CONTEXT REG_SET;
+#elif defined(_WRS_KERNEL)
+# include <regs.h>
+#elif defined(__APPLE__)
+# include <mach/thread_status.h>
+ typedef x86_thread_state32_t REG_SET;
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+# include <machine/reg.h>
+ typedef struct reg REG_SET;
+#else
+# include <sys/user.h>
+ typedef struct user_regs_struct REG_SET;
+#endif
+
+typedef struct RegisterDefinition {
+ char * name; /* pointer to register name */
+ int offset; /* offset to entry in REG_SET */
+ int size; /* register size in bytes */
+ int dwarf_id; /* ID of the register in DWARF sections */
+ int eh_frame_id; /* ID of the register in .eh_frame section */
+ int traceable; /* register value can be traced using .eh_frame of .debug_frame */
+} RegisterDefinition;
+
+typedef struct StackFrame {
+ int is_top_frame;
+ ContextAddress fp; /* frame address */
+ REG_SET regs; /* registers */
+ REG_SET mask; /* registers valid bits mask */
+} StackFrame;
+
+/* Return array of CPU regiter definitions. LAst item in the array has name == NULL */
+extern RegisterDefinition * get_reg_definitions(void);
+
+/* Search register definition for given DWARF register ID, return NULL if not found */
+extern RegisterDefinition * get_reg_by_dwarf_id(int id);
+
+/* Search register definition for given .eh_frame section register ID, return NULL if not found */
+extern RegisterDefinition * get_reg_by_eh_frame_id(int id);
+
+/* Return register definition of instruction pointer */
+extern RegisterDefinition * get_PC_definition(void);
+
+/* Read register value from stack frame data, return 0 on success, return -1 and set errno if register is not available */
+extern int read_reg_value(RegisterDefinition * reg_def, StackFrame * frame, uint64_t * value);
+
+/* Write register value into stack frame data, return 0 on success, return -1 and set errno if register is not available */
+extern int write_reg_value(RegisterDefinition * reg_def, StackFrame * frame, uint64_t value);
+
+/* Get instruction pointer (PC) value */
+#define get_regs_PC(x) get_regs_PC_func(&(x))
+
+/* Set instruction pointer (PC) value */
+#define set_regs_PC(x,y) set_regs_PC_func(&(x), (ContextAddress)(y))
+
+extern ContextAddress get_regs_PC_func(REG_SET * regs);
+extern void set_regs_PC_func(REG_SET * regs, ContextAddress pc);
+
+#if !defined(_WRS_KERNEL)
+extern unsigned char BREAK_INST[]; /* breakpoint instruction */
+#define BREAK_SIZE get_break_size() /* breakpoint instruction size */
+extern size_t get_break_size(void);
+#endif
+
+struct Context;
+
+/*
+ * Retrieve stack frame information by examining stack data in memory.
+ *
+ * "frame" is current frame info, it should have frame->regs and frame->mask filled with
+ * proper values before this function is called.
+ *
+ * "down" is next frame - moving from stack top to the bottom.
+ *
+ * The function uses register values in current frame to calculate frame address "frame->fp",
+ * and calculate register values in the next frame.
+ */
+extern int crawl_stack_frame(struct Context * ctx, StackFrame * frame, StackFrame * down);
+
+#endif /* ENABLE_DebugContext */
+
+#endif /* D_cpudefs */
diff --git a/framework/errors.c b/framework/errors.c
index b4ec5b87..4a80c8a4 100644
--- a/framework/errors.c
+++ b/framework/errors.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -27,7 +27,7 @@
#define ERR_SYSTEM (ERR_EXCEPTION + 1)
#define ERR_GAI (ERR_EXCEPTION + 2)
-static char * exception_msg;
+static char exception_msg[256];
static int exception_no;
static int errno_gai;
@@ -141,7 +141,7 @@ const char * errno_to_str(int err) {
case ERR_INV_TRANSPORT:
return "Invalid transport name";
case ERR_EXCEPTION:
- snprintf(buf, sizeof(buf), "%s: %s", exception_msg, errno_to_str(exception_no));
+ snprintf(buf, sizeof(buf), "%s: %s", errno_to_str(exception_no), exception_msg);
return buf;
#ifdef WIN32
case ERR_SYSTEM:
@@ -154,16 +154,18 @@ const char * errno_to_str(int err) {
}
}
-void set_exception_errno(int no, char * msg) {
+int set_exception_errno(int no, char * msg) {
assert(is_dispatch_thread());
if (msg == NULL) {
errno = no;
}
else {
errno = ERR_EXCEPTION;
- exception_no = no;
- exception_msg = msg;
+ if (no != ERR_EXCEPTION) exception_no = no;
+ strncpy(exception_msg, msg, sizeof(exception_msg) - 1);
+ exception_msg[sizeof(exception_msg) - 1] = 0;
}
+ return errno;
}
int get_exception_errno(int no) {
diff --git a/framework/errors.h b/framework/errors.h
index 9bf49041..6b6e23db 100644
--- a/framework/errors.h
+++ b/framework/errors.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -57,7 +57,7 @@
*/
extern const char * errno_to_str(int no);
-extern void set_exception_errno(int no, char * msg);
+extern int set_exception_errno(int no, char * msg);
extern int get_exception_errno(int no);
extern int set_gai_errno(int gai_error_code);
diff --git a/framework/exceptions.c b/framework/exceptions.c
index 0175a1eb..67a712fd 100644
--- a/framework/exceptions.c
+++ b/framework/exceptions.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -69,7 +69,7 @@ void exception(int error) {
error, errno_to_str(error));
exit(error);
}
- set_exception_errno(error, NULL);
+ error = set_exception_errno(error, NULL);
longjmp(chain->env, error);
}
@@ -83,7 +83,7 @@ void str_exception(int error, char * msg) {
}
strncpy(chain->msg, msg, sizeof(chain->msg) - 1);
chain->msg[sizeof(chain->msg) - 1] = 0;
- set_exception_errno(error, msg);
+ error = set_exception_errno(error, msg);
longjmp(chain->env, error);
}
diff --git a/framework/exceptions.h b/framework/exceptions.h
index 240f4929..c7b10835 100644
--- a/framework/exceptions.h
+++ b/framework/exceptions.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/ip_ifc.c b/framework/ip_ifc.c
index 9eb9adf0..b96be8d7 100644
--- a/framework/ip_ifc.c
+++ b/framework/ip_ifc.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/ip_ifc.h b/framework/ip_ifc.h
index 8d25583f..285e2e54 100644
--- a/framework/ip_ifc.h
+++ b/framework/ip_ifc.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/json.c b/framework/json.c
index c16abd5b..29489622 100644
--- a/framework/json.c
+++ b/framework/json.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/json.h b/framework/json.h
index 90501dbe..da00da73 100644
--- a/framework/json.h
+++ b/framework/json.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/mdep.c b/framework/mdep.c
index 06c5e827..7dd70362 100644
--- a/framework/mdep.c
+++ b/framework/mdep.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -720,8 +720,6 @@ ssize_t pwrite(int fd, const void * buf, size_t size, off_t offset) {
#include <shlobj.h>
-unsigned char BREAK_INST[] = { 0xcc };
-
char * get_os_name(void) {
static char str[256];
OSVERSIONINFOEX info;
@@ -837,16 +835,6 @@ void ini_mdep(void) {
# include <asm/unistd.h>
#endif
-#if defined(__i386__) || defined(__x86_64__)
-unsigned char BREAK_INST[] = { 0xcc };
-#else
-#error "Unknown CPU"
-#endif
-
-size_t get_break_size(void) {
- return sizeof(BREAK_INST);
-}
-
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
int clock_gettime(clockid_t clock_id, struct timespec * tp) {
struct timeval tv;
diff --git a/framework/mdep.h b/framework/mdep.h
index 8d79b838..dd4d4fe1 100644
--- a/framework/mdep.h
+++ b/framework/mdep.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -70,9 +70,6 @@ typedef int ssize_t;
typedef int socklen_t;
-extern unsigned char BREAK_INST[]; /* breakpoint instruction */
-#define BREAK_SIZE 1 /* breakpoint instruction size */
-
#if defined(__CYGWIN__)
#ifndef _LARGEFILE_SOURCE
@@ -291,9 +288,6 @@ extern char * canonicalize_file_name(const char * path);
#define environ taskIdCurrent->ppEnviron
-#define get_regs_PC(x) (*(int *)((int)&(x) + PC_OFFSET))
-#define set_regs_PC(x,y) *(int *)((int)&(x) + PC_OFFSET) = (int)(y)
-
#define closesocket close
typedef unsigned long uintptr_t;
@@ -378,10 +372,6 @@ extern int tkill(pid_t pid, int signal);
#define closesocket close
-extern unsigned char BREAK_INST[]; /* breakpoint instruction */
-#define BREAK_SIZE get_break_size() /* breakpoint instruction size */
-extern size_t get_break_size(void);
-
#endif
extern pthread_attr_t pthread_create_attr;
diff --git a/framework/myalloc.c b/framework/myalloc.c
index a67a2118..960130b3 100644
--- a/framework/myalloc.c
+++ b/framework/myalloc.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/myalloc.h b/framework/myalloc.h
index 33f28157..43d1d217 100644
--- a/framework/myalloc.h
+++ b/framework/myalloc.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/peer.c b/framework/peer.c
index f5ea35b0..9d308c22 100644
--- a/framework/peer.c
+++ b/framework/peer.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/peer.h b/framework/peer.h
index 25a6c5f9..4f4c7a8d 100644
--- a/framework/peer.h
+++ b/framework/peer.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/protocol.c b/framework/protocol.c
index bbd6a62b..5659fea3 100644
--- a/framework/protocol.c
+++ b/framework/protocol.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/protocol.h b/framework/protocol.h
index 0962f588..eb80bbcf 100644
--- a/framework/protocol.h
+++ b/framework/protocol.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/proxy.h b/framework/proxy.h
index d4e60cdf..3a35c7a2 100644
--- a/framework/proxy.h
+++ b/framework/proxy.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/streams.c b/framework/streams.c
index 116c4317..acc5986f 100644
--- a/framework/streams.c
+++ b/framework/streams.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/streams.h b/framework/streams.h
index a97dfbb3..f8ba09dc 100644
--- a/framework/streams.h
+++ b/framework/streams.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/tcf.h b/framework/tcf.h
index 7047084b..522714f0 100644
--- a/framework/tcf.h
+++ b/framework/tcf.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/trace.c b/framework/trace.c
index 81963225..abc15012 100644
--- a/framework/trace.c
+++ b/framework/trace.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/framework/trace.h b/framework/trace.h
index 59e20d00..e0556aba 100644
--- a/framework/trace.h
+++ b/framework/trace.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/machine/i386/cpudefs-mdep.h b/machine/i386/cpudefs-mdep.h
new file mode 100644
index 00000000..1636f8de
--- /dev/null
+++ b/machine/i386/cpudefs-mdep.h
@@ -0,0 +1,2 @@
+#include "machine/x86_64/cpudefs-mdep.h"
+
diff --git a/machine/i686/cpudefs-mdep.h b/machine/i686/cpudefs-mdep.h
new file mode 100644
index 00000000..ebebb103
--- /dev/null
+++ b/machine/i686/cpudefs-mdep.h
@@ -0,0 +1 @@
+#include "machine/x86_64/cpudefs-mdep.h"
diff --git a/machine/x86_64/cpudefs-mdep.h b/machine/x86_64/cpudefs-mdep.h
new file mode 100644
index 00000000..99277f5e
--- /dev/null
+++ b/machine/x86_64/cpudefs-mdep.h
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * This module provides CPU specific definitions for X86.
+ */
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#define REG_OFFSET(name) offsetof(REG_SET, name)
+
+RegisterDefinition regs_index[] = {
+#if defined(WIN32) && defined(__i386__)
+ { "eax", REG_OFFSET(Eax), 4, 0, 0, 0},
+ { "ecx", REG_OFFSET(Ecx), 4, 1, 1, 0},
+ { "edx", REG_OFFSET(Edx), 4, 2, 2, 0},
+ { "ebx", REG_OFFSET(Ebx), 4, 3, 3, 0},
+ { "esp", REG_OFFSET(Esp), 4, 4, 4, 1},
+ { "ebp", REG_OFFSET(Ebp), 4, 5, 5, 1},
+ { "esi", REG_OFFSET(Esi), 4, 6, 6, 0},
+ { "edi", REG_OFFSET(Edi), 4, 7, 7, 0},
+ { "eip", REG_OFFSET(Eip), 4, 8, 8, 1},
+ { "eflags", REG_OFFSET(EFlags), 4, 9, 9, 0},
+ { "cs", REG_OFFSET(SegCs), 4, -1, -1, 0},
+ { "ss", REG_OFFSET(SegSs), 4, -1, -1, 0},
+#elif defined(__APPLE__) && defined(__i386__)
+ { "eax", REG_OFFSET(__eax), 4, 0, 0, 0},
+ { "ecx", REG_OFFSET(__ecx), 4, 1, 1, 0},
+ { "edx", REG_OFFSET(__edx), 4, 2, 2, 0},
+ { "ebx", REG_OFFSET(__ebx), 4, 3, 3, 0},
+ { "esp", REG_OFFSET(__esp), 4, 4, 4, 1},
+ { "ebp", REG_OFFSET(__ebp), 4, 5, 5, 1},
+ { "esi", REG_OFFSET(__esi), 4, 6, 6, 0},
+ { "edi", REG_OFFSET(__edi), 4, 7, 7, 0},
+ { "eip", REG_OFFSET(__eip), 4, 8, 8, 1},
+ { "eflags", REG_OFFSET(__eflags), 4, 9, 9, 0},
+#elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__)
+ { "eax", REG_OFFSET(r_eax), 4, 0, 0, 0},
+ { "ecx", REG_OFFSET(r_ecx), 4, 1, 1, 0},
+ { "edx", REG_OFFSET(r_edx), 4, 2, 2, 0},
+ { "ebx", REG_OFFSET(r_ebx), 4, 3, 3, 0},
+ { "esp", REG_OFFSET(r_esp), 4, 4, 4, 1},
+ { "ebp", REG_OFFSET(r_ebp), 4, 5, 5, 1},
+ { "esi", REG_OFFSET(r_esi), 4, 6, 6, 0},
+ { "edi", REG_OFFSET(r_edi), 4, 7, 7, 0},
+ { "eip", REG_OFFSET(r_eip), 4, 8, 8, 1},
+ { "eflags", REG_OFFSET(r_eflags), 4, 9, 9, 0},
+#elif defined(__x86_64__)
+ { "rax", REG_OFFSET(rax), 8, 0, 0, 0},
+ { "rdx", REG_OFFSET(rdx), 8, 1, 1, 0},
+ { "rcx", REG_OFFSET(rcx), 8, 2, 2, 0},
+ { "rbx", REG_OFFSET(rbx), 8, 3, 3, 0},
+ { "rsi", REG_OFFSET(rsi), 8, 4, 4, 0},
+ { "rdi", REG_OFFSET(rdi), 8, 5, 5, 0},
+ { "rbp", REG_OFFSET(rbp), 8, 6, 6, 1},
+ { "rsp", REG_OFFSET(rsp), 8, 7, 7, 1},
+ { "r8", REG_OFFSET(r8), 8, 8, 8, 0},
+ { "r9", REG_OFFSET(r9), 8, 9, 9, 0},
+ { "r10", REG_OFFSET(r10), 8, 10, 10, 0},
+ { "r11", REG_OFFSET(r11), 8, 11, 11, 0},
+ { "r12", REG_OFFSET(r12), 8, 12, 12, 0},
+ { "r13", REG_OFFSET(r13), 8, 13, 13, 0},
+ { "r14", REG_OFFSET(r14), 8, 14, 14, 0},
+ { "r15", REG_OFFSET(r15), 8, 15, 15, 0},
+ { "rip", REG_OFFSET(rip), 8, -1, -1, 1},
+ { "eflags", REG_OFFSET(eflags), 4, 49, -1, 0},
+ { "es", REG_OFFSET(es), 4, 50, -1, 0},
+ { "cs", REG_OFFSET(cs), 4, 51, -1, 0},
+ { "ss", REG_OFFSET(ss), 4, 52, -1, 0},
+ { "ds", REG_OFFSET(ds), 4, 53, -1, 0},
+ { "fs", REG_OFFSET(fs), 4, 54, -1, 0},
+ { "gs", REG_OFFSET(gs), 4, 55, -1, 0},
+ { "fs_base", REG_OFFSET(fs_base), 4, 58, -1, 0},
+ { "gs_base", REG_OFFSET(gs_base), 4, 59, -1, 0},
+#elif defined(__i386__)
+ { "eax", REG_OFFSET(eax), 4, 0, 0, 0},
+ { "ecx", REG_OFFSET(ecx), 4, 1, 1, 0},
+ { "edx", REG_OFFSET(edx), 4, 2, 2, 0},
+ { "ebx", REG_OFFSET(ebx), 4, 3, 3, 0},
+ { "esp", REG_OFFSET(esp), 4, 4, 4, 1},
+ { "ebp", REG_OFFSET(ebp), 4, 5, 5, 1},
+ { "esi", REG_OFFSET(esi), 4, 6, 6, 0},
+ { "edi", REG_OFFSET(edi), 4, 7, 7, 0},
+ { "eip", REG_OFFSET(eip), 4, 8, 8, 1},
+ { "eflags", REG_OFFSET(eflags), 4, 9, 9, 0},
+#else
+# error "Unknown CPU"
+#endif
+ { NULL, 0, 0, 0, 0, 0},
+};
+
+static int read_mem(Context * ctx, ContextAddress address, void * buf, size_t size) {
+ if (context_read_mem(ctx, address, buf, size) < 0) return -1;
+ check_breakpoints_on_memory_read(ctx, address, buf, size);
+ return 0;
+}
+
+#if defined(WIN32) || defined(__CYGWIN__)
+# define REG_SP Esp
+# define REG_BP Ebp
+# define REG_IP Eip
+#elif defined(__APPLE__)
+# define REG_SP __esp
+# define REG_BP __ebp
+# define REG_IP __eip
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+# define REG_SP r_esp
+# define REG_BP r_ebp
+# define REG_IP r_eip
+#elif defined(__x86_64__)
+# define REG_SP rsp
+# define REG_BP rbp
+# define REG_IP rip
+#else
+# define REG_SP esp
+# define REG_BP ebp
+# define REG_IP eip
+#endif
+
+#define JMPD08 0xeb
+#define JMPD32 0xe9
+#define GRP5 0xff
+#define JMPN 0x25
+#define PUSH_EBP 0x55
+#define MOV_ESP00 0x89
+#define MOV_ESP01 0xe5
+#define MOV_ESP10 0x8b
+#define MOV_ESP11 0xec
+#define ENTER 0xc8
+#define RET 0xc3
+#define RETADD 0xc2
+#define REXW 0x48
+
+/*
+ * trace_jump - resolve any JMP instructions to final destination
+ *
+ * This routine returns a pointer to the next non-JMP instruction to be
+ * executed if the PC were at the specified <adrs>. That is, if the instruction
+ * at <adrs> is not a JMP, then <adrs> is returned. Otherwise, if the
+ * instruction at <adrs> is a JMP, then the destination of the JMP is
+ * computed, which then becomes the new <adrs> which is tested as before.
+ * Thus we will eventually return the address of the first non-JMP instruction
+ * to be executed.
+ *
+ * The need for this arises because compilers may put JMPs to instructions
+ * that we are interested in, instead of the instruction itself. For example,
+ * optimizers may replace a stack pop with a JMP to a stack pop. Or in very
+ * UNoptimized code, the first instruction of a subroutine may be a JMP to
+ * a PUSH %EBP MOV %ESP %EBP, instead of a PUSH %EBP MOV %ESP %EBP (compiler
+ * may omit routine "post-amble" at end of parsing the routine!). We call
+ * this routine anytime we are looking for a specific kind of instruction,
+ * to help handle such cases.
+ *
+ * RETURNS: The address that a chain of branches points to.
+ */
+static ContextAddress trace_jump(Context * ctx, ContextAddress addr) {
+ int cnt = 0;
+ /* while instruction is a JMP, get destination adrs */
+ while (cnt < 100) {
+ unsigned char instr; /* instruction opcode at <addr> */
+ ContextAddress dest; /* Jump destination address */
+ if (read_mem(ctx, addr, &instr, 1) < 0) break;
+
+ /* If instruction is a JMP, get destination adrs */
+ if (instr == JMPD08) {
+ signed char disp08;
+ if (read_mem(ctx, addr + 1, &disp08, 1) < 0) break;
+ dest = addr + 2 + disp08;
+ }
+ else if (instr == JMPD32) {
+ int disp32;
+ assert(sizeof(disp32) == 4);
+ if (read_mem(ctx, addr + 1, &disp32, 4) < 0) break;
+ dest = addr + 5 + disp32;
+ }
+ else if (instr == GRP5) {
+ ContextAddress ptr;
+ if (read_mem(ctx, addr + 1, &instr, 1) < 0) break;
+ if (instr != JMPN) break;
+ if (read_mem(ctx, addr + 2, &ptr, sizeof(ptr)) < 0) break;
+ if (read_mem(ctx, ptr, &dest, sizeof(dest)) < 0) break;
+ }
+ else {
+ break;
+ }
+ if (dest == addr) break;
+ addr = dest;
+ cnt++;
+ }
+ return addr;
+}
+
+static int func_entry(unsigned char * code) {
+ if (*code != PUSH_EBP) return 0;
+ code++;
+ if (*code == REXW) code++;
+ if (code[0] == MOV_ESP00 && code[1] == MOV_ESP01) return 1;
+ if (code[0] == MOV_ESP10 && code[1] == MOV_ESP11) return 1;
+ return 0;
+}
+
+int crawl_stack_frame(Context * ctx, StackFrame * frame, StackFrame * down) {
+ ContextAddress reg_ip = frame->regs.REG_IP;
+ ContextAddress reg_sp = frame->regs.REG_SP;
+ ContextAddress reg_bp = frame->regs.REG_BP;
+
+ ContextAddress dwn_ip = 0;
+ ContextAddress dwn_sp = 0;
+ ContextAddress dwn_bp = 0;
+
+ if (frame->mask.REG_IP != ~(ContextAddress)0) return 0;
+ if (frame->mask.REG_SP != ~(ContextAddress)0) return 0;
+ if (frame->mask.REG_BP != ~(ContextAddress)0) return 0;
+
+ if (frame->is_top_frame) {
+ /* Top frame */
+ ContextAddress addr = trace_jump(ctx, reg_ip);
+ ContextAddress plt = is_plt_section(ctx, addr);
+
+ /*
+ * we don't have a stack frame in a few restricted but useful cases:
+ * 1) we are at a PUSH %EBP MOV %ESP %EBP or RET or ENTER instruction,
+ * 2) we are the first instruction of a subroutine (this may NOT be
+ * a PUSH %EBP MOV %ESP %EBP instruction with some compilers)
+ * 3) we are inside PLT entry
+ */
+ if (plt) {
+ /* TODO: support for large code model PLT */
+ if (addr - plt == 0) {
+ dwn_sp = reg_sp + sizeof(ContextAddress) * 2;
+ }
+ else if (addr - plt < 16) {
+ dwn_sp = reg_sp + sizeof(ContextAddress) * 3;
+ }
+ else if ((addr - plt - 16) % 16 < 11) {
+ dwn_sp = reg_sp + sizeof(ContextAddress);
+ }
+ else {
+ dwn_sp = reg_sp + sizeof(ContextAddress) * 2;
+ }
+ dwn_bp = reg_bp;
+ }
+ else {
+ unsigned char code[5];
+
+ if (read_mem(ctx, addr - 1, code, sizeof(code)) < 0) return -1;
+
+ if (func_entry(code + 1) || code[1] == ENTER || code[1] == RET || code[1] == RETADD) {
+ dwn_sp = reg_sp + sizeof(ContextAddress);
+ dwn_bp = reg_bp;
+ }
+ else if (func_entry(code)) {
+ dwn_sp = reg_sp + sizeof(ContextAddress) * 2;
+ dwn_bp = reg_bp;
+ }
+ else {
+ dwn_sp = reg_bp + sizeof(ContextAddress) * 2;
+ if (read_mem(ctx, reg_bp, &dwn_bp, sizeof(ContextAddress)) < 0) dwn_bp = 0;
+ }
+ }
+ }
+ else {
+ dwn_sp = reg_bp + sizeof(ContextAddress) * 2;
+ if (read_mem(ctx, reg_bp, &dwn_bp, sizeof(ContextAddress)) < 0) dwn_bp = 0;
+ }
+
+ if (read_mem(ctx, dwn_sp - sizeof(ContextAddress), &dwn_ip, sizeof(ContextAddress)) < 0) dwn_ip = 0;
+
+ if (dwn_bp < reg_sp) dwn_bp = 0;
+
+ if (dwn_sp != 0) {
+ down->regs.REG_SP = dwn_sp;
+ down->mask.REG_SP = ~(ContextAddress)0;
+ }
+ if (dwn_bp != 0) {
+ down->regs.REG_BP = dwn_bp;
+ down->mask.REG_BP = ~(ContextAddress)0;
+ }
+ if (dwn_ip != 0) {
+ down->regs.REG_IP = dwn_ip;
+ down->mask.REG_IP = ~(ContextAddress)0;
+ }
+
+ frame->fp = dwn_sp;
+
+ return 0;
+}
+
+RegisterDefinition * get_PC_definition(void) {
+ static RegisterDefinition * reg_def = NULL;
+ if (reg_def == NULL) {
+ RegisterDefinition * r;
+ for (r = get_reg_definitions(); r->name != NULL; r++) {
+ if (r->offset == offsetof(REG_SET, REG_IP)) {
+ reg_def = r;
+ break;
+ }
+ }
+ }
+ return reg_def;
+}
+
+ContextAddress get_regs_PC_func(REG_SET * regs) {
+ return regs->REG_IP;
+}
+
+void set_regs_PC_func(REG_SET * regs, ContextAddress pc) {
+ regs->REG_IP = pc;
+}
+
+unsigned char BREAK_INST[] = { 0xcc };
+
+#else
+
+# error "Unknown CPU"
+
+#endif
diff --git a/main/cmdline.h b/main/cmdline.h
index e2125d2d..04391af3 100644
--- a/main/cmdline.h
+++ b/main/cmdline.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/main/main.c b/main/main.c
index 9b6af230..c039f638 100644
--- a/main/main.c
+++ b/main/main.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/main/main_client.c b/main/main_client.c
index a5e781cd..674c914e 100644
--- a/main/main_client.c
+++ b/main/main_client.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/main/main_lua.c b/main/main_lua.c
index 04e15e1a..d2ecdf9b 100644
--- a/main/main_lua.c
+++ b/main/main_lua.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/main/main_reg.c b/main/main_reg.c
index e00af83c..9fc568c7 100644
--- a/main/main_reg.c
+++ b/main/main_reg.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/main/test.c b/main/test.c
index 1d0092f9..c18e14b3 100644
--- a/main/test.c
+++ b/main/test.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/main/test.h b/main/test.h
index 9e80f06e..991713b6 100644
--- a/main/test.h
+++ b/main/test.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/breakpoints.c b/services/breakpoints.c
index ca7ccd66..2ec7def2 100644
--- a/services/breakpoints.c
+++ b/services/breakpoints.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -309,7 +309,7 @@ void check_breakpoints_on_memory_read(Context * ctx, ContextAddress address, voi
if (bi->ctx->mem != ctx->mem) continue;
if (bi->address + BREAK_SIZE <= address) continue;
if (bi->address >= address + size) continue;
- for (i = 0; i < BREAK_SIZE; i++) {
+ for (i = 0; i < (int)BREAK_SIZE; i++) {
if (bi->address + i < address) continue;
if (bi->address + i >= address + size) continue;
buf[bi->address + i - address] = bi->saved_code[i];
@@ -330,7 +330,7 @@ void check_breakpoints_on_memory_write(Context * ctx, ContextAddress address, vo
if (bi->ctx->mem != ctx->mem) continue;
if (bi->address + BREAK_SIZE <= address) continue;
if (bi->address >= address + size) continue;
- for (i = 0; i < BREAK_SIZE; i++) {
+ for (i = 0; i < (int)BREAK_SIZE; i++) {
if (bi->address + i < address) continue;
if (bi->address + i >= address + size) continue;
bi->saved_code[i] = buf[bi->address + i - address];
diff --git a/services/breakpoints.h b/services/breakpoints.h
index 92f1c681..ed58bf81 100644
--- a/services/breakpoints.h
+++ b/services/breakpoints.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/diagnostics.c b/services/diagnostics.c
index e8745073..c24e35ed 100644
--- a/services/diagnostics.c
+++ b/services/diagnostics.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/diagnostics.h b/services/diagnostics.h
index dd7dcbd6..dbb8f043 100644
--- a/services/diagnostics.h
+++ b/services/diagnostics.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/discovery.h b/services/discovery.h
index c58d3194..4e2c6708 100644
--- a/services/discovery.h
+++ b/services/discovery.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/discovery_udp.c b/services/discovery_udp.c
index 53e4928b..b6df6333 100644
--- a/services/discovery_udp.c
+++ b/services/discovery_udp.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/discovery_udp.h b/services/discovery_udp.h
index ec4fdb97..48fdb5a4 100644
--- a/services/discovery_udp.h
+++ b/services/discovery_udp.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/dwarf.h b/services/dwarf.h
index f6de8f7f..284af029 100644
--- a/services/dwarf.h
+++ b/services/dwarf.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1996, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 1996, 2009 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.
diff --git a/services/dwarfcache.c b/services/dwarfcache.c
index 9b13393e..570dfd89 100644
--- a/services/dwarfcache.c
+++ b/services/dwarfcache.c
@@ -23,7 +23,6 @@
#if ENABLE_ELF
#include <assert.h>
-#include <stdio.h>
#include "dwarf.h"
#include "dwarfio.h"
#include "dwarfcache.h"
@@ -52,7 +51,8 @@ unsigned calc_symbol_name_hash(char * s) {
while (*s) {
unsigned g;
h = (h << 4) + *s++;
- if (g = h & 0xf0000000) h ^= g >> 24;
+ g = h & 0xf0000000;
+ if (g) h ^= g >> 24;
h &= ~g;
}
return h % SYM_HASH_SIZE;
@@ -119,9 +119,9 @@ static void read_mod_fund_type(U2_T Form, ObjectInfo ** Type) {
size_t BufPos;
dio_ChkBlock(Form, &Buf, &BufSize);
*Type = find_object_info(sDebugSection->addr + dio_GetPos() - 1);
- (*Type)->mTag = TAG_lo_user;
+ (*Type)->mTag = TAG_fund_type;
(*Type)->mCompUnit = sCompUnit;
- (*Type)->mEncoding = Buf[BufSize - 1];
+ (*Type)->mFundType = Buf[BufSize - 1];
BufPos = BufSize - 1;
while (BufPos > 0) {
U2_T Tag = 0;
@@ -198,11 +198,11 @@ static void read_tag_com_unit(U2_T Attr, U2_T Form) {
break;
case AT_low_pc:
dio_ChkAddr(Form);
- Unit->mLowPC = (ContextAddress)dio_gFormRef;
+ Unit->mLowPC = (ContextAddress)dio_gFormData;
break;
case AT_high_pc:
dio_ChkAddr(Form);
- Unit->mHighPC = (ContextAddress)dio_gFormRef;
+ Unit->mHighPC = (ContextAddress)dio_gFormData;
break;
case AT_ranges:
dio_ChkData(Form);
@@ -221,7 +221,7 @@ static void read_tag_com_unit(U2_T Attr, U2_T Form) {
Unit->mLineInfoOffs = dio_gFormData;
break;
case AT_base_types:
- Unit->mBaseTypes = find_comp_unit(dio_gFormRef);
+ Unit->mBaseTypes = find_comp_unit(dio_gFormData);
break;
}
}
@@ -260,22 +260,22 @@ static void read_object_attributes(U2_T Tag, U2_T Attr, U2_T Form) {
break;
case AT_sibling:
dio_ChkRef(Form);
- Sibling = dio_gFormRef - sDebugSection->addr;
+ Sibling = dio_gFormData - sDebugSection->addr;
break;
case AT_type:
dio_ChkRef(Form);
- Info->mType = find_object_info(dio_gFormRef);
+ Info->mType = find_object_info(dio_gFormData);
break;
case AT_fund_type:
dio_ChkData(Form);
Info->mType = find_object_info(sDebugSection->addr + dio_GetPos() - dio_gFormDataSize);
- Info->mType->mTag = TAG_lo_user;
+ Info->mType->mTag = TAG_fund_type;
Info->mCompUnit = sCompUnit;
- Info->mType->mEncoding = (U2_T)dio_gFormData;
+ Info->mType->mFundType = (U2_T)dio_gFormData;
break;
case AT_user_def_type:
dio_ChkRef(Form);
- Info->mType = find_object_info(dio_gFormRef);
+ Info->mType = find_object_info(dio_gFormData);
break;
case AT_mod_fund_type:
read_mod_fund_type(Form, &Info->mType);
@@ -283,18 +283,6 @@ static void read_object_attributes(U2_T Tag, U2_T Attr, U2_T Form) {
case AT_mod_u_d_type:
read_mod_user_def_type(Form, &Info->mType);
break;
- case AT_encoding:
- dio_ChkData(Form);
- Info->mEncoding = (U2_T)dio_gFormData;
- break;
- case AT_low_pc:
- dio_ChkAddr(Form);
- Info->mLowPC = (ContextAddress)dio_gFormRef;
- break;
- case AT_high_pc:
- dio_ChkAddr(Form);
- Info->mHighPC = (ContextAddress)dio_gFormRef;
- break;
case AT_name:
dio_ChkString(Form);
Info->mName = dio_gFormDataAddr;
@@ -450,6 +438,12 @@ static void load_debug_sections(void) {
else if (strcmp(sec->name, ".debug_loc") == 0) {
sCache->mDebugLoc = sec;
}
+ else if (strcmp(sec->name, ".debug_frame") == 0) {
+ sCache->mDebugFrame = sec;
+ }
+ else if (strcmp(sec->name, ".eh_frame") == 0) {
+ sCache->mEHFrame = sec;
+ }
}
if (sObjectList == NULL) {
@@ -466,7 +460,6 @@ static void load_debug_sections(void) {
static U2_T gop_gAttr = 0;
static U2_T gop_gForm = 0;
-static U8_T gop_gFormRef = 0; /* Absolute address */
static U8_T gop_gFormData = 0;
static size_t gop_gFormDataSize = 0;
static void * gop_gFormDataAddr = NULL;
@@ -474,7 +467,6 @@ static void * gop_gFormDataAddr = NULL;
static void get_object_property_callback(U2_T Tag, U2_T Attr, U2_T Form) {
if (Attr != gop_gAttr) return;
gop_gForm = Form;
- gop_gFormRef = dio_gFormRef;
gop_gFormData = dio_gFormData;
gop_gFormDataSize = dio_gFormDataSize;
gop_gFormDataAddr = dio_gFormDataAddr;
@@ -499,24 +491,25 @@ U8_T get_numeric_property_value(PropertyValue * Value) {
int read_dwarf_object_property(Context * Ctx, int Frame, ObjectInfo * Obj, int Attr, PropertyValue * Value) {
Trap trap;
+ if (Obj->mTag == TAG_fund_type) {
+ /* TAG_fund_type is virtual DWARF object that is created by DWARF reader. It has no properties. */
+ errno = ERR_SYM_NOT_FOUND;
+ return -1;
+ }
+
memset(Value, 0, sizeof(PropertyValue));
Value->mContext = Ctx;
Value->mFrame = Frame;
Value->mObject = Obj;
- Value->mAttr = Attr;
+ Value->mAttr = (U2_T)Attr;
Value->mBigEndian = Obj->mCompUnit->mFile->big_endian;
- if (Attr == AT_location && Obj->mLowPC != 0) {
- Value->mValue = Obj->mLowPC;
- return 0;
- }
-
sCompUnit = Obj->mCompUnit;
sCache = (DWARFCache *)sCompUnit->mFile->dwarf_dt_cache;
sDebugSection = sCompUnit->mSection;
dio_EnterDebugSection(&sCompUnit->mDesc, sDebugSection, Obj->mID - sDebugSection->addr);
if (set_trap(&trap)) {
- gop_gAttr = Attr;
+ gop_gAttr = (U2_T)Attr;
gop_gForm = 0;
dio_ReadEntry(get_object_property_callback);
clear_trap(&trap);
@@ -536,7 +529,7 @@ int read_dwarf_object_property(Context * Ctx, int Frame, ObjectInfo * Obj, int A
case FORM_REF8 :
case FORM_REF_UDATA :
{
- ObjectInfo * RefObj = find_object(sCache, gop_gFormRef);
+ ObjectInfo * RefObj = find_object(sCache, gop_gFormData);
PropertyValue ValueAddr;
if (read_and_evaluate_dwarf_object_property(Ctx, Frame, 0, RefObj, AT_location, &ValueAddr) < 0) return -1;
@@ -577,10 +570,11 @@ int read_dwarf_object_property(Context * Ctx, int Frame, ObjectInfo * Obj, int A
break;
case FORM_SDATA :
case FORM_UDATA :
+ case FORM_ADDR:
Value->mValue = gop_gFormData;
break;
default:
- errno = ENOENT;
+ errno = ERR_SYM_NOT_FOUND;
return -1;
}
return 0;
@@ -850,7 +844,7 @@ void load_line_numbers(DWARFCache * Cache, CompUnit * Unit) {
state.mFile = dio_ReadULEB128();
break;
case DW_LNS_set_column:
- state.mColumn = dio_ReadULEB128();
+ state.mColumn = (U2_T)dio_ReadULEB128();
break;
case DW_LNS_negate_stmt:
state.mFlags ^= LINE_IsStmt;
diff --git a/services/dwarfcache.h b/services/dwarfcache.h
index 7b5f4db8..d173a9fd 100644
--- a/services/dwarfcache.h
+++ b/services/dwarfcache.h
@@ -30,6 +30,7 @@
#include "context.h"
#include "tcf_elf.h"
#include "dwarfio.h"
+#include "stacktrace.h"
typedef struct FileInfo FileInfo;
typedef struct LocationInfo LocationInfo;
@@ -62,6 +63,8 @@ struct SymbolSection {
unsigned * mHashNext;
};
+#define TAG_fund_type 0x2000
+
struct ObjectInfo {
ObjectInfo * mHashNext;
ObjectInfo * mListNext;
@@ -69,13 +72,10 @@ struct ObjectInfo {
ObjectInfo * mChildren;
ObjectInfo * mParent;
- U2_T mTag;
U8_T mID;
+ U2_T mTag;
- ContextAddress mLowPC;
- ContextAddress mHighPC;
-
- U2_T mEncoding;
+ U2_T mFundType;
ObjectInfo * mType;
CompUnit * mCompUnit;
char * mName;
@@ -153,6 +153,8 @@ struct DWARFCache {
ELF_Section * mDebugARanges;
ELF_Section * mDebugLine;
ELF_Section * mDebugLoc;
+ ELF_Section * mDebugFrame;
+ ELF_Section * mEHFrame;
SymbolSection ** mSymSections;
unsigned mSymSectionsCnt;
unsigned mSymSectionsLen;
diff --git a/services/dwarfexpr.c b/services/dwarfexpr.c
index 36442207..ab2b8335 100644
--- a/services/dwarfexpr.c
+++ b/services/dwarfexpr.c
@@ -37,7 +37,7 @@ static unsigned sExprStackLen = 0;
static unsigned sExprStackMax = 0;
static int sKeepStack = 0;
-#define check_e_stack(n) if (sExprStackLen < n) { errno = ERR_INV_DWARF; return -1; }
+#define check_e_stack(n) if (sExprStackLen < n) { errno = set_exception_errno(ERR_INV_DWARF, "invalid DWARF expression stack"); return -1; }
static ObjectInfo * get_parent_function(ObjectInfo * Info) {
while (Info != NULL) {
@@ -54,391 +54,36 @@ static ObjectInfo * get_parent_function(ObjectInfo * Info) {
}
static int get_register(Context * Ctx, int Frame, unsigned rg, U8_T * value) {
-#if !ENABLE_DebugContext
-#elif defined(__linux__) && defined(__i386__) || \
- defined(_WRS_KERNEL) && (CPU_FAMILY==SIMNT || CPU_FAMILY==I80X86)
- ContextAddress IP, FP;
- if (is_top_frame(Ctx, Frame)) {
- switch (rg) {
- case 0:
- *value = (ContextAddress)Ctx->regs.eax;
- return 0;
- case 1:
- *value = (ContextAddress)Ctx->regs.ecx;
- return 0;
- case 2:
- *value = (ContextAddress)Ctx->regs.edx;
- return 0;
- case 3:
- *value = (ContextAddress)Ctx->regs.ebx;
- return 0;
- case 4:
- *value = (ContextAddress)Ctx->regs.esp;
- return 0;
- case 5:
- *value = (ContextAddress)Ctx->regs.ebp;
- return 0;
- case 6:
- *value = (ContextAddress)Ctx->regs.esi;
- return 0;
- case 7:
- *value = (ContextAddress)Ctx->regs.edi;
- return 0;
- case 8:
-#ifdef _WRS_KERNEL
- *value = (ContextAddress)Ctx->regs.pc;
-#else
- *value = (ContextAddress)Ctx->regs.eip;
-#endif
- return 0;
- case 9:
- *value = (ContextAddress)Ctx->regs.eflags;
- return 0;
- }
- }
- if (get_frame_info(Ctx, Frame, &IP, NULL, &FP) < 0) return -1;
- switch (rg) {
- case 5:
- *value = FP;
- return 0;
- case 8:
- *value = IP;
- return 0;
- }
-#elif defined(__linux__) && defined(__x86_64__)
- ContextAddress RA, FP;
- if (is_top_frame(Ctx, Frame)) {
- switch (rg) {
- case 0:
- *value = Ctx->regs.rax;
- return 0;
- case 1:
- *value = Ctx->regs.rbx;
- return 0;
- case 2:
- *value = Ctx->regs.rcx;
- return 0;
- case 3:
- *value = Ctx->regs.rdx;
- return 0;
- case 4:
- *value = Ctx->regs.rsi;
- return 0;
- case 5:
- *value = Ctx->regs.rdi;
- return 0;
- case 6:
- *value = Ctx->regs.rbp;
- return 0;
- case 7:
- *value = Ctx->regs.rsp;
- return 0;
- case 8:
- *value = Ctx->regs.r8;
- return 0;
- case 9:
- *value = Ctx->regs.r9;
- return 0;
- case 10:
- *value = Ctx->regs.r10;
- return 0;
- case 11:
- *value = Ctx->regs.r11;
- return 0;
- case 12:
- *value = Ctx->regs.r11;
- return 0;
- case 13:
- *value = Ctx->regs.r13;
- return 0;
- case 14:
- *value = Ctx->regs.r14;
- return 0;
- case 15:
- *value = Ctx->regs.r15;
- return 0;
- case 16:
- if (get_frame_info(Ctx, Frame, NULL, &RA, NULL) < 0) return -1;
- *value = RA;
- return 0;
- }
- }
- if (get_frame_info(Ctx, Frame, NULL, &RA, &FP) < 0) return -1;
- switch (rg) {
- case 6:
- *value = FP;
- return 0;
- case 16:
- *value = RA;
- return 0;
- }
-#elif defined(__APPLE__) && defined(__i386__)
- ContextAddress IP, FP;
- if (is_top_frame(Ctx, Frame)) {
- switch (rg) {
- case 0:
- *value = (ContextAddress)Ctx->regs.__eax;
- return 0;
- case 1:
- *value = (ContextAddress)Ctx->regs.__ecx;
- return 0;
- case 2:
- *value = (ContextAddress)Ctx->regs.__edx;
- return 0;
- case 3:
- *value = (ContextAddress)Ctx->regs.__ebx;
- return 0;
- case 4:
- *value = (ContextAddress)Ctx->regs.__esp;
- return 0;
- case 5:
- *value = (ContextAddress)Ctx->regs.__ebp;
- return 0;
- case 6:
- *value = (ContextAddress)Ctx->regs.__esi;
- return 0;
- case 7:
- *value = (ContextAddress)Ctx->regs.__edi;
- return 0;
- case 8:
- *value = (ContextAddress)Ctx->regs.__eip;
- return 0;
- case 9:
- *value = (ContextAddress)Ctx->regs.__eflags;
- return 0;
- }
- }
- if (get_frame_info(Ctx, Frame, &IP, NULL, &FP) < 0) return -1;
- switch (rg) {
- case 5:
- *value = FP;
- return 0;
- case 8:
- *value = IP;
- return 0;
- }
-#elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__)
- ContextAddress IP, FP;
- if (is_top_frame(Ctx, Frame)) {
- switch (rg) {
- case 0:
- *value = (ContextAddress)Ctx->regs.r_eax;
- return 0;
- case 1:
- *value = (ContextAddress)Ctx->regs.r_ecx;
- return 0;
- case 2:
- *value = (ContextAddress)Ctx->regs.r_edx;
- return 0;
- case 3:
- *value = (ContextAddress)Ctx->regs.r_ebx;
- return 0;
- case 4:
- *value = (ContextAddress)Ctx->regs.r_esp;
- return 0;
- case 5:
- *value = (ContextAddress)Ctx->regs.r_ebp;
- return 0;
- case 6:
- *value = (ContextAddress)Ctx->regs.r_esi;
- return 0;
- case 7:
- *value = (ContextAddress)Ctx->regs.r_edi;
- return 0;
- case 8:
- *value = (ContextAddress)Ctx->regs.r_eip;
- return 0;
- case 9:
- *value = (ContextAddress)Ctx->regs.r_eflags;
- return 0;
- }
- }
- if (get_frame_info(Ctx, Frame, &IP, NULL, &FP) < 0) return -1;
- switch (rg) {
- case 5:
- *value = FP;
- return 0;
- case 8:
- *value = IP;
- return 0;
+#if ENABLE_DebugContext
+ RegisterDefinition * reg_def = get_reg_by_dwarf_id(rg);
+ if (reg_def != NULL) {
+ StackFrame * info;
+ if (get_frame_info(Ctx, Frame, &info) < 0) return -1;
+ if (read_reg_value(reg_def, info, value) >= 0) return 0;
}
-#else
-#error "Unknown DWARF registers mapping"
#endif
- trace(LOG_ALWAYS, "get_register: Unsupported DWARF register number %d", rg);
errno = ERR_UNSUPPORTED;
return -1;
}
static int set_register(Context * Ctx, int Frame, unsigned rg, U8_T value) {
-#if !ENABLE_DebugContext
-#elif defined(__linux__) && defined(__i386__) || \
- defined(_WRS_KERNEL) && (CPU_FAMILY==SIMNT || CPU_FAMILY==I80X86)
- if (is_top_frame(Ctx, Frame)) {
- switch (rg) {
- case 0:
- Ctx->regs.eax = (ContextAddress)value;
- return 0;
- case 1:
- Ctx->regs.ecx = (ContextAddress)value;
- return 0;
- case 2:
- Ctx->regs.edx = (ContextAddress)value;
- return 0;
- case 3:
- Ctx->regs.ebx = (ContextAddress)value;
- return 0;
- case 4:
- Ctx->regs.esp = (ContextAddress)value;
- return 0;
- case 5:
- Ctx->regs.ebp = (ContextAddress)value;
- return 0;
- case 6:
- Ctx->regs.esi = (ContextAddress)value;
- return 0;
- case 7:
- Ctx->regs.edi = (ContextAddress)value;
- return 0;
- case 8:
-#ifdef _WRS_KERNEL
- Ctx->regs.pc = (void *)(ContextAddress)value;
-#else
- Ctx->regs.eip = (ContextAddress)value;
-#endif
- return 0;
- case 9:
- Ctx->regs.eflags = (ContextAddress)value;
- return 0;
- }
- }
-#elif defined(__linux__) && defined(__x86_64__)
- if (is_top_frame(Ctx, Frame)) {
- switch (rg) {
- case 0:
- Ctx->regs.rax = (ContextAddress)value;
- return 0;
- case 1:
- Ctx->regs.rbx = (ContextAddress)value;
- return 0;
- case 2:
- Ctx->regs.rcx = (ContextAddress)value;
- return 0;
- case 3:
- Ctx->regs.rdx = (ContextAddress)value;
- return 0;
- case 4:
- Ctx->regs.rsi = (ContextAddress)value;
- return 0;
- case 5:
- Ctx->regs.rdi = (ContextAddress)value;
- return 0;
- case 6:
- Ctx->regs.rbp = (ContextAddress)value;
- return 0;
- case 7:
- Ctx->regs.rsp = (ContextAddress)value;
- return 0;
- case 8:
- Ctx->regs.r8 = (ContextAddress)value;
- return 0;
- case 9:
- Ctx->regs.r9 = (ContextAddress)value;
- return 0;
- case 10:
- Ctx->regs.r10 = (ContextAddress)value;
- return 0;
- case 11:
- Ctx->regs.r11 = (ContextAddress)value;
- return 0;
- case 12:
- Ctx->regs.r12 = (ContextAddress)value;
- return 0;
- case 13:
- Ctx->regs.r13 = (ContextAddress)value;
- return 0;
- case 14:
- Ctx->regs.r14 = (ContextAddress)value;
- return 0;
- case 15:
- Ctx->regs.r15 = (ContextAddress)value;
- return 0;
- }
- }
-#elif defined(__APPLE__) && defined(__i386__)
- if (is_top_frame(Ctx, Frame)) {
- switch (rg) {
- case 0:
- Ctx->regs.__eax = (ContextAddress)value;
- return 0;
- case 1:
- Ctx->regs.__ecx = (ContextAddress)value;
- return 0;
- case 2:
- Ctx->regs.__edx = (ContextAddress)value;
- return 0;
- case 3:
- Ctx->regs.__ebx = (ContextAddress)value;
- return 0;
- case 4:
- Ctx->regs.__esp = (ContextAddress)value;
- return 0;
- case 5:
- Ctx->regs.__ebp = (ContextAddress)value;
- return 0;
- case 6:
- Ctx->regs.__esi = (ContextAddress)value;
- return 0;
- case 7:
- Ctx->regs.__edi = (ContextAddress)value;
- return 0;
- case 8:
- Ctx->regs.__eip = (ContextAddress)value;
- return 0;
- case 9:
- Ctx->regs.__eflags = (ContextAddress)value;
- return 0;
- }
- }
-#elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__)
- if (is_top_frame(Ctx, Frame)) {
- switch (rg) {
- case 0:
- Ctx->regs.r_eax = (ContextAddress)value;
- return 0;
- case 1:
- Ctx->regs.r_ecx = (ContextAddress)value;
- return 0;
- case 2:
- Ctx->regs.r_edx = (ContextAddress)value;
- return 0;
- case 3:
- Ctx->regs.r_ebx = (ContextAddress)value;
- return 0;
- case 4:
- Ctx->regs.r_esp = (ContextAddress)value;
- return 0;
- case 5:
- Ctx->regs.r_ebp = (ContextAddress)value;
- return 0;
- case 6:
- Ctx->regs.r_esi = (ContextAddress)value;
- return 0;
- case 7:
- Ctx->regs.r_edi = (ContextAddress)value;
- return 0;
- case 8:
- Ctx->regs.r_eip = (ContextAddress)value;
- return 0;
- case 9:
- Ctx->regs.r_eflags = (ContextAddress)value;
+#if ENABLE_DebugContext
+ RegisterDefinition * reg_def = get_reg_by_dwarf_id(rg);
+ if (reg_def != NULL) {
+ size_t size = reg_def->size;
+ if (size <= 8 && Ctx->stopped && is_top_frame(Ctx, Frame)) {
+ U1_T * addr = (U1_T *)&Ctx->regs + reg_def->offset;
+ switch (size) {
+ case 1: *(U1_T *)addr = (U1_T)value; break;
+ case 2: *(U2_T *)addr = (U2_T)value; break;
+ case 4: *(U4_T *)addr = (U4_T)value; break;
+ case 8: *(U8_T *)addr = (U8_T)value; break;
+ }
+ Ctx->regs_dirty = 1;
return 0;
}
}
-#else
-#error "Unknown DWARF registers mapping"
#endif
- trace(LOG_ALWAYS, "set_register: Unsupported DWARF register number %d", rg);
errno = ERR_UNSUPPORTED;
return -1;
}
@@ -450,7 +95,7 @@ static int register_access_func(PropertyValue * Value, int write, U8_T * Data) {
static int evaluate_expression(U8_T BaseAddress, PropertyValue * Value, U1_T * Buf, size_t Size) {
if (Size == 0) {
- errno = ERR_INV_DWARF;
+ errno = set_exception_errno(ERR_INV_DWARF, "DWARF expression size = 0");
return -1;
}
dio_EnterDataSection(&Value->mObject->mCompUnit->mDesc, Buf, 0, Size);
@@ -465,8 +110,8 @@ static int evaluate_expression(U8_T BaseAddress, PropertyValue * Value, U1_T * B
switch (Op) {
case OP_addr:
if ((sExprStack[sExprStackLen++] = elf_map_to_run_time_address(
- Value->mContext, Value->mObject->mCompUnit->mFile, dio_ReadAddress())) == 0) {
- errno = ERR_INV_DWARF;
+ Value->mContext, Value->mObject->mCompUnit->mFile, (ContextAddress)dio_ReadAddress())) == 0) {
+ errno = set_exception_errno(ERR_INV_DWARF, "object has no RT address");
return -1;
}
break;
@@ -803,7 +448,7 @@ static int evaluate_expression(U8_T BaseAddress, PropertyValue * Value, U1_T * B
{
unsigned n = Op - OP_reg0;
if (dio_GetPos() < Size) {
- errno = ERR_INV_DWARF;
+ errno = set_exception_errno(ERR_INV_DWARF, "OP_reg must be last instruction");
return -1;
}
Value->mValue = n;
@@ -814,7 +459,7 @@ static int evaluate_expression(U8_T BaseAddress, PropertyValue * Value, U1_T * B
{
unsigned n = dio_ReadULEB128();
if (dio_GetPos() < Size) {
- errno = ERR_INV_DWARF;
+ errno = set_exception_errno(ERR_INV_DWARF, "OP_regx must be last instruction");
return -1;
}
Value->mValue = n;
@@ -863,8 +508,9 @@ static int evaluate_expression(U8_T BaseAddress, PropertyValue * Value, U1_T * B
ObjectInfo * Parent = get_parent_function(Value->mObject);
int error = 0;
+ memset(&FP, 0, sizeof(FP));
sKeepStack++;
- if (Parent == NULL) error = ERR_INV_DWARF;
+ if (Parent == NULL) error = set_exception_errno(ERR_INV_DWARF, "OP_fbreg: no parent function");
if (!error && read_and_evaluate_dwarf_object_property(Value->mContext, Value->mFrame, 0, Parent, AT_frame_base, &FP) < 0) error = errno;
sKeepStack--;
@@ -913,20 +559,21 @@ static int evaluate_expression(U8_T BaseAddress, PropertyValue * Value, U1_T * B
}
static int evaluate_location(U8_T BaseAddresss, PropertyValue * Value) {
- U1_T * Addr = NULL;
+ U8_T IP = 0;
U8_T Offset = 0;
U8_T Base = 0;
U8_T BaseMark = 0;
- ContextAddress IP = 0;
+ StackFrame * Frame = NULL;
DWARFCache * Cache = (DWARFCache *)Value->mObject->mCompUnit->mFile->dwarf_dt_cache;
assert(Cache->magic == SYM_CACHE_MAGIC);
if (Cache->mDebugLoc == NULL) {
- errno = ERR_INV_DWARF;
+ errno = set_exception_errno(ERR_INV_DWARF, "missing .debug_loc section");
return -1;
}
if (elf_load(Cache->mDebugLoc) < 0) return -1;
- if (get_frame_info(Value->mContext, Value->mFrame, &IP, NULL, NULL) < 0) return -1;
+ if (get_frame_info(Value->mContext, Value->mFrame, &Frame) < 0) return -1;
+ if (read_reg_value(get_PC_definition(), Frame, &IP) < 0) return -1;
dio_EnterDataSection(&Value->mObject->mCompUnit->mDesc, Value->mAddr, 0, Value->mSize);
switch (Value->mSize) {
case 4:
@@ -938,12 +585,11 @@ static int evaluate_location(U8_T BaseAddresss, PropertyValue * Value) {
BaseMark = ~(U8_T)0;
break;
default:
- errno = ERR_INV_DWARF;
+ errno = set_exception_errno(ERR_INV_DWARF, "invalid .debug_loc pointer size");
return -1;
}
- Addr = Cache->mDebugLoc->data;
Base = Value->mObject->mCompUnit->mLowPC;
- dio_EnterDataSection(&Value->mObject->mCompUnit->mDesc, Addr, Offset, Cache->mDebugLoc->size);
+ dio_EnterDataSection(&Value->mObject->mCompUnit->mDesc, Cache->mDebugLoc->data, Offset, Cache->mDebugLoc->size);
for (;;) {
U8_T Addr0 = dio_ReadAddress();
U8_T Addr1 = dio_ReadAddress();
@@ -955,10 +601,10 @@ static int evaluate_location(U8_T BaseAddresss, PropertyValue * Value) {
}
else {
U2_T Size = dio_ReadU2();
- ContextAddress RTAddr0 = elf_map_to_run_time_address(Value->mContext, Cache->mFile, Base + Addr0);
- ContextAddress RTAddr1 = Addr1 - Addr0 + RTAddr0;
+ ContextAddress RTAddr0 = elf_map_to_run_time_address(Value->mContext, Cache->mFile, (ContextAddress)(Base + Addr0));
+ ContextAddress RTAddr1 = (ContextAddress)(Addr1 - Addr0) + RTAddr0;
if (RTAddr0 != 0 && IP >= RTAddr0 && IP < RTAddr1) {
- return evaluate_expression(BaseAddresss, Value, Addr + dio_GetPos(), Size);
+ return evaluate_expression(BaseAddresss, Value, dio_GetDataPtr(), Size);
}
dio_Skip(Size);
}
@@ -984,7 +630,7 @@ int dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * Value) {
}
if (set_trap(&trap)) {
if (Value->mAccessFunc != NULL || Value->mAddr == NULL || Value->mSize == 0) {
- error = ERR_INV_DWARF;
+ error = set_exception_errno(ERR_INV_DWARF, "invalid DWARF expression reference");
}
else if (Value->mForm == FORM_DATA4 || Value->mForm == FORM_DATA8) {
if (evaluate_location(BaseAddress, Value) < 0) error = errno;
@@ -998,7 +644,9 @@ int dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * Value) {
error = trap.error;
}
- if (!error && !sKeepStack && sExprStackLen != (Value->mAccessFunc == NULL ? 1 : 0)) error = ERR_INV_DWARF;
+ if (!error && !sKeepStack && sExprStackLen != (Value->mAccessFunc == NULL ? 1u : 0u)) {
+ error = set_exception_errno(ERR_INV_DWARF, "invalid DWARF expression stack");
+ }
if (!error) {
if (Value->mAccessFunc == NULL) {
diff --git a/services/dwarfframe.c b/services/dwarfframe.c
new file mode 100644
index 00000000..96711c20
--- /dev/null
+++ b/services/dwarfframe.c
@@ -0,0 +1,554 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2009 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.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * This module implements handling of .debug_frame and .eh_frame sections.
+ *
+ * Functions in this module use exceptions to report errors, see exceptions.h
+ */
+
+#include "config.h"
+
+#if ENABLE_ELF
+
+#include <assert.h>
+#include <stdio.h>
+#include "dwarfio.h"
+#include "dwarfframe.h"
+#include "exceptions.h"
+#include "breakpoints.h"
+#include "myalloc.h"
+
+#define EH_PE_omit 0xff
+
+#define EH_PE_absptr 0x00
+#define EH_PE_uleb128 0x01
+#define EH_PE_udata2 0x02
+#define EH_PE_udata4 0x03
+#define EH_PE_udata8 0x04
+#define EH_PE_sleb128 0x09
+#define EH_PE_sdata2 0x0a
+#define EH_PE_sdata4 0x0b
+#define EH_PE_sdata8 0x0c
+
+#define EH_PB_pcrel 0x01
+#define EH_PB_textrel 0x02
+#define EH_PB_datarel 0x03
+#define EH_PB_funcrel 0x04
+#define EH_PB_aligned 0x05
+
+#define EH_PE_indirect 0x80
+
+#define RULE_OFFSET 1
+#define RULE_SAME_VALUE 2
+#define RULE_REGISTER 3
+#define RULE_EXPRESSION 4
+#define RULE_VAL_OFFSET 5
+#define RULE_VAL_EXPRESSION 6
+
+typedef struct RegisterRules {
+ int rule;
+ I4_T offset;
+ U1_T * expression;
+} RegisterRules;
+
+typedef struct StackFrameRegisters {
+ RegisterRules * regs;
+ int regs_cnt;
+ int regs_max;
+} StackFrameRegisters;
+
+typedef struct StackFrameRules {
+ Context * ctx;
+ ELF_Section * section;
+ int eh_frame;
+ U1_T version;
+ U4_T code_alignment;
+ I4_T data_alignment;
+ U8_T cie_pos;
+ char * cie_aug;
+ U8_T cie_eh_data;
+ U4_T fde_aug_length;
+ U1_T * fde_aug_data;
+ U1_T lsda_encoding;
+ U1_T prh_encoding;
+ U1_T addr_encoding;
+ U8_T location;
+ int return_address_register;
+ int cfa_rule;
+ I4_T cfa_offset;
+ U4_T cfa_register;
+ U1_T * cfa_expression;
+} StackFrameRules;
+
+static StackFrameRegisters frame_regs;
+static StackFrameRegisters cie_regs;
+static StackFrameRegisters * regs_stack = NULL;
+static int regs_stack_max = 0;
+static int regs_stack_pos = 0;
+
+static StackFrameRules rules;
+
+static RegisterRules * get_reg(StackFrameRegisters * regs, int reg) {
+ RegisterDefinition * reg_def;
+ while (reg >= regs->regs_max) {
+ regs->regs_max = regs->regs_max == 0 ? 32 : regs->regs_max * 2;
+ regs->regs = loc_realloc(regs->regs, sizeof(RegisterRules) * regs->regs_max);
+ }
+ while (regs->regs_cnt <= reg) {
+ int n = regs->regs_cnt++;
+ memset(regs->regs + n, 0, sizeof(RegisterRules));
+ reg_def = rules.eh_frame ?
+ get_reg_by_eh_frame_id(n) :
+ get_reg_by_dwarf_id(n);
+ if (reg_def != NULL && reg_def->traceable) {
+ /* It looks like GCC assumes that an unspecified register implies "same value" */
+ regs->regs[n].rule = RULE_SAME_VALUE;
+ }
+ }
+ return regs->regs + reg;
+}
+
+static void copy_register_rules(StackFrameRegisters * dst, StackFrameRegisters * src) {
+ int n;
+ dst->regs_cnt = 0;
+ for (n = 0; n < src->regs_cnt; n++) {
+ *get_reg(dst, n) = *get_reg(src, n);
+ }
+}
+
+static StackFrameRegisters * get_regs_stack_item(int n) {
+ while (n >= regs_stack_max) {
+ int max = regs_stack_max;
+ regs_stack_max = regs_stack_max == 0 ? 8 : regs_stack_max * 2;
+ regs_stack = loc_realloc(regs_stack, sizeof(StackFrameRegisters) * regs_stack_max);
+ memset(regs_stack + max, 0, sizeof(StackFrameRegisters) * (regs_stack_max - max));
+ }
+ return regs_stack + n;
+}
+
+static U8_T read_frame_data_pointer(U1_T encoding, int abs) {
+ U8_T v = 0;
+ if (encoding != EH_PE_omit) {
+ U8_T pos = dio_GetPos();
+ switch (encoding & 0xf) {
+ case EH_PE_absptr:
+ v = dio_ReadAddress();
+ break;
+ case EH_PE_uleb128:
+ v = dio_ReadU8LEB128();
+ break;
+ case EH_PE_udata2:
+ v = dio_ReadU2();
+ break;
+ case EH_PE_udata4:
+ v = dio_ReadU4();
+ break;
+ case EH_PE_udata8:
+ v = dio_ReadU8();
+ break;
+ case EH_PE_sleb128:
+ v = dio_ReadS8LEB128();
+ break;
+ case EH_PE_sdata2:
+ v = (I2_T)dio_ReadU2();
+ break;
+ case EH_PE_sdata4:
+ v = (I4_T)dio_ReadU4();
+ break;
+ case EH_PE_sdata8:
+ v = (I8_T)dio_ReadU8();
+ break;
+ default:
+ printf("cie at 0x%08x\n", (U4_T)rules.cie_pos);
+ str_exception(ERR_INV_DWARF, "Unknown encoding of .eh_frame section pointers");
+ break;
+ }
+ if (v != 0 && !abs) {
+ switch ((encoding >> 4) & 0x7) {
+ case 0:
+ break;
+ case EH_PB_pcrel:
+ v += rules.section->addr + pos;
+ break;
+ case EH_PB_datarel:
+ v += rules.section->addr;
+ break;
+ case EH_PB_textrel:
+ case EH_PB_funcrel:
+ case EH_PB_aligned:
+ default:
+ str_exception(ERR_INV_DWARF, "Unknown encoding of .eh_frame section pointers");
+ break;
+ }
+ if (encoding & EH_PE_indirect) {
+ unsigned idx;
+ U8_T res = 0;
+ ELF_File * file = rules.section->file;
+ for (idx = 1; idx < file->section_cnt; idx++) {
+ ELF_Section * sec = file->sections + idx;
+ if ((sec->flags & SHF_ALLOC) == 0) continue;
+ if (sec->addr <= v && sec->addr + sec->size > v) {
+ res = elf_read_section(sec, (uintptr_t)(v - sec->addr), file->elf64 ? 8 : 4);
+ break;
+ }
+ }
+ v = res;
+ }
+ }
+ }
+ return v;
+}
+
+static void exec_stack_frame_instruction(void) {
+ RegisterRules * reg;
+ U4_T n;
+ U1_T op = dio_ReadU1();
+ switch (op) {
+ case 0x00: /* DW_CFA_nop */
+ break;
+ case 0x01: /* DW_CFA_set_loc */
+ rules.location = read_frame_data_pointer(rules.addr_encoding, 0);
+ break;
+ case 0x02: /* DW_CFA_advance_loc1 */
+ rules.location += dio_ReadU1() * rules.code_alignment;
+ break;
+ case 0x03: /* DW_CFA_advance_loc2 */
+ rules.location += dio_ReadU2() * rules.code_alignment;
+ break;
+ case 0x04: /* DW_CFA_advance_loc4 */
+ rules.location += dio_ReadU4() * rules.code_alignment;
+ break;
+ case 0x05: /* DW_CFA_offset_extended */
+ reg = get_reg(&frame_regs, dio_ReadULEB128());
+ reg->rule = RULE_OFFSET;
+ reg->offset = dio_ReadULEB128() * rules.data_alignment;
+ break;
+ case 0x06: /* DW_CFA_restore_extended */
+ n = dio_ReadULEB128();
+ reg = get_reg(&frame_regs, n);
+ *reg = *get_reg(&cie_regs, n);
+ break;
+ case 0x07: /* DW_CFA_undefined */
+ reg = get_reg(&frame_regs, dio_ReadULEB128());
+ memset(reg, 0, sizeof(*reg));
+ break;
+ case 0x08: /* DW_CFA_same_value */
+ reg = get_reg(&frame_regs, dio_ReadULEB128());
+ reg->rule = RULE_SAME_VALUE;
+ break;
+ case 0x09: /* DW_CFA_register */
+ reg = get_reg(&frame_regs, dio_ReadULEB128());
+ reg->rule = RULE_REGISTER;
+ reg->offset = dio_ReadULEB128();
+ break;
+ case 0x0a: /* DW_CFA_remember_state */
+ copy_register_rules(get_regs_stack_item(regs_stack_pos++), &frame_regs);
+ break;
+ case 0x0b: /* DW_CFA_restore_state */
+ if (regs_stack_pos <= 0) {
+ str_exception(ERR_INV_DWARF, "Invalid DW_CFA_restore_state instruction");
+ }
+ copy_register_rules(&frame_regs, get_regs_stack_item(--regs_stack_pos));
+ break;
+ case 0x0c: /* DW_CFA_def_cfa */
+ rules.cfa_rule = RULE_OFFSET;
+ rules.cfa_register = dio_ReadULEB128();
+ rules.cfa_offset = dio_ReadULEB128();
+ break;
+ case 0x0d: /* DW_CFA_def_cfa_register */
+ rules.cfa_rule = RULE_OFFSET;
+ rules.cfa_register = dio_ReadULEB128();
+ break;
+ case 0x0e: /* DW_CFA_def_cfa_offset */
+ rules.cfa_rule = RULE_OFFSET;
+ rules.cfa_offset = dio_ReadULEB128();
+ break;
+ case 0x0f: /* DW_CFA_def_cfa_expression */
+ rules.cfa_rule = RULE_EXPRESSION;
+ rules.cfa_offset = dio_ReadULEB128();
+ rules.cfa_expression = dio_GetDataPtr();
+ dio_Skip(rules.cfa_offset);
+ break;
+ case 0x10: /* DW_CFA_expression */
+ reg = get_reg(&frame_regs, dio_ReadULEB128());
+ reg->rule = RULE_EXPRESSION;
+ reg->offset = dio_ReadULEB128();
+ reg->expression = dio_GetDataPtr();
+ dio_Skip(reg->offset);
+ break;
+ case 0x11: /* DW_CFA_offset_extended_sf */
+ reg = get_reg(&frame_regs, dio_ReadULEB128());
+ reg->rule = RULE_OFFSET;
+ reg->offset = dio_ReadSLEB128() * rules.data_alignment;
+ break;
+ case 0x12: /* DW_CFA_def_cfa_sf */
+ rules.cfa_rule = RULE_OFFSET;
+ rules.cfa_register = dio_ReadULEB128();
+ rules.cfa_offset = dio_ReadSLEB128() * rules.data_alignment;
+ break;
+ case 0x13: /* DW_CFA_def_cfa_offset_sf */
+ rules.cfa_rule = RULE_OFFSET;
+ rules.cfa_offset = dio_ReadSLEB128() * rules.data_alignment;
+ break;
+ case 0x14: /* DW_CFA_val_offset */
+ reg = get_reg(&frame_regs, dio_ReadULEB128());
+ reg->rule = RULE_VAL_OFFSET;
+ reg->offset = dio_ReadULEB128() * rules.data_alignment;
+ break;
+ case 0x15: /* DW_CFA_val_offset_sf */
+ reg = get_reg(&frame_regs, dio_ReadULEB128());
+ reg->rule = RULE_VAL_OFFSET;
+ reg->offset = dio_ReadSLEB128() * rules.data_alignment;
+ break;
+ case 0x16: /* DW_CFA_val_expression */
+ reg = get_reg(&frame_regs, dio_ReadULEB128());
+ reg->rule = RULE_VAL_EXPRESSION;
+ reg->offset = dio_ReadULEB128();
+ reg->expression = dio_GetDataPtr();
+ dio_Skip(reg->offset);
+ break;
+ default:
+ switch (op >> 6) {
+ case 0:
+ str_exception(ERR_INV_DWARF, "Unsupported instruction in Call Frame Information");
+ break;
+ case 1: /* DW_CFA_advance_loc */
+ rules.location += (op & 0x3f) * rules.code_alignment;
+ break;
+ case 2: /* DW_CFA_offset */
+ reg = get_reg(&frame_regs, op & 0x3f);
+ reg->rule = RULE_OFFSET;
+ reg->offset = dio_ReadULEB128() * rules.data_alignment;
+ break;
+ case 3: /* DW_CFA_restore */
+ n = op & 0x3f;
+ reg = get_reg(&frame_regs, n);
+ *reg = *get_reg(&cie_regs, n);
+ break;
+ }
+ }
+}
+
+static int fill_frame_register(RegisterRules * reg, RegisterDefinition * reg_def, StackFrame * frame, StackFrame * down) {
+ switch (reg->rule) {
+ case RULE_OFFSET:
+ if (frame->fp != 0 && reg_def != NULL) {
+ size_t size = reg_def->size;
+ if (size <= 8) {
+ U1_T v[8];
+ if (context_read_mem(rules.ctx, frame->fp + reg->offset, v, size) < 0) return -1;
+ check_breakpoints_on_memory_read(rules.ctx, frame->fp + reg->offset, v, size);
+ switch (size) {
+ case 1: write_reg_value(reg_def, down, *(U1_T *)v); break;
+ case 2: write_reg_value(reg_def, down, *(U2_T *)v); break;
+ case 4: write_reg_value(reg_def, down, *(U4_T *)v); break;
+ case 8: write_reg_value(reg_def, down, *(U8_T *)v); break;
+ }
+ }
+ }
+ break;
+ case RULE_SAME_VALUE:
+ if (reg_def != NULL) {
+ U8_T v = 0;
+ if (read_reg_value(reg_def, frame, &v) >= 0) {
+ write_reg_value(reg_def, down, v);
+ }
+ }
+ break;
+ case RULE_REGISTER:
+ if (reg_def != NULL) {
+ RegisterDefinition * src_index = rules.eh_frame ?
+ get_reg_by_eh_frame_id(reg->offset) :
+ get_reg_by_dwarf_id(reg->offset);
+ if (src_index != NULL) {
+ U8_T v = 0;
+ if (read_reg_value(src_index, frame, &v) >= 0) {
+ write_reg_value(reg_def, down, v);
+ }
+ }
+ }
+ break;
+ case RULE_VAL_OFFSET:
+ if (frame->fp != 0 && reg_def != NULL) {
+ U8_T v = frame->fp + reg->offset;
+ write_reg_value(reg_def, down, v);
+ }
+ break;
+ case RULE_EXPRESSION:
+ case RULE_VAL_EXPRESSION:
+ /* TODO: RULE_EXPRESSION */
+ break;
+ }
+ return 0;
+}
+
+static int fill_stack_frame(StackFrame * frame, StackFrame * down) {
+ int i;
+ U8_T v = 0;
+ RegisterRules * reg;
+ RegisterDefinition * reg_def;
+
+ switch (rules.cfa_rule) {
+ case RULE_OFFSET:
+ reg_def = rules.eh_frame ?
+ get_reg_by_eh_frame_id(rules.cfa_register) :
+ get_reg_by_dwarf_id(rules.cfa_register);
+ if (reg_def != NULL) {
+ if (read_reg_value(reg_def, frame, &v) >= 0) {
+ frame->fp = (ContextAddress)(v + rules.cfa_offset);
+ }
+ }
+ break;
+ /* TODO: RULE_EXPRESSION */
+ }
+
+ reg = get_reg(&frame_regs, rules.return_address_register);
+ if (reg->rule != 0 && fill_frame_register(reg, get_PC_definition(), frame, down) < 0) return -1;
+ for (i = 0; i < frame_regs.regs_cnt; i++) {
+ if (i == rules.return_address_register) continue;
+ reg = get_reg(&frame_regs, i);
+ if (reg->rule == 0) continue;
+ reg_def = rules.eh_frame ?
+ get_reg_by_eh_frame_id(i) :
+ get_reg_by_dwarf_id(i);
+ if (fill_frame_register(reg, reg_def, frame, down) < 0) return -1;
+ }
+ return 0;
+}
+
+static void read_frame_cie(U8_T pos) {
+ int cie_dwarf64 = 0;
+ U8_T saved_pos = dio_GetPos();
+ U8_T cie_length = 0;
+ U8_T cie_end = 0;
+
+ rules.cie_pos = pos;
+ dio_Skip(pos - dio_GetPos());
+ cie_length = dio_ReadU4();
+ if (cie_length == 0xffffffffu) {
+ cie_length = dio_ReadU8();
+ cie_dwarf64 = 1;
+ }
+ cie_end = dio_GetPos() + cie_length;
+ dio_Skip(cie_dwarf64 ? 8 : 4);
+ rules.version = dio_ReadU1();
+ if (rules.version != 1 && rules.version != 3) {
+ str_exception(ERR_INV_DWARF, "Unsupported version of Call Frame Information");
+ }
+ rules.cie_aug = dio_ReadString();
+ if (rules.cie_aug != NULL && strcmp(rules.cie_aug, "eh") == 0) {
+ rules.cie_eh_data = dio_ReadAddress();
+ }
+ rules.code_alignment = dio_ReadULEB128();
+ rules.data_alignment = dio_ReadSLEB128();
+ rules.return_address_register = dio_ReadULEB128();
+ rules.lsda_encoding = 0;
+ rules.prh_encoding = 0;
+ rules.addr_encoding = 0;
+ if (rules.cie_aug != NULL && rules.cie_aug[0] == 'z') {
+ U4_T aug_length = dio_ReadULEB128();
+ U8_T aug_pos = dio_GetPos();
+ char * p = rules.cie_aug + 1;
+ while (*p) {
+ switch (*p++) {
+ case 'L':
+ rules.lsda_encoding = dio_ReadU1();
+ break;
+ case 'P':
+ rules.prh_encoding = dio_ReadU1();
+ read_frame_data_pointer(rules.prh_encoding, 0);
+ break;
+ case 'R':
+ rules.addr_encoding = dio_ReadU1();
+ break;
+ }
+ }
+ dio_Skip(aug_pos + aug_length - dio_GetPos());
+ }
+ cie_regs.regs_cnt = 0;
+ frame_regs.regs_cnt = 0;
+ regs_stack_pos = 0;
+ while (dio_GetPos() < cie_end) {
+ exec_stack_frame_instruction();
+ }
+ copy_register_rules(&cie_regs, &frame_regs);
+ dio_Skip(saved_pos - dio_GetPos());
+}
+
+void get_dwarf_stack_frame_info(Context * ctx, ELF_File * file, StackFrame * frame, StackFrame * down) {
+ /* TODO: use .eh_frame_hdr section for faster frame data search */
+ U8_T IP = 0;
+ DWARFCache * cache = get_dwarf_cache(file);
+ ELF_Section * section = cache->mDebugFrame;
+ if (section == NULL) section = cache->mEHFrame;
+ if (section == NULL) return;
+
+ if (read_reg_value(get_PC_definition(), frame, &IP) < 0) exception(errno);
+ memset(&rules, 0, sizeof(StackFrameRules));
+ rules.ctx = ctx;
+ rules.section = section;
+ rules.eh_frame = section == cache->mEHFrame;
+ rules.cie_pos = ~(U8_T)0;
+ dio_EnterDebugSection(NULL, section, 0);
+ while (dio_GetPos() < section->size) {
+ int fde_dwarf64 = 0;
+ U8_T fde_length = 0;
+ U8_T fde_pos = 0;
+ U8_T fde_end = 0;
+ U8_T cie_ref = 0;
+ int fde_flag = 0;
+
+ fde_length = dio_ReadU4();
+ if (fde_length == 0xffffffffu) {
+ fde_length = dio_ReadU8();
+ fde_dwarf64 = 1;
+ }
+ if (fde_length == 0) break;
+ fde_pos = dio_GetPos();
+ fde_end = fde_pos + fde_length;
+ cie_ref = fde_dwarf64 ? dio_ReadU8() : dio_ReadU4();
+ if (rules.eh_frame) fde_flag = cie_ref != 0;
+ else if (fde_dwarf64) fde_flag = cie_ref != ~(U8_T)0;
+ else fde_flag = cie_ref != ~(U4_T)0;
+ if (fde_flag) {
+ U8_T Addr, Range, AddrRT;
+ if (rules.eh_frame) cie_ref = fde_pos - cie_ref;
+ if (cie_ref != rules.cie_pos) read_frame_cie(cie_ref);
+ Addr = read_frame_data_pointer(rules.addr_encoding, 0);
+ Range = read_frame_data_pointer(rules.addr_encoding, 1);
+ AddrRT = elf_map_to_run_time_address(ctx, file, (ContextAddress)Addr);
+ if (AddrRT != 0 && AddrRT <= IP && AddrRT + Range > IP) {
+ if (rules.cie_aug != NULL && rules.cie_aug[0] == 'z') {
+ rules.fde_aug_length = dio_ReadULEB128();
+ rules.fde_aug_data = dio_GetDataPtr();
+ dio_Skip(rules.fde_aug_length);
+ }
+ copy_register_rules(&frame_regs, &cie_regs);
+ rules.location = Addr;
+ regs_stack_pos = 0;
+ while (dio_GetPos() < fde_end) {
+ exec_stack_frame_instruction();
+ if (rules.location - Addr + AddrRT > IP) break;
+ }
+ fill_stack_frame(frame, down);
+ break;
+ }
+ }
+ dio_Skip(fde_end - dio_GetPos());
+ }
+ dio_ExitSection();
+}
+
+#endif /* ENABLE_ELF */
diff --git a/services/dwarfframe.h b/services/dwarfframe.h
new file mode 100644
index 00000000..d4939ed8
--- /dev/null
+++ b/services/dwarfframe.h
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2009 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.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * This module implements handling of .debug_frame and .eh_frame sections.
+ *
+ * Functions in this module use exceptions to report errors, see exceptions.h
+ */
+
+#ifndef D_dwarfframe
+#define D_dwarfframe
+
+#include "config.h"
+
+#if ENABLE_ELF
+
+#include "context.h"
+#include "dwarfcache.h"
+
+/*
+ * Lookup stack frame data in ELF file, in .debug_frame and .eh_frame sections.
+ *
+ * "frame" is current frame info, it should have frame->regs and frame->mask filled with
+ * proper values before this function is called.
+ *
+ * "down" is next frame - moving from stack top to the bottom.
+ *
+ * The function uses register values in current frame to calculate frame address "frame->fp",
+ * and calculate register values in the next frame.
+ *
+ * If frame data is not found the function does nothing.
+ * In case of error reading frame data, the function throws an exception.
+ */
+extern void get_dwarf_stack_frame_info(Context * ctx, ELF_File * file, StackFrame * frame, StackFrame * down);
+
+#endif /* ENABLE_ELF */
+
+#endif /* D_dwarfframe */
diff --git a/services/dwarfio.c b/services/dwarfio.c
index 343c2ba4..72b38897 100644
--- a/services/dwarfio.c
+++ b/services/dwarfio.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2009 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.
@@ -59,13 +59,13 @@ typedef struct DIO_Cache DIO_Cache;
U8_T dio_gEntryPos = 0;
-U8_T dio_gFormRef = 0;
U8_T dio_gFormData = 0;
size_t dio_gFormDataSize = 0;
void * dio_gFormDataAddr = NULL;
static ELF_Section * sSection;
-static U1_T sBigEndian;
+static int sBigEndian;
+static int sAddressSize;
static U1_T * sData;
static U8_T sDataPos;
static U8_T sDataLen;
@@ -116,6 +116,9 @@ void dio_EnterDebugSection(DIO_UnitDescriptor * Unit, ELF_Section * Section, U8_
sDataPos = Offset;
sDataLen = Section->size;
sBigEndian = Section->file->big_endian;
+ if (Unit != NULL) sAddressSize = Unit->mAddressSize;
+ else if (Section->file->elf64) sAddressSize = 8;
+ else sAddressSize = 4;
sUnit = Unit;
dio_gEntryPos = 0;
assert(sData != NULL);
@@ -127,6 +130,7 @@ void dio_EnterDataSection(DIO_UnitDescriptor * Unit, U1_T * Data, U8_T Offset, U
sDataPos = Offset;
sDataLen = Size;
sBigEndian = Unit->mFile->big_endian;
+ sAddressSize = Unit->mAddressSize;
sUnit = Unit;
dio_gEntryPos = 0;
assert(sData != NULL);
@@ -144,6 +148,10 @@ U8_T dio_GetPos() {
return sDataPos;
}
+U1_T * dio_GetDataPtr(void) {
+ return sData + sDataPos;
+}
+
void dio_Skip(I8_T Bytes) {
if (sDataPos + Bytes > sDataLen) exception(ERR_EOF);
sDataPos += Bytes;
@@ -249,7 +257,7 @@ U8_T dio_ReadUX(int Size) {
}
U8_T dio_ReadAddress(void) {
- switch (sUnit->mAddressSize) {
+ switch (sAddressSize) {
case 2:
return dio_ReadU2();
case 4:
@@ -304,7 +312,8 @@ static U1_T * dio_LoadStringTable(U4_T * StringTableSize) {
}
static void dio_ReadFormAddr(void) {
- dio_gFormRef = dio_ReadAddress();
+ dio_gFormData = dio_ReadAddress();
+ dio_gFormDataSize = sAddressSize;
}
static void dio_ReadFormBlock(U4_T Size) {
@@ -321,20 +330,23 @@ static void dio_ReadFormData(U1_T Size, U8_T Data) {
}
static void dio_ReadFormRef(void) {
- dio_gFormRef = dio_ReadU4();
+ dio_gFormData = dio_ReadU4();
+ dio_gFormDataSize = 4;
}
static void dio_ReadFormRelRef(U8_T Offset) {
if (sUnit->mUnitSize > 0 && Offset >= sUnit->mUnitSize) {
str_exception(ERR_INV_DWARF, "invalid REF attribute value");
}
- dio_gFormRef = sSection->addr + sUnit->mUnitOffs + Offset;
+ dio_gFormData = sSection->addr + sUnit->mUnitOffs + Offset;
+ dio_gFormDataSize = sAddressSize;
}
static void dio_ReadFormRefAddr(void) {
U4_T Size = sUnit->mAddressSize;
if (sUnit->mVersion >= 3) Size = sUnit->m64bit ? 8 : 4;
- dio_gFormRef = dio_ReadUX(Size);
+ dio_gFormData = dio_ReadUX(Size);
+ dio_gFormDataSize = Size;
}
static void dio_ReadFormString(void) {
@@ -362,7 +374,6 @@ static void dio_ReadAttribute(U2_T Attr, U2_T Form) {
dio_gFormDataAddr = NULL;
dio_gFormDataSize = 0;
dio_gFormData = 0;
- dio_gFormRef = 0;
switch (Form) {
case FORM_ADDR : dio_ReadFormAddr(); break;
case FORM_REF : dio_ReadFormRef(); break;
@@ -443,7 +454,7 @@ void dio_ReadEntry(DIO_EntryCallBack CallBack) {
if (Attr == AT_sibling && sUnit->mUnitSize == 0) {
dio_ChkRef(Form);
assert(sUnit->mVersion == 1);
- sUnit->mUnitSize = (U4_T)(dio_gFormRef - sSection->addr - sUnit->mUnitOffs);
+ sUnit->mUnitSize = (U4_T)(dio_gFormData - sSection->addr - sUnit->mUnitOffs);
assert(sUnit->mUnitOffs < dio_GetPos());
assert(sUnit->mUnitOffs + sUnit->mUnitSize >= dio_GetPos());
}
diff --git a/services/dwarfio.h b/services/dwarfio.h
index 62637d50..53bdd475 100644
--- a/services/dwarfio.h
+++ b/services/dwarfio.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2009 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.
@@ -37,7 +37,6 @@ typedef struct DIO_UnitDescriptor {
extern U8_T dio_gEntryPos;
-extern U8_T dio_gFormRef; /* Absolute address */
extern U8_T dio_gFormData;
extern size_t dio_gFormDataSize;
extern void * dio_gFormDataAddr;
@@ -49,6 +48,7 @@ extern void dio_ExitSection(void);
extern void dio_Skip(I8_T Bytes);
extern void dio_Read(U1_T * Buf, U4_T Size);
extern U8_T dio_GetPos(void); /* Offset in the section */
+extern U1_T * dio_GetDataPtr(void);
extern U1_T dio_ReadU1(void);
extern U2_T dio_ReadU2(void);
diff --git a/services/expressions.c b/services/expressions.c
index 364d2fa2..3a1f7575 100644
--- a/services/expressions.c
+++ b/services/expressions.c
@@ -2209,6 +2209,7 @@ static void command_evaluate(char * token, Channel * c) {
if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
if (expression_context_id(id, parent, &ctx, &frame, name, &expr) < 0) err = errno;
+ if (!err && frame != STACK_NO_FRAME && !ctx->intercepted) err = ERR_IS_RUNNING;
if (!err && evaluate_expression(ctx, frame, expr ? expr->script : name, 0, &value) < 0) err = errno;
if (value.size >= 0x100000) err = ERR_BUFFER_OVERFLOW;
diff --git a/services/expressions.h b/services/expressions.h
index 97b6a65f..4efa49a9 100644
--- a/services/expressions.h
+++ b/services/expressions.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/filesystem.c b/services/filesystem.c
index d1a43fd8..8dd6e36e 100644
--- a/services/filesystem.c
+++ b/services/filesystem.c
@@ -1174,6 +1174,7 @@ static void command_roots(char * token, Channel * c) {
}
}
#elif defined(_WRS_KERNEL)
+ /* TODO: iosDvList */
write_stream(&c->out, '{');
json_write_string(&c->out, "FileName");
write_stream(&c->out, ':');
diff --git a/services/filesystem.h b/services/filesystem.h
index b53406b9..239be92d 100644
--- a/services/filesystem.h
+++ b/services/filesystem.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/linenumbers.h b/services/linenumbers.h
index 68b5dae8..da40dce2 100644
--- a/services/linenumbers.h
+++ b/services/linenumbers.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/linenumbers_elf.c b/services/linenumbers_elf.c
index c82b9527..8df3cba4 100644
--- a/services/linenumbers_elf.c
+++ b/services/linenumbers_elf.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/linenumbers_win32.c b/services/linenumbers_win32.c
index 05235990..c2baafac 100644
--- a/services/linenumbers_win32.c
+++ b/services/linenumbers_win32.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -20,7 +20,7 @@
#include "config.h"
-#if SERVICE_LineNumbers && defined(_MSC_VER)
+#if SERVICE_LineNumbers && defined(_MSC_VER) && !ENABLE_ELF
#include <errno.h>
#include <assert.h>
diff --git a/services/memoryservice.c b/services/memoryservice.c
index 3177a87a..9d19c531 100644
--- a/services/memoryservice.c
+++ b/services/memoryservice.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/memoryservice.h b/services/memoryservice.h
index b58a08b3..b0dd07c1 100644
--- a/services/memoryservice.h
+++ b/services/memoryservice.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/processes.c b/services/processes.c
index 809febec..f50b448f 100644
--- a/services/processes.c
+++ b/services/processes.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/processes.h b/services/processes.h
index b018efd8..ace94ff2 100644
--- a/services/processes.h
+++ b/services/processes.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/registers.c b/services/registers.c
index 343ea292..46c26735 100644
--- a/services/registers.c
+++ b/services/registers.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -29,117 +29,15 @@
#include "context.h"
#include "json.h"
#include "exceptions.h"
+#include "stacktrace.h"
#include "registers.h"
static const char * REGISTERS = "Registers";
-#if defined(_WRS_KERNEL)
-
-# define regs_index taskRegName
-# if defined(_WRS_REG_INDEX_REGWIDTH) || (CPU_FAMILY==COLDFIRE)
-# define REG_WIDTH(x) (x).regWidth
-# else
-# define REG_WIDTH(x) 4
-# endif
-
-#else
-
-typedef struct {
- char *regName; /* pointer to register name */
- int regOff; /* offset to entry in REG_SET */
- int regWidth; /* register width in bytes */
-} REG_INDEX;
-
-#define REG_WIDTH(x) (x).regWidth
-
-#define REG_OFFSET(name) offsetof(REG_SET, name)
-
-static REG_INDEX regs_index[] = {
-#if defined(WIN32) && defined(__i386__)
- { "edi", REG_OFFSET(Edi), 4},
- { "esi", REG_OFFSET(Esi), 4},
- { "ebp", REG_OFFSET(Ebp), 4},
- { "esp", REG_OFFSET(Esp), 4},
- { "ebx", REG_OFFSET(Ebx), 4},
- { "edx", REG_OFFSET(Edx), 4},
- { "ecx", REG_OFFSET(Ecx), 4},
- { "eax", REG_OFFSET(Eax), 4},
- { "eflags", REG_OFFSET(EFlags), 4},
- { "eip", REG_OFFSET(Eip), 4},
- { "cs", REG_OFFSET(SegCs), 4},
- { "ss", REG_OFFSET(SegSs), 4},
-#elif defined(__APPLE__) && defined(__i386__)
- { "edi", REG_OFFSET(__edi), 4},
- { "esi", REG_OFFSET(__esi), 4},
- { "ebp", REG_OFFSET(__ebp), 4},
- { "esp", REG_OFFSET(__esp), 4},
- { "ebx", REG_OFFSET(__ebx), 4},
- { "edx", REG_OFFSET(__edx), 4},
- { "ecx", REG_OFFSET(__ecx), 4},
- { "eax", REG_OFFSET(__eax), 4},
- { "eflags", REG_OFFSET(__eflags), 4},
- { "eip", REG_OFFSET(__eip), 4},
-#elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__)
- { "edi", REG_OFFSET(r_edi), 4},
- { "esi", REG_OFFSET(r_esi), 4},
- { "ebp", REG_OFFSET(r_ebp), 4},
- { "esp", REG_OFFSET(r_esp), 4},
- { "ebx", REG_OFFSET(r_ebx), 4},
- { "edx", REG_OFFSET(r_edx), 4},
- { "ecx", REG_OFFSET(r_ecx), 4},
- { "eax", REG_OFFSET(r_eax), 4},
- { "eflags", REG_OFFSET(r_eflags), 4},
- { "eip", REG_OFFSET(r_eip), 4},
-#elif defined(__x86_64__)
- { "rax", REG_OFFSET(rax), 8},
- { "rbx", REG_OFFSET(rbx), 8},
- { "rcx", REG_OFFSET(rcx), 8},
- { "rdx", REG_OFFSET(rdx), 8},
- { "rsi", REG_OFFSET(rsi), 8},
- { "rdi", REG_OFFSET(rdi), 8},
- { "r8", REG_OFFSET(r8), 8},
- { "r9", REG_OFFSET(r9), 8},
- { "r10", REG_OFFSET(r10), 8},
- { "r11", REG_OFFSET(r11), 8},
- { "r12", REG_OFFSET(r12), 8},
- { "r13", REG_OFFSET(r13), 8},
- { "r14", REG_OFFSET(r14), 8},
- { "r15", REG_OFFSET(r15), 8},
- { "rbp", REG_OFFSET(rbp), 8},
- { "rsp", REG_OFFSET(rsp), 8},
- { "rip", REG_OFFSET(rip), 8},
- { "eflags", REG_OFFSET(eflags), 4},
- { "cs", REG_OFFSET(cs), 4},
- { "ss", REG_OFFSET(ss), 4},
- { "ds", REG_OFFSET(ds), 4},
- { "es", REG_OFFSET(es), 4},
- { "fs", REG_OFFSET(fs), 4},
- { "gs", REG_OFFSET(gs), 4},
- { "fs_base", REG_OFFSET(fs_base), 4},
- { "gs_base", REG_OFFSET(gs_base), 4},
-#elif defined(__i386__)
- { "edi", REG_OFFSET(edi), 4},
- { "esi", REG_OFFSET(esi), 4},
- { "ebp", REG_OFFSET(ebp), 4},
- { "esp", REG_OFFSET(esp), 4},
- { "ebx", REG_OFFSET(ebx), 4},
- { "edx", REG_OFFSET(edx), 4},
- { "ecx", REG_OFFSET(ecx), 4},
- { "eax", REG_OFFSET(eax), 4},
- { "eflags", REG_OFFSET(eflags), 4},
- { "eip", REG_OFFSET(eip), 4},
-#else
-# error "Unknown CPU"
-#endif
- { NULL, 0, 0},
-};
-
-#endif /* _WRS_KERNEL */
-
static short endianess_test = 0x0201;
#define BIG_ENDIAN_DATA (*(char *)&endianess_test == 0x02)
-static void write_context(OutputStream * out, char * id, Context * ctx, REG_INDEX * idx) {
+static void write_context(OutputStream * out, char * id, Context * ctx, int frame, RegisterDefinition * reg_def) {
assert(!ctx->exited);
write_stream(out, '{');
@@ -156,12 +54,12 @@ static void write_context(OutputStream * out, char * id, Context * ctx, REG_INDE
write_stream(out, ',');
json_write_string(out, "Name");
write_stream(out, ':');
- json_write_string(out, idx->regName);
+ json_write_string(out, reg_def->name);
write_stream(out, ',');
json_write_string(out, "Size");
write_stream(out, ':');
- json_write_long(out, REG_WIDTH(*idx));
+ json_write_long(out, reg_def->size);
write_stream(out, ',');
json_write_string(out, "Readable");
@@ -189,17 +87,20 @@ static void write_context(OutputStream * out, char * id, Context * ctx, REG_INDE
write_stream(out, 0);
}
-static int id2register(char * id, Context ** ctx, REG_INDEX ** idx) {
+static int id2register(char * id, Context ** ctx, int * frame, RegisterDefinition ** reg_def) {
int i;
char name[64];
+ RegisterDefinition * reg_defs = get_reg_definitions();
+
*ctx = NULL;
- *idx = NULL;
+ *frame = STACK_TOP_FRAME;
+ *reg_def = NULL;
if (*id++ != 'R') {
errno = ERR_INV_CONTEXT;
return -1;
}
i = 0;
- while (*id != '.') {
+ while (*id != '.' && *id != '@') {
if (*id == 0) {
errno = ERR_INV_CONTEXT;
return -1;
@@ -207,16 +108,30 @@ static int id2register(char * id, Context ** ctx, REG_INDEX ** idx) {
name[i++] = *id++;
}
name[i++] = 0;
+ if (*id == '@') {
+ int n = 0;
+ id++;
+ while (*id != '.') {
+ if (*id >= '0' && *id <= '9') {
+ n = n * 10 + (*id++ - '0');
+ }
+ else {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ }
+ *frame = n;
+ }
id++;
- for (i = 0; regs_index[i].regName != NULL; i++) {
- if (strcmp(regs_index[i].regName, name) == 0) break;
+ for (i = 0; reg_defs[i].name != NULL; i++) {
+ if (strcmp(reg_defs[i].name, name) == 0) break;
}
- if (regs_index[i].regName == NULL) {
+ if (reg_defs[i].name == NULL) {
errno = ERR_INV_CONTEXT;
return -1;
}
*ctx = id2ctx(id);
- *idx = regs_index + i;
+ *reg_def = reg_defs + i;
if (*ctx == NULL) {
errno = ERR_INV_CONTEXT;
return -1;
@@ -231,20 +146,21 @@ static int id2register(char * id, Context ** ctx, REG_INDEX ** idx) {
static void command_get_context(char * token, Channel * c) {
int err = 0;
char id[256];
+ int frame = 0;
Context * ctx = NULL;
- REG_INDEX * idx = NULL;
+ RegisterDefinition * reg_def = NULL;
json_read_string(&c->inp, id, sizeof(id));
if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
- if (id2register(id, &ctx, &idx) < 0) err = errno;
+ if (id2register(id, &ctx, &frame, &reg_def) < 0) err = errno;
write_stringz(&c->out, "R");
write_stringz(&c->out, token);
write_errno(&c->out, err);
if (err == 0) {
- write_context(&c->out, id, ctx, idx);
+ write_context(&c->out, id, ctx, frame, reg_def);
}
else {
write_stringz(&c->out, "null");
@@ -254,32 +170,50 @@ static void command_get_context(char * token, Channel * c) {
static void command_get_children(char * token, Channel * c) {
char id[256];
- pid_t pid, parent;
+ Context * ctx = NULL;
+ int frame = 0;
+ StackFrame * frame_info = NULL;
+ int err = 0;
json_read_string(&c->inp, id, sizeof(id));
if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
- pid = id2pid(id, &parent);
+ if (is_stack_frame_id(id, &ctx, &frame)) {
+ if (get_frame_info(ctx, frame, &frame_info) < 0) err = errno;
+ }
+ else {
+ pid_t pid, parent;
+ pid = id2pid(id, &parent);
+ if (pid != 0 && parent != 0) ctx = context_find_from_pid(pid);
+ frame = STACK_TOP_FRAME;
+ }
write_stringz(&c->out, "R");
write_stringz(&c->out, token);
- write_errno(&c->out, 0);
+ write_errno(&c->out, err);
write_stream(&c->out, '[');
- if (pid != 0 && parent != 0) {
- Context * ctx = context_find_from_pid(pid);
+ if (err == 0 && ctx != NULL && context_has_state(ctx)) {
if (ctx != NULL) {
+ int cnt = 0;
char t_id[128];
- REG_INDEX * idx = regs_index;
+ RegisterDefinition * reg_def;
strcpy(t_id, thread_id(ctx));
- while (idx->regName != NULL) {
- char r_id[128];
- if (idx != regs_index) write_stream(&c->out, ',');
- snprintf(r_id, sizeof(r_id), "R%s.%s", idx->regName, t_id);
- json_write_string(&c->out, r_id);
- idx ++;
+ for (reg_def = get_reg_definitions(); reg_def->name != NULL; reg_def++) {
+ if (frame == STACK_TOP_FRAME || read_reg_value(reg_def, frame_info, NULL) == 0) {
+ char r_id[128];
+ if (cnt > 0) write_stream(&c->out, ',');
+ if (frame == STACK_TOP_FRAME) {
+ snprintf(r_id, sizeof(r_id), "R%s.%s", reg_def->name, t_id);
+ }
+ else {
+ snprintf(r_id, sizeof(r_id), "R%s@%d.%s", reg_def->name, frame, t_id);
+ }
+ json_write_string(&c->out, r_id);
+ cnt++;
+ }
}
}
}
@@ -303,23 +237,35 @@ static void send_event_register_changed(Channel * c, char * id) {
static void command_get(char * token, Channel * c) {
int err = 0;
char id[256];
+ int frame = 0;
Context * ctx = NULL;
- REG_INDEX * idx = NULL;
+ RegisterDefinition * reg_def = NULL;
+ char * data = NULL;
json_read_string(&c->inp, id, sizeof(id));
if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
- if (id2register(id, &ctx, &idx) < 0) err = errno;
+ if (id2register(id, &ctx, &frame, &reg_def) < 0) err = errno;
else if (!ctx->intercepted) err = ERR_IS_RUNNING;
+ if (!err) {
+ if (is_top_frame(ctx, frame)) {
+ data = (char *)&ctx->regs + reg_def->offset;
+ }
+ else {
+ StackFrame * info = NULL;
+ if (get_frame_info(ctx, frame, &info)) err = errno;
+ else if (read_reg_value(reg_def, info, NULL) < 0) err = errno;
+ else data = (char *)&info->regs + reg_def->offset;
+ }
+ }
+
write_stringz(&c->out, "R");
write_stringz(&c->out, token);
write_errno(&c->out, err);
if (err == 0) {
- char * data = (char *)&ctx->regs + idx->regOff;
- int size = REG_WIDTH(*idx);
- json_write_binary(&c->out, data, size);
+ json_write_binary(&c->out, data, reg_def->size);
write_stream(&c->out, 0);
}
else {
@@ -334,8 +280,9 @@ static void command_set(char * token, Channel * c) {
char val[256];
int val_len = 0;
JsonReadBinaryState state;
+ int frame = 0;
Context * ctx = NULL;
- REG_INDEX * idx = NULL;
+ RegisterDefinition * reg_def = NULL;
json_read_string(&c->inp, id, sizeof(id));
if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
@@ -349,12 +296,13 @@ static void command_set(char * token, Channel * c) {
if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
- if (id2register(id, &ctx, &idx) < 0) err = errno;
+ if (id2register(id, &ctx, &frame, &reg_def) < 0) err = errno;
+ else if (!is_top_frame(ctx, frame)) err = ERR_INV_CONTEXT;
else if (!ctx->intercepted) err = ERR_IS_RUNNING;
if (err == 0) {
- char * data = (char *)&ctx->regs + idx->regOff;
- int size = REG_WIDTH(*idx);
+ char * data = (char *)&ctx->regs + reg_def->offset;
+ int size = reg_def->size;
if (val_len != size) {
err = ERR_INV_DATA_SIZE;
}
@@ -374,7 +322,9 @@ static void command_set(char * token, Channel * c) {
struct Location {
char id[256];
Context * ctx;
- REG_INDEX * idx;
+ int frame;
+ StackFrame * frame_info;
+ RegisterDefinition * reg_def;
unsigned offs;
unsigned size;
};
@@ -384,7 +334,7 @@ static Location * buf = NULL;
static int buf_pos = 0;
static int buf_len = 0;
-static int read_location_list(InputStream * inp) {
+static int read_location_list(InputStream * inp, int setm) {
int err = 0;
int ch = read_stream(inp);
@@ -417,14 +367,20 @@ static int read_location_list(InputStream * inp) {
buf = (Location *)loc_realloc(buf, buf_len * sizeof(Location));
}
loc = buf + buf_pos++;
+ memset(loc, 0, sizeof(Location));
json_read_string(inp, loc->id, sizeof(loc->id));
if (read_stream(inp) != ',') exception(ERR_JSON_SYNTAX);
loc->offs = (unsigned)json_read_ulong(inp);
if (read_stream(inp) != ',') exception(ERR_JSON_SYNTAX);
loc->size = (unsigned)json_read_ulong(inp);
if (read_stream(inp) != ']') exception(ERR_JSON_SYNTAX);
- if (id2register(loc->id, &loc->ctx, &loc->idx) < 0) err = errno;
+ if (id2register(loc->id, &loc->ctx, &loc->frame, &loc->reg_def) < 0) err = errno;
else if (!loc->ctx->intercepted) err = ERR_IS_RUNNING;
+ if (!err && !is_top_frame(loc->ctx, loc->frame)) {
+ if (setm) err = ERR_INV_CONTEXT;
+ else if (get_frame_info(loc->ctx, loc->frame, &loc->frame_info) < 0) err = errno;
+ else if (read_reg_value(loc->reg_def, loc->frame_info, NULL) < 0) err = errno;
+ }
}
ch = read_stream(inp);
if (ch == ',') continue;
@@ -437,7 +393,7 @@ static int read_location_list(InputStream * inp) {
}
static void command_getm(char * token, Channel * c) {
- int err = read_location_list(&c->inp);
+ int err = read_location_list(&c->inp, 0);
if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
@@ -450,7 +406,9 @@ static void command_getm(char * token, Channel * c) {
json_write_binary_start(&state, &c->out, -1);
for (i = 0; i < buf_pos; i++) {
Location * l = buf + i;
- char * data = (char *)&l->ctx->regs + l->idx->regOff + l->offs;
+ char * data = l->frame_info == NULL ?
+ (char *)&l->ctx->regs + l->reg_def->offset + l->offs :
+ (char *)&l->frame_info->regs + l->reg_def->offset + l->offs;
json_write_binary_data(&state, data, l->size);
}
json_write_binary_end(&state);
@@ -466,13 +424,15 @@ static void command_setm(char * token, Channel * c) {
int i = 0;
char tmp[256];
JsonReadBinaryState state;
- int err = read_location_list(&c->inp);
+ int err = read_location_list(&c->inp, 1);
if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
json_read_binary_start(&state, &c->inp);
for (i = 0; i < buf_pos; i++) {
unsigned rd_done = 0;
Location * l = buf + i;
- char * data = (char *)&l->ctx->regs + l->idx->regOff + l->offs;
+ char * data = l->frame_info == NULL ?
+ (char *)&l->ctx->regs + l->reg_def->offset + l->offs :
+ (char *)&l->frame_info->regs + l->reg_def->offset + l->offs;
while (rd_done < l->size) {
int rd = json_read_binary_data(&state, err ? tmp : (data + rd_done), l->size - rd_done);
if (rd == 0) break;
diff --git a/services/registers.h b/services/registers.h
index 987f8170..95d145a4 100644
--- a/services/registers.h
+++ b/services/registers.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/runctrl.c b/services/runctrl.c
index cf3861d8..eaf9794b 100644
--- a/services/runctrl.c
+++ b/services/runctrl.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/runctrl.h b/services/runctrl.h
index 43190a88..da0c3840 100644
--- a/services/runctrl.h
+++ b/services/runctrl.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/stacktrace.c b/services/stacktrace.c
index 3714f9e8..b6565f89 100644
--- a/services/stacktrace.c
+++ b/services/stacktrace.c
@@ -34,30 +34,21 @@
#include "stacktrace.h"
#include "breakpoints.h"
#include "symbols.h"
+#include "dwarfframe.h"
-static const char * STACKTRACE = "StackTrace";
+#define MAX_FRAMES 1000
-struct StackFrame {
- ContextAddress fp; /* frame address */
- ContextAddress ip; /* istruction pointer */
- ContextAddress rp; /* return address */
- ContextAddress fn; /* address of function */
- int arg_cnt; /* number of function arguments */
- ContextAddress args;/* address of function arguments */
-};
+static const char * STACKTRACE = "StackTrace";
struct StackTrace {
int error;
int frame_cnt;
int frame_max;
- struct StackFrame frames[1];
+ struct StackFrame frames[1]; /* ordered bottom to top */
};
-typedef struct StackFrame StackFrame;
typedef struct StackTrace StackTrace;
-static Context dump_stack_ctx;
-
static void add_frame(Context * ctx, StackFrame * frame) {
StackTrace * stack_trace = (StackTrace *)ctx->stack_trace;
if (stack_trace->frame_cnt >= stack_trace->frame_max) {
@@ -74,6 +65,8 @@ static void add_frame(Context * ctx, StackFrame * frame) {
#include <trcLib.h>
static Context * client_ctx;
+static int frame_cnt;
+static ContextAddress frame_rp;
static void vxworks_stack_trace_callback(
void * callAdrs, /* address from which function was called */
@@ -86,213 +79,91 @@ static void vxworks_stack_trace_callback(
{
StackFrame f;
memset(&f, 0, sizeof(f));
- f.rp = (ContextAddress)callAdrs;
- f.fn = (ContextAddress)funcAdrs;
- f.arg_cnt = nargs;
- f.args = (ContextAddress)args;
+ if (frame_cnt == 0) {
+ f.is_top_frame = 1;
+ f.regs = client_ctx->regs;
+ memset(&f.mask, 0xff, sizeof(f.mask));
+ }
+ else {
+ write_reg_value(get_PC_definition(), &f, frame_rp);
+ }
+ f.fp = (ContextAddress)args;
+ frame_rp = (ContextAddress)callAdrs;
add_frame(client_ctx, &f);
+ frame_cnt++;
}
static int trace_stack(Context * ctx) {
- int i;
- StackTrace * s;
client_ctx = ctx;
+ frame_cnt = 0;
trcStack(&ctx->regs, (FUNCPTR)vxworks_stack_trace_callback, ctx->pid);
- s = (StackTrace *)ctx->stack_trace;
- if (s->frame_cnt == 0) {
- vxworks_stack_trace_callback(NULL, 0, 0, NULL, ctx->pid, 1);
- }
- /* VxWorks stack trace is in reverse order - from bottom to top */
- for (i = 0; i < s->frame_cnt / 2; i++) {
- StackFrame f = s->frames[i];
- s->frames[i] = s->frames[s->frame_cnt - i - 1];
- s->frames[s->frame_cnt - i - 1] = f;
- }
- for (i = 0; i < s->frame_cnt; i++) {
- s->frames[i].ip = i == 0 ? get_regs_PC(ctx->regs) : s->frames[i - 1].rp;
- }
+ if (frame_cnt == 0) vxworks_stack_trace_callback(NULL, 0, 0, NULL, ctx->pid, 1);
return 0;
}
#else
-static int read_mem(Context * ctx, ContextAddress address, void * buf, size_t size) {
- if (ctx == &dump_stack_ctx) {
- /* Tracing current thread stack */
- memmove(buf, (void *)address, size);
- }
- else {
- if (context_read_mem(ctx, address, buf, size) < 0) return -1;
- check_breakpoints_on_memory_read(ctx, address, buf, size);
- }
- return 0;
-}
-
-#if defined(__i386__) || defined(__x86_64__)
-
-#define MAX_FRAMES 1000
-
-#define JMPD08 0xeb
-#define JMPD32 0xe9
-#define GRP5 0xff
-#define JMPN 0x25
-#define PUSH_EBP 0x55
-#define MOV_ESP00 0x89
-#define MOV_ESP01 0xe5
-#define MOV_ESP10 0x8b
-#define MOV_ESP11 0xec
-#define ENTER 0xc8
-#define RET 0xc3
-#define RETADD 0xc2
-#define REXW 0x48
+static int walk_frames(Context * ctx) {
+ unsigned cnt = 0;
+ StackFrame frame;
+ StackFrame down;
-/*
- * trace_jump - resolve any JMP instructions to final destination
- *
- * This routine returns a pointer to the next non-JMP instruction to be
- * executed if the pc were at the specified <adrs>. That is, if the instruction
- * at <adrs> is not a JMP, then <adrs> is returned. Otherwise, if the
- * instruction at <adrs> is a JMP, then the destination of the JMP is
- * computed, which then becomes the new <adrs> which is tested as before.
- * Thus we will eventually return the address of the first non-JMP instruction
- * to be executed.
- *
- * The need for this arises because compilers may put JMPs to instructions
- * that we are interested in, instead of the instruction itself. For example,
- * optimizers may replace a stack pop with a JMP to a stack pop. Or in very
- * UNoptimized code, the first instruction of a subroutine may be a JMP to
- * a PUSH %EBP MOV %ESP %EBP, instead of a PUSH %EBP MOV %ESP %EBP (compiler
- * may omit routine "post-amble" at end of parsing the routine!). We call
- * this routine anytime we are looking for a specific kind of instruction,
- * to help handle such cases.
- *
- * RETURNS: The address that a chain of branches points to.
- */
-static ContextAddress trace_jump(Context * ctx, ContextAddress addr) {
- int cnt = 0;
- /* while instruction is a JMP, get destination adrs */
- while (cnt < 100) {
- unsigned char instr; /* instruction opcode at <addr> */
- ContextAddress dest; /* Jump destination address */
- if (read_mem(ctx, addr, &instr, 1) < 0) break;
-
- /* If instruction is a JMP, get destination adrs */
- if (instr == JMPD08) {
- signed char disp08;
- if (read_mem(ctx, addr + 1, &disp08, 1) < 0) break;
- dest = addr + 2 + disp08;
- }
- else if (instr == JMPD32) {
- int disp32;
- assert(sizeof(disp32) == 4);
- if (read_mem(ctx, addr + 1, &disp32, 4) < 0) break;
- dest = addr + 5 + disp32;
- }
- else if (instr == GRP5) {
- ContextAddress ptr;
- if (read_mem(ctx, addr + 1, &instr, 1) < 0) break;
- if (instr != JMPN) break;
- if (read_mem(ctx, addr + 2, &ptr, sizeof(ptr)) < 0) break;
- if (read_mem(ctx, ptr, &dest, sizeof(dest)) < 0) break;
- }
- else {
- break;
+ memset(&frame, 0, sizeof(frame));
+ frame.is_top_frame = 1;
+ frame.regs = ctx->regs;
+ memset(&frame.mask, 0xff, sizeof(frame.mask));
+ while (cnt < MAX_FRAMES) {
+ memset(&down, 0, sizeof(down));
+#if ENABLE_ELF
+ {
+ int error = 0;
+ int found = 0;
+ ContextAddress ip = get_regs_PC(frame.regs);
+ ELF_File * file = elf_list_first(ctx, ip, ip + 1);
+ while (error == 0 && file != NULL) {
+ Trap trap;
+ if (set_trap(&trap)) {
+ get_dwarf_stack_frame_info(ctx, file, &frame, &down);
+ if (frame.fp != 0) found = 1;
+ clear_trap(&trap);
+ }
+ else {
+ error = trap.error;
+ }
+ if (error || found) break;
+ file = elf_list_next(ctx);
+ if (file == NULL) error = errno;
+ }
+ elf_list_done(ctx);
+ if (error) {
+ errno = error;
+ return -1;
+ }
}
- if (dest == addr) break;
- addr = dest;
+#endif
+ if (frame.fp == 0 && crawl_stack_frame(ctx, &frame, &down) < 0) return -1;
+ if (cnt > 0 && frame.fp == 0) break;
+ add_frame(ctx, &frame);
cnt++;
+ frame = down;
}
- return addr;
-}
-static int func_entry(unsigned char * code) {
- if (*code != PUSH_EBP) return 0;
- code++;
- if (*code == REXW) code++;
- if (code[0] == MOV_ESP00 && code[1] == MOV_ESP01) return 1;
- if (code[0] == MOV_ESP10 && code[1] == MOV_ESP11) return 1;
return 0;
}
static int trace_stack(Context * ctx) {
- ContextAddress pc = get_regs_PC(ctx->regs);
- ContextAddress fp = get_regs_BP(ctx->regs);
- ContextAddress fp_prev = 0;
-
- ContextAddress addr = trace_jump(ctx, pc);
- ContextAddress plt = is_plt_section(ctx, addr);
- unsigned char code[5];
- unsigned cnt = 0;
-
- /*
- * we don't have a stack frame in a few restricted but useful cases:
- * 1) we are at a PUSH %EBP MOV %ESP %EBP or RET or ENTER instruction,
- * 2) we are the first instruction of a subroutine (this may NOT be
- * a PUSH %EBP MOV %ESP %EBP instruction with some compilers)
- * 3) we are inside PLT entry
- */
-
- if (plt) {
- fp_prev = fp;
- if (addr - plt == 0) {
- fp = get_regs_SP(ctx->regs);
- }
- else if (addr - plt < sizeof(ContextAddress) * 4) {
- fp = get_regs_SP(ctx->regs) + sizeof(ContextAddress);
- }
- else if ((addr - plt) % (sizeof(ContextAddress) * 4) < sizeof(ContextAddress) * 2) {
- fp = get_regs_SP(ctx->regs) - sizeof(ContextAddress);
- }
- else {
- fp = get_regs_SP(ctx->regs);
- }
- }
- else {
- if (read_mem(ctx, addr - 1, code, sizeof(code)) < 0) return -1;
-
- if (func_entry(code + 1) || code[1] == ENTER || code[1] == RET || code[1] == RETADD) {
- fp_prev = fp;
- fp = get_regs_SP(ctx->regs) - sizeof(ContextAddress);
- }
- else if (func_entry(code)) {
- fp_prev = fp;
- fp = get_regs_SP(ctx->regs);
- }
- }
-
- while (cnt < MAX_FRAMES) {
- ContextAddress frame[2];
- ContextAddress fp_next;
- StackFrame f;
- memset(&f, 0, sizeof(f));
- f.ip = pc;
- if (fp == 0) {
- add_frame(ctx, &f);
- break;
- }
- if (read_mem(ctx, fp, frame, sizeof(frame)) < 0) {
- memset(frame, 0, sizeof(frame));
- }
- f.fp = fp;
- f.rp = frame[1];
- add_frame(ctx, &f);
- cnt++;
- fp_next = fp_prev != 0 ? fp_prev : frame[0];
- fp_prev = 0;
- if (fp_next <= fp) break;
- fp = fp_next;
- pc = f.rp;
+ int i;
+ StackTrace * s;
+ if (walk_frames(ctx) < 0) return -1;
+ s = (StackTrace *)ctx->stack_trace;
+ for (i = 0; i < s->frame_cnt / 2; i++) {
+ StackFrame f = s->frames[i];
+ s->frames[i] = s->frames[s->frame_cnt - i - 1];
+ s->frames[s->frame_cnt - i - 1] = f;
}
-
return 0;
}
-#else
-
-#error "Unknown CPU"
-
-#endif
-
#endif
static StackTrace * create_stack_trace(Context * ctx) {
@@ -308,6 +179,7 @@ static StackTrace * create_stack_trace(Context * ctx) {
else if (trace_stack(ctx) < 0) {
stack_trace = (StackTrace *)ctx->stack_trace;
stack_trace->error = errno;
+ /* TODO: need to save error message text in stack_trace */
}
else {
stack_trace = (StackTrace *)ctx->stack_trace;
@@ -348,31 +220,10 @@ static int id2frame(char * id, Context ** ctx, int * frame) {
return 0;
}
-static int id2frame_index(char * id, Context ** ctx, int * idx) {
- int frame = 0;
- StackTrace * s = NULL;
-
- if (id2frame(id, ctx, &frame) < 0) return -1;
-
- if (!(*ctx)->stopped) {
- errno = ERR_IS_RUNNING;
- return -1;
- }
- s = create_stack_trace(*ctx);
- if (s->error != 0) {
- errno = s->error;
- return -1;
- }
- if (frame < 0 || frame >= s->frame_cnt) {
- errno = ERR_INV_CONTEXT;
- return -1;
- }
+static void write_context(OutputStream * out, char * id, Context * ctx, int level, StackFrame * frame, StackFrame * down) {
+ uint64_t v;
+ RegisterDefinition * reg_def = get_PC_definition();
- *idx = s->frame_cnt - frame - 1;
- return 0;
-}
-
-static void write_context(OutputStream * out, char * id, Context * ctx, int level, StackFrame * frame) {
write_stream(out, '{');
json_write_string(out, "ID");
@@ -398,32 +249,18 @@ static void write_context(OutputStream * out, char * id, Context * ctx, int leve
json_write_ulong(out, frame->fp);
}
- if (frame->rp) {
- write_stream(out, ',');
- json_write_string(out, "RP");
- write_stream(out, ':');
- json_write_ulong(out, frame->rp);
- }
-
- if (frame->ip) {
+ if (read_reg_value(reg_def, frame, &v) == 0) {
write_stream(out, ',');
json_write_string(out, "IP");
write_stream(out, ':');
- json_write_ulong(out, frame->ip);
+ json_write_ulong(out, (ContextAddress)v);
}
- if (frame->arg_cnt) {
+ if (down != NULL && read_reg_value(reg_def, down, &v) == 0) {
write_stream(out, ',');
- json_write_string(out, "ArgsCnt");
- write_stream(out, ':');
- json_write_ulong(out, frame->arg_cnt);
- }
-
- if (frame->args) {
- write_stream(out, ',');
- json_write_string(out, "ArgsAddr");
+ json_write_string(out, "RP");
write_stream(out, ':');
- json_write_ulong(out, frame->args);
+ json_write_ulong(out, (ContextAddress)v);
}
write_stream(out, '}');
@@ -445,9 +282,9 @@ static void command_get_context(char * token, Channel * c) {
for (i = 0; i < id_cnt; i++) {
StackTrace * s = NULL;
Context * ctx = NULL;
- int idx = 0;
+ int frame = 0;
if (i > 0) write_stream(&c->out, ',');
- if (id2frame_index(ids[i], &ctx, &idx) < 0) {
+ if (id2frame(ids[i], &ctx, &frame) < 0) {
err = errno;
}
else if (!ctx->intercepted) {
@@ -456,12 +293,13 @@ static void command_get_context(char * token, Channel * c) {
else {
s = create_stack_trace(ctx);
}
- if (s == NULL || idx < 0 || idx >= s->frame_cnt) {
+ if (s == NULL || frame < 0 || frame >= s->frame_cnt) {
write_string(&c->out, "null");
}
else {
- int level = s->frame_cnt - idx - 1;
- write_context(&c->out, ids[i], ctx, level, s->frames + idx);
+ StackFrame * f = s->frames + frame;
+ StackFrame * d = frame > 0 ? f - 1 : NULL;
+ write_context(&c->out, ids[i], ctx, frame, f, d);
}
}
write_stream(&c->out, ']');
@@ -526,32 +364,6 @@ static void delete_stack_trace(Context * ctx, void * client_data) {
}
}
-void dump_stack_trace(void) {
-#ifdef WIN32
- dump_stack_ctx.handle = OpenThread(THREAD_GET_CONTEXT, FALSE, GetCurrentThreadId());
- memset(&dump_stack_ctx.regs, 0, sizeof(dump_stack_ctx.regs));
- dump_stack_ctx.regs.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
- if (GetThreadContext(dump_stack_ctx.handle, &dump_stack_ctx.regs) == 0) {
- set_win32_errno(GetLastError());
- trace(LOG_ALWAYS, "dump_stack_trace: Can't read thread registers: %d: %s",
- errno, errno_to_str(errno));
- }
- else {
- int i;
- StackTrace * s;
- trace(LOG_ALWAYS, "Stack trace:");
- s = create_stack_trace(&dump_stack_ctx);
- for (i = 0; i < s->frame_cnt; i++) {
- StackFrame * f = s->frames + i;
- trace(LOG_ALWAYS, " 0x%0*lx 0x%0*lx", sizeof(f->ip) * 2, f->ip, sizeof(f->fp) * 2, f->fp);
- }
- }
- CloseHandle(dump_stack_ctx.handle);
-#else
- trace(LOG_ALWAYS, "dump_stack_trace: not implemented");
-#endif
-}
-
int is_stack_frame_id(char * id, Context ** ctx, int * frame) {
return id2frame(id, ctx, frame) == 0;
}
@@ -582,10 +394,10 @@ char * get_stack_frame_id(Context * ctx, int frame) {
return id;
}
-int get_frame_info(Context * ctx, int frame, ContextAddress * ip, ContextAddress * rp, ContextAddress * fp) {
- StackFrame * f;
- StackTrace * s;
+int get_frame_info(Context * ctx, int frame, StackFrame ** info) {
+ StackTrace * stack;
+ *info = NULL;
if (ctx == NULL || !context_has_state(ctx)) {
errno = ERR_INV_CONTEXT;
return -1;
@@ -595,42 +407,33 @@ int get_frame_info(Context * ctx, int frame, ContextAddress * ip, ContextAddress
return -1;
}
- if (frame == STACK_TOP_FRAME && !rp && !fp && !ctx->regs_error) {
- /* Optimization: no need to perform stack trace */
- if (ip) *ip = get_regs_PC(ctx->regs);
- return 0;
- }
-
- s = create_stack_trace(ctx);
- if (s->error != 0) {
- errno = s->error;
+ stack = create_stack_trace(ctx);
+ if (stack->error != 0) {
+ errno = stack->error;
return -1;
}
if (frame == STACK_TOP_FRAME) {
- frame = s->frame_cnt - 1;
+ frame = stack->frame_cnt - 1;
}
- else if (frame < 0 || frame >= s->frame_cnt) {
+ else if (frame < 0 || frame >= stack->frame_cnt) {
errno = ERR_INV_CONTEXT;
return -1;
}
- f = s->frames + (s->frame_cnt - frame - 1);
- if (ip) *ip = f->ip;
- if (rp) *rp = f->rp;
- if (fp) *fp = f->fp;
+ *info = stack->frames + frame;
return 0;
}
int is_top_frame(Context * ctx, int frame) {
- StackTrace * s;
+ StackTrace * stack;
if (ctx == NULL || !context_has_state(ctx)) return 0;
if (!ctx->stopped) return 0;
if (frame == STACK_TOP_FRAME) return 1;
- s = create_stack_trace(ctx);
- if (s->error != 0) return 0;
- return frame == s->frame_cnt - 1;
+ stack = create_stack_trace(ctx);
+ if (stack->error != 0) return 0;
+ return frame == stack->frame_cnt - 1;
}
void ini_stack_trace_service(Protocol * proto, TCFBroadcastGroup * bcg) {
@@ -644,7 +447,6 @@ void ini_stack_trace_service(Protocol * proto, TCFBroadcastGroup * bcg) {
add_context_event_listener(&listener, bcg);
add_command_handler(proto, STACKTRACE, "getContext", command_get_context);
add_command_handler(proto, STACKTRACE, "getChildren", command_get_children);
- memset(&dump_stack_ctx, 0, sizeof(dump_stack_ctx));
}
#endif
diff --git a/services/stacktrace.h b/services/stacktrace.h
index 85b76c1d..9f309ef3 100644
--- a/services/stacktrace.h
+++ b/services/stacktrace.h
@@ -29,13 +29,6 @@
#if SERVICE_StackTrace
/*
- * Dump current stack trace into log.
- * The function can be used to debug the agent itself.
- */
-extern void dump_stack_trace(void);
-
-
-/*
* Check if given context ID is stack frame ID.
* Return 1 if frame ID, 0 otherwise.
*/
@@ -48,11 +41,8 @@ extern char * get_stack_frame_id(Context * ctx, int frame);
/*
* Get information about given stack frame.
- * ip - instruction pointer (in this frame)
- * rp - return pointer (parent frame instruction pointer)
- * fp - frame pointer (frame address on the thread stack)
*/
-extern int get_frame_info(Context * ctx, int frame, ContextAddress * ip, ContextAddress * rp, ContextAddress * fp);
+extern int get_frame_info(Context * ctx, int frame, StackFrame ** info);
/*
* Return 1 if 'frame' is the top frame of the context.
@@ -66,7 +56,7 @@ extern void ini_stack_trace_service(Protocol *, TCFBroadcastGroup *);
#else /* SERVICE_StackTrace */
-#define get_frame_info(ctx, frame, ip, rp, fp) (errno = ERR_UNSUPPORTED, -1)
+#define get_frame_info(ctx, frame, info) (errno = ERR_UNSUPPORTED, -1)
#define is_stack_frame_id(id, ctx, frame) 0
#define get_stack_frame_id(ctx, frame) NULL
#define is_top_frame(ctx, frame) (frame == STACK_TOP_FRAME)
diff --git a/services/symbols_elf.c b/services/symbols_elf.c
index 38977406..93718fd0 100644
--- a/services/symbols_elf.c
+++ b/services/symbols_elf.c
@@ -103,6 +103,7 @@ static void object2symbol(Context * ctx, ObjectInfo * obj, Symbol * sym) {
case TAG_set_type:
case TAG_subrange_type:
case TAG_base_type:
+ case TAG_fund_type:
case TAG_file_type:
case TAG_packed_type:
case TAG_thrown_type:
@@ -129,7 +130,15 @@ static void object2symbol(Context * ctx, ObjectInfo * obj, Symbol * sym) {
}
}
-static int find_in_object_tree(Context * ctx, ObjectInfo * list, ContextAddress ip, char * name, Symbol * sym) {
+static int get_num_prop(Context * ctx, int frame, ObjectInfo * obj, int at, U8_T * res) {
+ PropertyValue v;
+
+ if (read_and_evaluate_dwarf_object_property(ctx, frame, 0, obj, at, &v) < 0) return 0;
+ *res = get_numeric_property_value(&v);
+ return 1;
+}
+
+static int find_in_object_tree(Context * ctx, int frame, ObjectInfo * list, ContextAddress ip, char * name, Symbol * sym) {
int found = 0;
ObjectInfo * obj = list;
while (obj != NULL) {
@@ -139,7 +148,7 @@ static int find_in_object_tree(Context * ctx, ObjectInfo * list, ContextAddress
}
switch (obj->mTag) {
case TAG_enumeration_type:
- if (find_in_object_tree(ctx, obj->mChildren, ip, name, sym)) found = 1;
+ if (find_in_object_tree(ctx, frame, obj->mChildren, ip, name, sym)) found = 1;
break;
case TAG_global_subroutine:
case TAG_subroutine:
@@ -147,10 +156,14 @@ static int find_in_object_tree(Context * ctx, ObjectInfo * list, ContextAddress
case TAG_entry_point:
case TAG_lexical_block:
{
- ContextAddress addr0 = elf_map_to_run_time_address(ctx, obj->mCompUnit->mFile, obj->mLowPC);
- ContextAddress addr1 = obj->mHighPC - obj->mLowPC + addr0;
- if (addr0 != 0 && addr0 <= ip && addr1 > ip) {
- if (find_in_object_tree(ctx, obj->mChildren, ip, name, sym)) return 1;
+ U8_T LowPC, HighPC;
+ if (get_num_prop(ctx, frame, obj, AT_low_pc, &LowPC) &&
+ get_num_prop(ctx, frame, obj, AT_high_pc, &HighPC)) {
+ ContextAddress addr0 = elf_map_to_run_time_address(ctx, obj->mCompUnit->mFile, (ContextAddress)LowPC);
+ ContextAddress addr1 = (ContextAddress)(HighPC - LowPC) + addr0;
+ if (addr0 != 0 && addr0 <= ip && addr1 > ip) {
+ if (find_in_object_tree(ctx, frame, obj->mChildren, ip, name, sym)) return 1;
+ }
}
}
break;
@@ -160,16 +173,16 @@ static int find_in_object_tree(Context * ctx, ObjectInfo * list, ContextAddress
return found;
}
-static int find_in_dwarf(DWARFCache * cache, Context * ctx, char * name, ContextAddress ip, Symbol * sym) {
+static int find_in_dwarf(DWARFCache * cache, Context * ctx, int frame, char * name, ContextAddress ip, Symbol * sym) {
unsigned i;
for (i = 0; i < cache->mCompUnitsCnt; i++) {
CompUnit * unit = cache->mCompUnits[i];
ContextAddress addr0 = elf_map_to_run_time_address(ctx, unit->mFile, unit->mLowPC);
ContextAddress addr1 = unit->mHighPC - unit->mLowPC + addr0;
if (addr0 != 0 && addr0 <= ip && addr1 > ip) {
- if (find_in_object_tree(ctx, unit->mChildren, ip, name, sym)) return 1;
+ if (find_in_object_tree(ctx, frame, unit->mChildren, ip, name, sym)) return 1;
if (unit->mBaseTypes != NULL) {
- if (find_in_object_tree(ctx, unit->mBaseTypes->mChildren, ip, name, sym)) return 1;
+ if (find_in_object_tree(ctx, frame, unit->mBaseTypes->mChildren, ip, name, sym)) return 1;
}
return 0;
}
@@ -245,20 +258,23 @@ int find_symbol(Context * ctx, int frame, char * name, Symbol * sym) {
assert(ctx != NULL);
if (error == 0 && !found) {
- ContextAddress ip = 0;
+ U8_T ip = 0;
if (frame != STACK_NO_FRAME) {
- if (get_frame_info(ctx, frame, &ip, NULL, NULL) < 0) error = errno;
+ StackFrame * frame_info;
+ if (get_frame_info(ctx, frame, &frame_info) < 0) error = errno;
+ else if (read_reg_value(get_PC_definition(), frame_info, &ip)) error = errno;
}
if (error == 0) {
- ELF_File * file = elf_list_first(ctx, ip, ip == 0 ? ~(ContextAddress)0 : ip + 1);
+ ELF_File * file = elf_list_first(ctx, (ContextAddress)ip,
+ ip == 0 ? ~(ContextAddress)0 : (ContextAddress)(ip + 1));
if (file == NULL) error = errno;
while (error == 0 && file != NULL) {
Trap trap;
if (set_trap(&trap)) {
DWARFCache * cache = get_dwarf_cache(file);
- if (ip != 0) found = find_in_dwarf(cache, ctx, name, ip, sym);
+ if (ip != 0) found = find_in_dwarf(cache, ctx, frame, name, (ContextAddress)ip, sym);
if (!found) found = find_in_sym_table(cache, ctx, name, sym);
if (!found && ip != 0) {
char * s = NULL;
@@ -277,7 +293,7 @@ int find_symbol(Context * ctx, int frame, char * name, Symbol * sym) {
else if (strcmp(name, "signed long long") == 0) s = "long long int";
else if (strcmp(name, "signed long long int") == 0) s = "long long int";
else if (strcmp(name, "unsigned long long") == 0) s = "unsigned long long int";
- if (s != NULL) found = find_in_dwarf(cache, ctx, s, ip, sym);
+ if (s != NULL) found = find_in_dwarf(cache, ctx, frame, s, (ContextAddress)ip, sym);
}
clear_trap(&trap);
}
@@ -306,7 +322,8 @@ int find_symbol(Context * ctx, int frame, char * name, Symbol * sym) {
return 0;
}
-static void enumerate_local_vars(Context * ctx, ObjectInfo * obj, ContextAddress ip, int level, EnumerateSymbolsCallBack * call_back, void * args) {
+static void enumerate_local_vars(Context * ctx, int frame, ObjectInfo * obj,
+ ContextAddress ip, int level, EnumerateSymbolsCallBack * call_back, void * args) {
Symbol sym;
while (obj != NULL) {
switch (obj->mTag) {
@@ -316,10 +333,14 @@ static void enumerate_local_vars(Context * ctx, ObjectInfo * obj, ContextAddress
case TAG_entry_point:
case TAG_lexical_block:
{
- ContextAddress addr0 = elf_map_to_run_time_address(ctx, obj->mCompUnit->mFile, obj->mLowPC);
- ContextAddress addr1 = obj->mHighPC - obj->mLowPC + addr0;
- if (addr0 != 0 && addr0 <= ip && addr1 > ip) {
- enumerate_local_vars(ctx, obj->mChildren, ip, level + 1, call_back, args);
+ U8_T LowPC, HighPC;
+ if (get_num_prop(ctx, frame, obj, AT_low_pc, &LowPC) &&
+ get_num_prop(ctx, frame, obj, AT_high_pc, &HighPC)) {
+ ContextAddress addr0 = elf_map_to_run_time_address(ctx, obj->mCompUnit->mFile, (ContextAddress)LowPC);
+ ContextAddress addr1 = (ContextAddress)(HighPC - LowPC) + addr0;
+ if (addr0 != 0 && addr0 <= ip && addr1 > ip) {
+ enumerate_local_vars(ctx, frame, obj->mChildren, ip, level + 1, call_back, args);
+ }
}
}
break;
@@ -338,14 +359,17 @@ static void enumerate_local_vars(Context * ctx, ObjectInfo * obj, ContextAddress
int enumerate_symbols(Context * ctx, int frame, EnumerateSymbolsCallBack * call_back, void * args) {
int error = 0;
- ContextAddress ip = 0;
+ U8_T ip = 0;
if (frame != STACK_NO_FRAME) {
- if (get_frame_info(ctx, frame, &ip, NULL, NULL) < 0) error = errno;
+ StackFrame * frame_info;
+ if (get_frame_info(ctx, frame, &frame_info) < 0) error = errno;
+ else if (read_reg_value(get_PC_definition(), frame_info, &ip)) error = errno;
}
if (error == 0) {
- ELF_File * file = elf_list_first(ctx, ip, ip == 0 ? ~(ContextAddress)0 : ip + 1);
+ ELF_File * file = elf_list_first(ctx, (ContextAddress)ip,
+ ip == 0 ? ~(ContextAddress)0 : (ContextAddress)(ip + 1));
if (file == NULL) error = errno;
while (error == 0 && file != NULL) {
Trap trap;
@@ -358,7 +382,7 @@ int enumerate_symbols(Context * ctx, int frame, EnumerateSymbolsCallBack * call_
ContextAddress addr0 = elf_map_to_run_time_address(ctx, unit->mFile, unit->mLowPC);
ContextAddress addr1 = unit->mHighPC - unit->mLowPC + addr0;
if (addr0 != 0 && addr0 <= ip && addr1 > ip) {
- enumerate_local_vars(ctx, unit->mChildren, ip, 0, call_back, args);
+ enumerate_local_vars(ctx, frame, unit->mChildren, (ContextAddress)ip, 0, call_back, args);
break;
}
}
@@ -465,7 +489,7 @@ int id2symbol(char * id, Symbol * sym) {
if (*p == '.') p++;
dev = read_hex(&p);
if (*p == '.') p++;
- ino = read_hex(&p);
+ ino = (ino_t)read_hex(&p);
if (*p == '.') p++;
mtime = read_hex(&p);
if (*p == '.') p++;
@@ -609,14 +633,6 @@ static ObjectInfo * get_object_type(ObjectInfo * obj) {
return NULL;
}
-static int get_num_prop(Context * ctx, int frame, ObjectInfo * obj, int at, U8_T * res) {
- PropertyValue v;
-
- if (read_and_evaluate_dwarf_object_property(ctx, frame, 0, obj, at, &v) < 0) return 0;
- *res = get_numeric_property_value(&v);
- return 1;
-}
-
static U8_T get_object_length(Context * ctx, int frame, ObjectInfo * obj) {
U8_T x, y;
@@ -650,6 +666,7 @@ int get_symbol_type(const Symbol * sym, Symbol * type) {
}
int get_symbol_type_class(const Symbol * sym, int * type_class) {
+ U8_T x;
if (LOC(sym)->pointer) {
*type_class = LOC(sym)->size == 0 ? TYPE_CLASS_POINTER : TYPE_CLASS_ARRAY;
return 0;
@@ -687,25 +704,70 @@ int get_symbol_type_class(const Symbol * sym, int * type_class) {
*type_class = TYPE_CLASS_COMPOSITE;
return 0;
case TAG_base_type:
- switch (obj->mEncoding) {
- case ATE_address:
- *type_class = TYPE_CLASS_POINTER;
+ if (get_num_prop(sym->ctx, STACK_NO_FRAME, obj, AT_encoding, &x)) {
+ switch ((int)x) {
+ case ATE_address:
+ *type_class = TYPE_CLASS_POINTER;
+ return 0;
+ case ATE_boolean:
+ *type_class = TYPE_CLASS_INTEGER;
+ return 0;
+ case ATE_float:
+ *type_class = TYPE_CLASS_REAL;
+ return 0;
+ case ATE_signed:
+ case ATE_signed_char:
+ *type_class = TYPE_CLASS_INTEGER;
+ return 0;
+ case ATE_unsigned:
+ case ATE_unsigned_char:
+ *type_class = TYPE_CLASS_CARDINAL;
+ return 0;
+ }
+ }
+ *type_class = TYPE_CLASS_UNKNOWN;
+ return 0;
+ case TAG_fund_type:
+ switch (obj->mFundType) {
+ case FT_boolean:
+ *type_class = TYPE_CLASS_INTEGER;
return 0;
- case ATE_boolean:
+ case FT_char:
*type_class = TYPE_CLASS_INTEGER;
return 0;
- case ATE_float:
+ case FT_dbl_prec_float:
+ case FT_ext_prec_float:
+ case FT_float:
*type_class = TYPE_CLASS_REAL;
return 0;
- case ATE_signed:
- case ATE_signed_char:
+ case FT_signed_char:
+ case FT_signed_integer:
+ case FT_signed_long:
+ case FT_signed_short:
+ case FT_short:
+ case FT_integer:
+ case FT_long:
*type_class = TYPE_CLASS_INTEGER;
return 0;
- case ATE_unsigned:
- case ATE_unsigned_char:
+ case FT_unsigned_char:
+ case FT_unsigned_integer:
+ case FT_unsigned_long:
+ case FT_unsigned_short:
+ *type_class = TYPE_CLASS_CARDINAL;
+ return 0;
+ case FT_pointer:
+ *type_class = TYPE_CLASS_POINTER;
+ return 0;
+ case FT_void:
*type_class = TYPE_CLASS_CARDINAL;
return 0;
+ case FT_label:
+ case FT_complex:
+ case FT_dbl_prec_complex:
+ case FT_ext_prec_complex:
+ break;
}
+ *type_class = TYPE_CLASS_UNKNOWN;
return 0;
case TAG_subrange_type:
case TAG_packed_type:
@@ -1006,9 +1068,14 @@ int get_symbol_address(const Symbol * sym, int frame, ContextAddress * address)
if (unpack(sym) < 0) return -1;
if (obj != NULL && obj->mTag != TAG_member) {
U8_T v;
- if (!get_num_prop(sym->ctx, frame, obj, AT_location, &v)) return -1;
- *address = (ContextAddress)v;
- return 0;
+ if (get_num_prop(sym->ctx, frame, obj, AT_location, &v)) {
+ *address = (ContextAddress)v;
+ return 0;
+ }
+ if (get_num_prop(sym->ctx, frame, obj, AT_low_pc, &v)) {
+ *address = (ContextAddress)v;
+ return 0;
+ }
}
if (sym32 != NULL) {
switch (ELF32_ST_TYPE(sym32->st_info)) {
diff --git a/services/symbols_win32.c b/services/symbols_win32.c
index bde98853..ce3752b9 100644
--- a/services/symbols_win32.c
+++ b/services/symbols_win32.c
@@ -18,7 +18,7 @@
#include "config.h"
-#if SERVICE_Symbols && defined(_MSC_VER)
+#if SERVICE_Symbols && defined(_MSC_VER) && !ENABLE_ELF
#include <errno.h>
#include <assert.h>
@@ -106,7 +106,7 @@ typedef struct SymbolCacheEntry {
int error;
} SymbolCacheEntry;
-#define SYMBOL_CACHE_SIZE 101
+#define SYMBOL_CACHE_SIZE 153
static SymbolCacheEntry symbol_cache[SYMBOL_CACHE_SIZE];
static char * tmp_buf = NULL;
@@ -138,9 +138,11 @@ static size_t add_to_sym_buf(Symbol * sym) {
static int get_stack_frame(Context * ctx, int frame, IMAGEHLP_STACK_FRAME * stack_frame) {
memset(stack_frame, 0, sizeof(IMAGEHLP_STACK_FRAME));
if (frame != STACK_NO_FRAME && ctx->parent != NULL) {
- ContextAddress ip = 0;
- if (get_frame_info(ctx, frame, &ip, NULL, NULL) < 0) return -1;
- stack_frame->InstructionOffset = ip;
+ uint64_t v = 0;
+ StackFrame * frame_info;
+ if (get_frame_info(ctx, frame, &frame_info) < 0) return -1;
+ if (read_reg_value(get_PC_definition(), frame_info, &v) < 0) return -1;
+ stack_frame->InstructionOffset = v;
}
return 0;
}
@@ -694,9 +696,9 @@ int get_symbol_address(const Symbol * sym, int frame, ContextAddress * addr) {
*addr = (ContextAddress)info->Address;
if ((info->Flags & SYMFLAG_FRAMEREL) || (info->Flags & SYMFLAG_REGREL)) {
- ContextAddress fp = 0;
- if (get_frame_info(sym->ctx, frame, NULL, NULL, &fp) < 0) return -1;
- *addr += fp;
+ StackFrame * frame_info;
+ if (get_frame_info(sym->ctx, frame, &frame_info) < 0) return -1;
+ *addr += frame_info->fp - sizeof(ContextAddress) * 2;
}
return 0;
diff --git a/services/sysmon.c b/services/sysmon.c
index b371f077..081cc60e 100644
--- a/services/sysmon.c
+++ b/services/sysmon.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/sysmon.h b/services/sysmon.h
index a7b56556..20732caa 100644
--- a/services/sysmon.h
+++ b/services/sysmon.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
diff --git a/services/tcf_elf.c b/services/tcf_elf.c
index 53694dff..37176b92 100644
--- a/services/tcf_elf.c
+++ b/services/tcf_elf.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -66,12 +66,12 @@ static void elf_dispose(ELF_File * file) {
}
if (file->fd >= 0) close(file->fd);
if (file->sections != NULL) {
+#ifdef USE_MMAP
for (n = 0; n < file->section_cnt; n++) {
ELF_Section * s = file->sections + n;
-#ifdef USE_MMAP
if (s->mmap_addr != NULL) munmap(s->mmap_addr, s->mmap_size);
-#endif
}
+#endif
loc_free(file->sections);
}
loc_free(file->pheaders);
@@ -331,7 +331,7 @@ ELF_File * elf_open(char * file_name) {
sec->type = shdr.sh_type;
sec->offset = shdr.sh_offset;
sec->size = shdr.sh_size;
- sec->flags = shdr.sh_flags;
+ sec->flags = (U4_T)shdr.sh_flags;
sec->addr = shdr.sh_addr;
sec->link = shdr.sh_link;
sec->info = shdr.sh_info;
@@ -366,7 +366,7 @@ ELF_File * elf_open(char * file_name) {
p->file_size = phdr.p_filesz;
p->mem_size = phdr.p_memsz;
p->flags = phdr.p_flags;
- p->align = phdr.p_align;
+ p->align = (U4_T)phdr.p_align;
cnt++;
}
}
@@ -425,6 +425,21 @@ int elf_load(ELF_Section * s) {
#endif
}
+U8_T elf_read_section(ELF_Section * section, uintptr_t offset, size_t size) {
+ U1_T buf[8];
+ if (section->data == NULL && elf_load(section) < 0) exception(errno);
+ memcpy(buf, (U1_T *)section->data + offset, size);
+ if (section->file->byte_swap) swap_bytes(buf, size);
+ switch (size) {
+ case 1: return *(U1_T *)buf;
+ case 2: return *(U2_T *)buf;
+ case 4: return *(U4_T *)buf;
+ case 8: return *(U8_T *)buf;
+ }
+ exception(ERR_INV_DATA_SIZE);
+ return 0;
+}
+
void elf_close(ELF_File * file) {
assert(file != NULL);
assert(file->ref_cnt > 0);
diff --git a/services/tcf_elf.h b/services/tcf_elf.h
index a16a639b..adaabaf7 100644
--- a/services/tcf_elf.h
+++ b/services/tcf_elf.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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.
@@ -172,6 +172,8 @@ typedef struct Elf32_Shdr {
Elf32_Word sh_entsize;
} Elf32_Shdr;
+#define SHF_ALLOC 0x00000002
+
typedef struct Elf32_Phdr {
Elf32_Word p_type;
Elf32_Off p_offset;
@@ -399,6 +401,12 @@ extern void elf_list_done(Context * ctx);
extern int elf_load(ELF_Section * section);
/*
+ * Read a binary value of given size from ELF section, adjust endianness if necessary
+.
+ */
+extern U8_T elf_read_section(ELF_Section * section, uintptr_t offset, size_t size);
+
+/*
* Register ELF file close callback.
* The callback is called each time an ELF file data is about to be disposed.
* Service implementation can use the callback to deallocate

Back to the top