duran 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.rdoc +11 -0
- data/Rakefile +29 -0
- data/VERSION +1 -0
- data/client_src/dr_include/dr_api.h +102 -0
- data/client_src/dr_include/dr_app.h +92 -0
- data/client_src/dr_include/dr_config.h +650 -0
- data/client_src/dr_include/dr_defines.h +391 -0
- data/client_src/dr_include/dr_events.h +1057 -0
- data/client_src/dr_include/dr_ir_instr.h +1214 -0
- data/client_src/dr_include/dr_ir_instrlist.h +149 -0
- data/client_src/dr_include/dr_ir_macros.h +2426 -0
- data/client_src/dr_include/dr_ir_opcodes.h +768 -0
- data/client_src/dr_include/dr_ir_opnd.h +1170 -0
- data/client_src/dr_include/dr_ir_utils.h +708 -0
- data/client_src/dr_include/dr_proc.h +327 -0
- data/client_src/dr_include/dr_tools.h +1304 -0
- data/client_src/duran.c +57 -0
- data/client_src/extconf.rb +28 -0
- data/lib/duran.rb +18 -0
- data/lib/duran/app.rb +8 -0
- data/lib/duran/defines.rb +39 -0
- data/lib/duran/events.rb +156 -0
- data/lib/duran/ir_opcodes.rb +616 -0
- data/lib/duran/ir_opnd.rb +329 -0
- data/lib/duran/ir_utils.rb +133 -0
- data/lib/duran/proc.rb +49 -0
- data/lib/duran/structs.rb +20 -0
- data/lib/duran/structs/exception.rb +23 -0
- data/lib/duran/structs/fault_fragment_info.rb +34 -0
- data/lib/duran/structs/instruction.rb +15 -0
- data/lib/duran/structs/machine_context.rb +80 -0
- data/lib/duran/structs/memory_info.rb +12 -0
- data/lib/duran/structs/module_data.rb +61 -0
- data/lib/duran/structs/module_names.rb +24 -0
- data/lib/duran/structs/operand.rb +15 -0
- data/lib/duran/structs/restore_state_info.rb +30 -0
- data/lib/duran/structs/signal_info.rb +41 -0
- data/lib/duran/structs/tracedump.rb +50 -0
- data/lib/duran/tools.rb +214 -0
- metadata +104 -0
data/lib/duran/proc.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
# XXX feature_bit_t is an enum, but there's gaps and i'm feeling lazy atm
|
4
|
+
typedef :uint, :feature_bit_t
|
5
|
+
|
6
|
+
enum :cache_size_t, [
|
7
|
+
:CACHE_SIZE_8_KB, #/**< L1 or L2 cache size of 8 KB. */
|
8
|
+
:CACHE_SIZE_16_KB, #/**< L1 or L2 cache size of 16 KB. */
|
9
|
+
:CACHE_SIZE_32_KB, #/**< L1 or L2 cache size of 32 KB. */
|
10
|
+
:CACHE_SIZE_64_KB, #/**< L1 or L2 cache size of 64 KB. */
|
11
|
+
:CACHE_SIZE_128_KB, #/**< L1 or L2 cache size of 128 KB. */
|
12
|
+
:CACHE_SIZE_256_KB, #/**< L1 or L2 cache size of 256 KB. */
|
13
|
+
:CACHE_SIZE_512_KB, #/**< L1 or L2 cache size of 512 KB. */
|
14
|
+
:CACHE_SIZE_1_MB, #/**< L1 or L2 cache size of 1 MB. */
|
15
|
+
:CACHE_SIZE_2_MB, #/**< L1 or L2 cache size of 2 MB. */
|
16
|
+
:CACHE_SIZE_UNKNOWN #/**< Unknown L1 or L2 cache size. */
|
17
|
+
]
|
18
|
+
|
19
|
+
enum :vendor_t, [:intel, :amd, :unknown]
|
20
|
+
|
21
|
+
|
22
|
+
attach_function :proc_get_cache_line_size, [], :size_t
|
23
|
+
attach_function :proc_is_cache_aligned, [:pointer], :bool
|
24
|
+
attach_function :proc_bump_to_end_of_cache_line, [:ptr_uint_t], :ptr_uint_t
|
25
|
+
attach_function :proc_get_containing_page, [:pointer], :pointer
|
26
|
+
attach_function :proc_get_vendor, [], :vendor_t
|
27
|
+
attach_function :proc_get_family, [], :uint
|
28
|
+
attach_function :proc_get_type, [], :uint
|
29
|
+
attach_function :proc_get_model, [], :uint
|
30
|
+
attach_function :proc_get_stepping, [], :uint
|
31
|
+
attach_function :proc_get_brand_string, [], :string
|
32
|
+
attach_function :proc_get_L1_icache_size, [], :cache_size_t
|
33
|
+
attach_function :proc_get_L1_dcache_size, [], :cache_size_t
|
34
|
+
attach_function :proc_get_L2_cache_size, [], :cache_size_t
|
35
|
+
attach_function :proc_get_cache_size_str, [:cache_size_t], :string
|
36
|
+
attach_function :proc_fpstate_save_size, [], :size_t
|
37
|
+
attach_function :proc_save_fpstate, [:pointer], :size_t
|
38
|
+
attach_function :proc_restore_fpstate, [:pointer], :void
|
39
|
+
attach_function :proc_has_feature, [:feature_bit_t], :bool
|
40
|
+
attach_function :proc_get_all_feature_bits, [], :pointer
|
41
|
+
|
42
|
+
attach_function :dr_insert_save_fpstate,
|
43
|
+
[:dr_ctx_t, :pointer, :pointer, Operand], :void
|
44
|
+
|
45
|
+
attach_function :dr_insert_restore_fpstate,
|
46
|
+
[:dr_ctx_t, :pointer, :pointer, Operand], :void
|
47
|
+
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
class DRYStruct < FFI::Struct
|
4
|
+
include FFI::DRY::StructHelper
|
5
|
+
end
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'duran/structs/operand'
|
10
|
+
require 'duran/structs/instruction'
|
11
|
+
require 'duran/structs/machine_context'
|
12
|
+
require 'duran/structs/fault_fragment_info'
|
13
|
+
require 'duran/structs/restore_state_info'
|
14
|
+
require 'duran/structs/exception'
|
15
|
+
require 'duran/structs/signal_info'
|
16
|
+
require 'duran/structs/memory_info'
|
17
|
+
require 'duran/structs/module_names'
|
18
|
+
require 'duran/structs/module_data'
|
19
|
+
require 'duran/structs/tracedump'
|
20
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
class Exception < DRYStruct
|
4
|
+
dsl_layout do
|
5
|
+
struct :mcontext, MachineContext, :desc => "Context at exception point"
|
6
|
+
|
7
|
+
field :record, :pointer, :desc => "Ptr. to the Win32 EXCEPTION_RECORD"
|
8
|
+
|
9
|
+
# aligns to 8 bytes to avoid differences in padding... XXX TODO confirm!
|
10
|
+
|
11
|
+
struct :raw_mcontext, MachineContext, :desc => \
|
12
|
+
"The raw pre-translated machine state at the exception interruption "+
|
13
|
+
"point inside the code cache. Clients are cautioned when examining "+
|
14
|
+
"code cache instructions to not rely on any details of code inserted "+
|
15
|
+
"other than their own."
|
16
|
+
|
17
|
+
struct :fault_fragment_info, FaultFragmentInfo, :desc => \
|
18
|
+
"Information about the code fragment inside the code cache at "+
|
19
|
+
"the exception interruption point. "
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Duran
|
2
|
+
# See _dr_fault_fragment_info_t in dr_events.h
|
3
|
+
#
|
4
|
+
# Data structure passed within dr_exception_t, dr_siginfo_t, and
|
5
|
+
# dr_restore_state_info_t.
|
6
|
+
# Contains information about the code fragment inside the code cache
|
7
|
+
# at the exception/signal/translation interruption point.
|
8
|
+
class FaultFragmentInfo < DRYStruct
|
9
|
+
dsl_layout do
|
10
|
+
field :tag, :pointer, :desc => \
|
11
|
+
"The tag of the code fragment inside the code cache at the "+
|
12
|
+
"exception/signal/translation interruption point. NULL for "+
|
13
|
+
"interruption not in the code cache."
|
14
|
+
|
15
|
+
field :cache_start_pc, :pointer, :desc => \
|
16
|
+
"The start address of the code fragment inside the code cache at "+
|
17
|
+
"the exception/signal/translation interruption point. NULL for "+
|
18
|
+
"interruption not in the code cache. "+
|
19
|
+
"Clients are cautioned when examining code cache instructions to not"+
|
20
|
+
"rely on any details of code inserted other than their own. "
|
21
|
+
|
22
|
+
field :is_trace, :bool, :desc => \
|
23
|
+
"Indicates whether the interrupted code fragment is a trace"
|
24
|
+
|
25
|
+
field :app_code_consistent, :bool, :desc => \
|
26
|
+
"Indicates whether the original application code containing the "+
|
27
|
+
"code corresponding to the exception/signal/translation interruption "+
|
28
|
+
"point is guaranteed to still be in the same state it was when the "+
|
29
|
+
"code was placed in the code cache. This guarantee varies "+
|
30
|
+
"depending on the type of cache consistency being used by DR."
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
# Internal structure of instr_t is below abstraction layer, but we
|
4
|
+
# provide its size so that it can be used in stack variables
|
5
|
+
# instead of always allocated on the heap.
|
6
|
+
class Instruction < DRYStruct
|
7
|
+
dsl_layout do
|
8
|
+
if ::Duran::ARCH == :x64
|
9
|
+
array :black_box_uint, [:uint, 26]
|
10
|
+
else
|
11
|
+
array :black_box_uint, [:uint, 16]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
class MachineContext < DRYStruct
|
4
|
+
NUM_XMM_SLOTS =
|
5
|
+
::Duran::ARCH == :x64 ? ( ::Duran::PLATFORM == :windows ? 6 : 16) : 8
|
6
|
+
|
7
|
+
# comment from dr_defines.h:
|
8
|
+
#
|
9
|
+
# The SSE registers xmm0-xmm5 (-xmm15 on Linux) are volatile
|
10
|
+
# (caller-saved) for 64-bit and WOW64, and are actually zeroed out on
|
11
|
+
# Windows system calls. These fields are ignored for 32-bit processes
|
12
|
+
# that are not WOW64, or if the underlying processor does not support
|
13
|
+
# SSE. Use dr_mcontext_xmm_fields_valid() to determine whether the
|
14
|
+
# fields are valid.
|
15
|
+
class XMM_t < FFI::Struct
|
16
|
+
# Really a union, but FFI structs and unions with arrays are lots
|
17
|
+
# of broken so we fake it with our own helper methods.
|
18
|
+
layout :u8_stub, [:uchar, 16]
|
19
|
+
|
20
|
+
def u8
|
21
|
+
self[:u8_stub].to_a
|
22
|
+
end
|
23
|
+
|
24
|
+
def u64
|
25
|
+
self[:u8_stub].to_ptr.get_array_of_uint64(0,2)
|
26
|
+
end
|
27
|
+
|
28
|
+
def u32
|
29
|
+
self[:u8_stub].to_ptr.get_array_of_uint32(0,4)
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method :reg, (::Duran::ARCH == :x64 ? :u64 : :u32)
|
33
|
+
end
|
34
|
+
|
35
|
+
dsl_layout do
|
36
|
+
field :xdi, :reg_t, :desc => "platform-independent rdi/edi register"
|
37
|
+
field :xsi, :reg_t, :desc => "platform-independent rsi/esi register"
|
38
|
+
field :xbp, :reg_t, :desc => "platform-independent rbp/ebp register"
|
39
|
+
field :xsp, :reg_t, :desc => "platform-independent rsp/esp register"
|
40
|
+
field :xbx, :reg_t, :desc => "platform-independent rbx/ebx register"
|
41
|
+
field :xdx, :reg_t, :desc => "platform-independent rdx/edx register"
|
42
|
+
field :xcx, :reg_t, :desc => "platform-independent rcx/ecx register"
|
43
|
+
field :xax, :reg_t, :desc => "platform-independent rax/eax register"
|
44
|
+
if ::Duran::ARCH == :x64
|
45
|
+
field :r8, :reg_t, :desc => "r8 register"
|
46
|
+
field :r9, :reg_t, :desc => "r9 register"
|
47
|
+
field :r10, :reg_t, :desc => "r10 register"
|
48
|
+
field :r11, :reg_t, :desc => "r11 register"
|
49
|
+
field :r12, :reg_t, :desc => "r12 register"
|
50
|
+
field :r13, :reg_t, :desc => "r13 register"
|
51
|
+
field :r14, :reg_t, :desc => "r14 register"
|
52
|
+
field :r15, :reg_t, :desc => "r15 register"
|
53
|
+
end
|
54
|
+
array :xmm_stub, [:uchar, NUM_XMM_SLOTS*XMM_t.size]
|
55
|
+
field :xflags, :reg_t, :desc => 'platform-independent rflags/eflags register'
|
56
|
+
field :xip, :pointer, :desc => "platform-independent rip/eip register"
|
57
|
+
end
|
58
|
+
|
59
|
+
alias_method :pc, :xip
|
60
|
+
alias_method :pc=, :xip=
|
61
|
+
|
62
|
+
# Create e/r aliases for all the platform-independent register accessors
|
63
|
+
# named based on our architecture.
|
64
|
+
reg_pfx = ::Duran::ARCH == :x64 ? "r" : "e"
|
65
|
+
[:di, :si, :bp, :sp, :bx, :dx, :cx, :ax, :flags, :ip].each do |reg_sfx|
|
66
|
+
alias_method :"#{reg_pfx}#{reg_sfx}", :"x#{reg_sfx}"
|
67
|
+
alias_method :"#{reg_pfx}#{reg_sfx}=", :"x#{reg_sfx}="
|
68
|
+
end
|
69
|
+
|
70
|
+
def xmm
|
71
|
+
off=0
|
72
|
+
Array.new(NUM_XMM_SLOTS) do
|
73
|
+
r = XMM_t.new(self[:xmm_stub].to_ptr+off)
|
74
|
+
off += XMM_t.size
|
75
|
+
r
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Duran
|
2
|
+
enum :mem_type, [:free, :image, :data]
|
3
|
+
|
4
|
+
class MemoryInfo < DRYStruct
|
5
|
+
dsl_layout do
|
6
|
+
field :base_pc, :pointer, :desc => "Starting address of memory region"
|
7
|
+
field :mem_size, :size_t, :desc => "Size of region"
|
8
|
+
field :prot, :uint, :desc => "Protection of region (MEMPROT_* flags)"
|
9
|
+
field :mem_type, :uint, :desc => "Type of region"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
|
4
|
+
class ModuleData < DRYStruct
|
5
|
+
|
6
|
+
class VersionNumber < DRYStruct
|
7
|
+
dsl_layout do
|
8
|
+
field :p2, :ushort
|
9
|
+
field :p1, :ushort
|
10
|
+
field :p4, :ushort
|
11
|
+
field :p3, :ushort
|
12
|
+
end
|
13
|
+
|
14
|
+
def ms
|
15
|
+
to_ptr.get_uint32(0)
|
16
|
+
end
|
17
|
+
|
18
|
+
def ls
|
19
|
+
to_ptr.get_uint32(4)
|
20
|
+
end
|
21
|
+
|
22
|
+
def version
|
23
|
+
to_ptr.get_uint64(0)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
dsl_layout do
|
28
|
+
field :start_addr, :app_pc,
|
29
|
+
:desc => 'starting address of this module'
|
30
|
+
|
31
|
+
field :end_addr, :app_pc,
|
32
|
+
:desc => 'ending address of this module'
|
33
|
+
|
34
|
+
field :entry_point, :app_pc,
|
35
|
+
:desc => 'entry point for this module as specified in the headers'
|
36
|
+
|
37
|
+
field :flags, :uint, :desc => 'Reserved, set to 0'
|
38
|
+
|
39
|
+
struct :names, ModuleNames,
|
40
|
+
:desc => 'struct containing names for this module.'
|
41
|
+
|
42
|
+
field :full_path, :string,
|
43
|
+
:desc => 'full path to the file backing this module'
|
44
|
+
|
45
|
+
if ::Duran::PLATFORM == :windows
|
46
|
+
struct :file_version, VersionNumber,
|
47
|
+
:desc => "file version number from .rsrc section"
|
48
|
+
|
49
|
+
struct :product_version, VersionNumber,
|
50
|
+
:desc => "product version number from .rsrc section"
|
51
|
+
|
52
|
+
field :module_internal_size, :size_t,
|
53
|
+
:desc => "module internal size (from PE headers SizeOfImage)"
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
alias_method :handle, :start_addr
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
class ModuleNames < DRYStruct
|
4
|
+
dsl_layout do
|
5
|
+
field :module_name, :string,
|
6
|
+
:desc => "The name of the module from the PE or ELF header."
|
7
|
+
|
8
|
+
field :file_name, :string,
|
9
|
+
:desc => "The file name used to load this module."
|
10
|
+
|
11
|
+
if PLATFORM == :windows
|
12
|
+
field :exe_name, :string,
|
13
|
+
:desc => "The executable name used to launch the process."
|
14
|
+
|
15
|
+
field :rsrc_name, :string,
|
16
|
+
:desc => "The internal name given to the module in its resource."
|
17
|
+
|
18
|
+
else # :linux
|
19
|
+
field :inode, :uint64, :desc => "The inode of the module mapped in."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Duran
|
2
|
+
# Internal structure of opnd_t is below abstraction layer
|
3
|
+
# but FFI needs to know field sizes to copy it around
|
4
|
+
class Operand < DRYStruct
|
5
|
+
dsl_layout do
|
6
|
+
if ::Duran::ARCH == :x64
|
7
|
+
field :black_box_uint, :uint
|
8
|
+
field :black_box_uint64, :uint64
|
9
|
+
else
|
10
|
+
array :black_box_uint, [:uint, 3]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
# see _dr_restore_state_info_t in dr_events.h
|
4
|
+
#
|
5
|
+
# Data structure passed to a restore_state_ex event handler (see
|
6
|
+
# dr_register_restore_state_ex_event()). Contains the machine
|
7
|
+
# context at the translation point and other translation
|
8
|
+
# information.
|
9
|
+
class RestoreStateInfo < DRYStruct
|
10
|
+
dsl_layout do
|
11
|
+
struct :mcontext, MachineContext, :desc => \
|
12
|
+
"The application machine state at the translation point."
|
13
|
+
|
14
|
+
field :raw_mcontext_valid, :bool, :desc => \
|
15
|
+
"Whether raw_mcontext is valid."
|
16
|
+
|
17
|
+
struct :raw_mcontext, MachineContext, :desc => \
|
18
|
+
"The raw pre-translated machine state at the translation "+
|
19
|
+
"interruption point inside the code cache. Clients are "+
|
20
|
+
"cautioned when examining code cache instructions to not rely on "+
|
21
|
+
"any details of code inserted other than their own."
|
22
|
+
|
23
|
+
struct :fault_fragment, FaultFragmentInfo, :desc => \
|
24
|
+
"Information about the code fragment inside the code cache "+
|
25
|
+
"at the translation interruption point."
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
|
4
|
+
# Data structure passed with a signal event. Contains the machine
|
5
|
+
# context at the signal interruption point and other signal
|
6
|
+
# information.
|
7
|
+
class SignalInfo < DRYStruct
|
8
|
+
dsl_layout do
|
9
|
+
field :sig, :int, :desc => "The signal number."
|
10
|
+
|
11
|
+
field :context, :pointer, :desc => \
|
12
|
+
"The context of the thread receiving the signal."
|
13
|
+
|
14
|
+
struct :mcontext, MachineContext, :desc => \
|
15
|
+
"The application machine state at the signal interruption point."
|
16
|
+
|
17
|
+
struct :raw_mcontext, MachineContext, :desc => \
|
18
|
+
"The raw pre-translated machine state at the signal interruption "+
|
19
|
+
"point inside the code cache. NULL for delayable signals. Clients "+
|
20
|
+
"are cautioned when examining code cache instructions to not rely on "+
|
21
|
+
"any details of code inserted other than their own."
|
22
|
+
|
23
|
+
field :raw_mcontext_valid, :bool, :desc => "Whether raw_context is valid"
|
24
|
+
|
25
|
+
field :access_address, :pointer, :desc => \
|
26
|
+
"For SIGBUS and SIGSEGV, the address whose access caused the signal "+
|
27
|
+
"to be raised (as calculated by DR)."
|
28
|
+
|
29
|
+
field :blocked, :bool, :desc => \
|
30
|
+
"Indicates this signal is blocked. DR_SIGNAL_BYPASS is not allowed, "+
|
31
|
+
"and a second event will be sent if the signal is later delivered to "+
|
32
|
+
"the application. Events are only sent for blocked non-delayable "+
|
33
|
+
"signals, not for delayable signals."
|
34
|
+
|
35
|
+
struct :fault_fragment_info, FaultFragmentInfo, :desc => \
|
36
|
+
"Information about the code fragment inside the code cache "+
|
37
|
+
"at the signal interruption point."
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
module Duran
|
3
|
+
class TracedumpFileHeader < DRYStruct
|
4
|
+
dsl_layout do
|
5
|
+
field :version, :int,
|
6
|
+
:desc => "The DynamoRIO version that created the file"
|
7
|
+
|
8
|
+
field :x64, :bool,
|
9
|
+
:desc => "Whether a 64-bit DynamoRIO library created the file."
|
10
|
+
|
11
|
+
field :linkcount_size, :int,
|
12
|
+
:desc => "Size of the linkcount (linkcounts are deprecated)"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class TraceDumpTraceHeader < DRYStruct
|
17
|
+
dsl_layout do
|
18
|
+
field :frag_id, :int, :desc => "Identifier for the trace"
|
19
|
+
field :tag, :app_pc, :desc => "Application address for start of trace"
|
20
|
+
field :cache_start, :app_pc, :desc => "Code cache start address."
|
21
|
+
field :entry_offs, :int, :desc => "Offset into trace of normal entry."
|
22
|
+
field :num_exits, :int, :desc => "Number of exits from the trace."
|
23
|
+
field :code_size, :int, :desc => "Length of the trace in the code cache"
|
24
|
+
field :num_bbs, :uint, :desc => "Number of bbs making up the trace"
|
25
|
+
field :x64, :bool, :desc => "Whether the trace contains 64-bit code"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class TraceDumpStubData < DRYStruct
|
30
|
+
class Count < FFI::Union
|
31
|
+
layout :count32, :uint32, :count64, :uint64
|
32
|
+
|
33
|
+
def count32; self[:count32]; end
|
34
|
+
def count32=(val); self[:count32]=val; end
|
35
|
+
def count64; self[:count64]; end
|
36
|
+
def count64=(val); self[:count64]=val; end
|
37
|
+
end
|
38
|
+
|
39
|
+
dsl_layout do
|
40
|
+
field :cti_offs, :int, :desc => "Offset from the start of the fragment"
|
41
|
+
field :stub_pc, :app_pc, :desc => "Code cache address of the stub"
|
42
|
+
field :target, :app_pc, :desc => "Target of the stub"
|
43
|
+
field :linked, :bool, :desc => "Whether the stub is linked to its target"
|
44
|
+
field :stub_size, :int, :desc => "Length of stub_code array"
|
45
|
+
struct :count, Count , :desc => "32 or 64 bit execution count"
|
46
|
+
field :stub_code, :byte, :desc => "variable sized"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|