blob: e3be88f8cf1ac6ecfd12fd17f13187b141bcc50f [file] [log] [blame]
njnf536bbb2005-06-13 04:21:38 +00001
2/*--------------------------------------------------------------------*/
3/*--- Machine-related stuff. m_machine.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2005 Julian Seward
11 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
32#include "pub_core_threadstate.h"
njnf536bbb2005-06-13 04:21:38 +000033#include "pub_core_libcassert.h"
34#include "pub_core_libcbase.h"
35#include "pub_core_machine.h"
36
njnaf839f52005-06-23 03:27:57 +000037#define INSTR_PTR(regs) ((regs).vex.VG_INSTR_PTR)
38#define STACK_PTR(regs) ((regs).vex.VG_STACK_PTR)
39#define FRAME_PTR(regs) ((regs).vex.VG_FRAME_PTR)
njnf536bbb2005-06-13 04:21:38 +000040
41Addr VG_(get_SP) ( ThreadId tid )
42{
43 return STACK_PTR( VG_(threads)[tid].arch );
44}
45
46Addr VG_(get_IP) ( ThreadId tid )
47{
48 return INSTR_PTR( VG_(threads)[tid].arch );
49}
50
51Addr VG_(get_FP) ( ThreadId tid )
52{
53 return FRAME_PTR( VG_(threads)[tid].arch );
54}
55
56void VG_(set_SP) ( ThreadId tid, Addr sp )
57{
58 STACK_PTR( VG_(threads)[tid].arch ) = sp;
59}
60
61void VG_(set_IP) ( ThreadId tid, Addr ip )
62{
63 INSTR_PTR( VG_(threads)[tid].arch ) = ip;
64}
65
66
67void VG_(get_shadow_regs_area) ( ThreadId tid, OffT offset, SizeT size,
68 UChar* area )
69{
70 ThreadState* tst;
71
72 vg_assert(VG_(is_valid_tid)(tid));
73 tst = & VG_(threads)[tid];
74
75 // Bounds check
76 vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
77 vg_assert(offset + size <= sizeof(VexGuestArchState));
78
79 VG_(memcpy)( area, (void*)(((Addr)&(tst->arch.vex_shadow)) + offset), size);
80}
81
82void VG_(set_shadow_regs_area) ( ThreadId tid, OffT offset, SizeT size,
83 const UChar* area )
84{
85 ThreadState* tst;
86
87 vg_assert(VG_(is_valid_tid)(tid));
88 tst = & VG_(threads)[tid];
89
90 // Bounds check
91 vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
92 vg_assert(offset + size <= sizeof(VexGuestArchState));
93
94 VG_(memcpy)( (void*)(((Addr)(&tst->arch.vex_shadow)) + offset), area, size);
95}
96
97
njn6ace3ea2005-06-17 03:06:27 +000098static void apply_to_GPs_of_tid(VexGuestArchState* vex, void (*f)(Addr))
99{
100#if defined(VGA_x86)
101 (*f)(vex->guest_EAX);
102 (*f)(vex->guest_ECX);
103 (*f)(vex->guest_EDX);
104 (*f)(vex->guest_EBX);
105 (*f)(vex->guest_ESI);
106 (*f)(vex->guest_EDI);
107 (*f)(vex->guest_ESP);
108 (*f)(vex->guest_EBP);
109#elif defined(VGA_amd64)
110 (*f)(vex->guest_RAX);
111 (*f)(vex->guest_RCX);
112 (*f)(vex->guest_RDX);
113 (*f)(vex->guest_RBX);
114 (*f)(vex->guest_RSI);
115 (*f)(vex->guest_RDI);
116 (*f)(vex->guest_RSP);
117 (*f)(vex->guest_RBP);
118 (*f)(vex->guest_R8);
119 (*f)(vex->guest_R9);
120 (*f)(vex->guest_R10);
121 (*f)(vex->guest_R11);
122 (*f)(vex->guest_R12);
123 (*f)(vex->guest_R13);
124 (*f)(vex->guest_R14);
125 (*f)(vex->guest_R15);
cerion85665ca2005-06-20 15:51:07 +0000126#elif defined(VGA_ppc32)
127 /* XXX ask tool about validity? */
128 (*f)(vex->guest_GPR0);
129 (*f)(vex->guest_GPR1);
130 (*f)(vex->guest_GPR2);
131 (*f)(vex->guest_GPR3);
132 (*f)(vex->guest_GPR4);
133 (*f)(vex->guest_GPR5);
134 (*f)(vex->guest_GPR6);
135 (*f)(vex->guest_GPR7);
136 (*f)(vex->guest_GPR8);
137 (*f)(vex->guest_GPR9);
138 (*f)(vex->guest_GPR10);
139 (*f)(vex->guest_GPR11);
140 (*f)(vex->guest_GPR12);
141 (*f)(vex->guest_GPR13);
142 (*f)(vex->guest_GPR14);
143 (*f)(vex->guest_GPR15);
144 (*f)(vex->guest_GPR16);
145 (*f)(vex->guest_GPR17);
146 (*f)(vex->guest_GPR18);
147 (*f)(vex->guest_GPR19);
148 (*f)(vex->guest_GPR20);
149 (*f)(vex->guest_GPR21);
150 (*f)(vex->guest_GPR22);
151 (*f)(vex->guest_GPR23);
152 (*f)(vex->guest_GPR24);
153 (*f)(vex->guest_GPR25);
154 (*f)(vex->guest_GPR26);
155 (*f)(vex->guest_GPR27);
156 (*f)(vex->guest_GPR28);
157 (*f)(vex->guest_GPR29);
158 (*f)(vex->guest_GPR30);
159 (*f)(vex->guest_GPR31);
160 (*f)(vex->guest_CTR);
161 (*f)(vex->guest_LR);
162
njn6ace3ea2005-06-17 03:06:27 +0000163#else
164# error Unknown arch
165#endif
166}
167
168
169void VG_(apply_to_GP_regs)(void (*f)(UWord))
170{
171 ThreadId tid;
172
173 for (tid = 1; tid < VG_N_THREADS; tid++) {
174 if (VG_(is_valid_tid)(tid)) {
175 ThreadState* tst = VG_(get_ThreadState)(tid);
176 apply_to_GPs_of_tid(&(tst->arch.vex), f);
177 }
178 }
179}
180
njnb506bd82005-06-21 04:01:51 +0000181// Try and identify a thread whose stack satisfies the predicate p, or
182// return VG_INVALID_THREADID if none do.
183ThreadId VG_(first_matching_thread_stack)
184 ( Bool (*p) ( Addr stack_min, Addr stack_max, void* d ),
185 void* d )
186{
187 ThreadId tid;
njn6ace3ea2005-06-17 03:06:27 +0000188
njnb506bd82005-06-21 04:01:51 +0000189 for (tid = 1; tid < VG_N_THREADS; tid++) {
190 if (VG_(threads)[tid].status == VgTs_Empty) continue;
191
192 if ( p ( VG_(get_SP)(tid),
193 VG_(threads)[tid].client_stack_highest_word, d ) )
194 return tid;
195 }
196 return VG_INVALID_THREADID;
197}
njn6ace3ea2005-06-17 03:06:27 +0000198
sewardj10f08cf2005-06-29 10:16:14 +0000199//////////////////////////////////////////////////////////////////
200// Architecture specifics
201
202// PPC: what is the cache line size (for dcbz etc) ?
203// This info is harvested on Linux at startup from the AT_SYSINFO
204// entries. 0 means not-yet-set.
205#if defined(VGA_ppc32)
206Int VG_(cache_line_size_ppc32) = 0;
207#endif
208
njnf536bbb2005-06-13 04:21:38 +0000209/*--------------------------------------------------------------------*/
210/*--- end ---*/
211/*--------------------------------------------------------------------*/