1 /* Copyright (C) 2009-2018 Free Software Foundation, Inc.
2 Contributed by ARM Ltd.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "common-defs.h"
20 #include "break-common.h"
21 #include "nat/linux-nat.h"
22 #include "nat/aarch64-linux-hw-point.h"
23 #include "nat/aarch64-linux.h"
25 #include "elf/common.h"
26 #include "nat/gdb_ptrace.h"
27 #include <asm/ptrace.h>
30 /* Called when resuming a thread LWP.
31 The hardware debug registers are updated when there is any change. */
34 aarch64_linux_prepare_to_resume (struct lwp_info
*lwp
)
36 struct arch_lwp_info
*info
= lwp_arch_private_info (lwp
);
38 /* NULL means this is the main thread still going through the shell,
39 or, no watchpoint has been set yet. In that case, there's
44 if (DR_HAS_CHANGED (info
->dr_changed_bp
)
45 || DR_HAS_CHANGED (info
->dr_changed_wp
))
47 ptid_t ptid
= ptid_of_lwp (lwp
);
48 int tid
= ptid
.lwp ();
49 struct aarch64_debug_reg_state
*state
50 = aarch64_get_debug_reg_state (ptid
.pid ());
53 debug_printf ("prepare_to_resume thread %d\n", tid
);
56 if (DR_HAS_CHANGED (info
->dr_changed_wp
))
58 aarch64_linux_set_debug_regs (state
, tid
, 1);
59 DR_CLEAR_CHANGED (info
->dr_changed_wp
);
63 if (DR_HAS_CHANGED (info
->dr_changed_bp
))
65 aarch64_linux_set_debug_regs (state
, tid
, 0);
66 DR_CLEAR_CHANGED (info
->dr_changed_bp
);
71 /* Function to call when a new thread is detected. */
74 aarch64_linux_new_thread (struct lwp_info
*lwp
)
76 struct arch_lwp_info
*info
= XNEW (struct arch_lwp_info
);
78 /* Mark that all the hardware breakpoint/watchpoint register pairs
79 for this thread need to be initialized (with data from
80 aarch_process_info.debug_reg_state). */
81 DR_MARK_ALL_CHANGED (info
->dr_changed_bp
, aarch64_num_bp_regs
);
82 DR_MARK_ALL_CHANGED (info
->dr_changed_wp
, aarch64_num_wp_regs
);
84 lwp_set_arch_private_info (lwp
, info
);
87 /* See nat/aarch64-linux.h. */
90 aarch64_linux_delete_thread (struct arch_lwp_info
*arch_lwp
)
95 /* Convert native siginfo FROM to the siginfo in the layout of the
96 inferior's architecture TO. */
99 aarch64_compat_siginfo_from_siginfo (compat_siginfo_t
*to
, siginfo_t
*from
)
101 memset (to
, 0, sizeof (*to
));
103 to
->si_signo
= from
->si_signo
;
104 to
->si_errno
= from
->si_errno
;
105 to
->si_code
= from
->si_code
;
107 if (to
->si_code
== SI_TIMER
)
109 to
->cpt_si_timerid
= from
->si_timerid
;
110 to
->cpt_si_overrun
= from
->si_overrun
;
111 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
113 else if (to
->si_code
== SI_USER
)
115 to
->cpt_si_pid
= from
->si_pid
;
116 to
->cpt_si_uid
= from
->si_uid
;
118 else if (to
->si_code
< 0)
120 to
->cpt_si_pid
= from
->si_pid
;
121 to
->cpt_si_uid
= from
->si_uid
;
122 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
126 switch (to
->si_signo
)
129 to
->cpt_si_pid
= from
->si_pid
;
130 to
->cpt_si_uid
= from
->si_uid
;
131 to
->cpt_si_status
= from
->si_status
;
132 to
->cpt_si_utime
= from
->si_utime
;
133 to
->cpt_si_stime
= from
->si_stime
;
139 to
->cpt_si_addr
= (intptr_t) from
->si_addr
;
142 to
->cpt_si_band
= from
->si_band
;
143 to
->cpt_si_fd
= from
->si_fd
;
146 to
->cpt_si_pid
= from
->si_pid
;
147 to
->cpt_si_uid
= from
->si_uid
;
148 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
154 /* Convert inferior's architecture siginfo FROM to native siginfo TO. */
157 aarch64_siginfo_from_compat_siginfo (siginfo_t
*to
, compat_siginfo_t
*from
)
159 memset (to
, 0, sizeof (*to
));
161 to
->si_signo
= from
->si_signo
;
162 to
->si_errno
= from
->si_errno
;
163 to
->si_code
= from
->si_code
;
165 if (to
->si_code
== SI_TIMER
)
167 to
->si_timerid
= from
->cpt_si_timerid
;
168 to
->si_overrun
= from
->cpt_si_overrun
;
169 to
->si_ptr
= (void *) (intptr_t) from
->cpt_si_ptr
;
171 else if (to
->si_code
== SI_USER
)
173 to
->si_pid
= from
->cpt_si_pid
;
174 to
->si_uid
= from
->cpt_si_uid
;
178 to
->si_pid
= from
->cpt_si_pid
;
179 to
->si_uid
= from
->cpt_si_uid
;
180 to
->si_ptr
= (void *) (intptr_t) from
->cpt_si_ptr
;
184 switch (to
->si_signo
)
187 to
->si_pid
= from
->cpt_si_pid
;
188 to
->si_uid
= from
->cpt_si_uid
;
189 to
->si_status
= from
->cpt_si_status
;
190 to
->si_utime
= from
->cpt_si_utime
;
191 to
->si_stime
= from
->cpt_si_stime
;
197 to
->si_addr
= (void *) (intptr_t) from
->cpt_si_addr
;
200 to
->si_band
= from
->cpt_si_band
;
201 to
->si_fd
= from
->cpt_si_fd
;
204 to
->si_pid
= from
->cpt_si_pid
;
205 to
->si_uid
= from
->cpt_si_uid
;
206 to
->si_ptr
= (void* ) (intptr_t) from
->cpt_si_ptr
;
212 /* Called by libthread_db. Returns a pointer to the thread local
213 storage (or its descriptor). */
216 aarch64_ps_get_thread_area (struct ps_prochandle
*ph
,
217 lwpid_t lwpid
, int idx
, void **base
,
226 iovec
.iov_base
= ®64
;
227 iovec
.iov_len
= sizeof (reg64
);
231 iovec
.iov_base
= ®32
;
232 iovec
.iov_len
= sizeof (reg32
);
235 if (ptrace (PTRACE_GETREGSET
, lwpid
, NT_ARM_TLS
, &iovec
) != 0)
238 /* IDX is the bias from the thread pointer to the beginning of the
239 thread descriptor. It has to be subtracted due to implementation
240 quirks in libthread_db. */
242 *base
= (void *) (reg64
- idx
);
244 *base
= (void *) (uintptr_t) (reg32
- idx
);
This page took 0.036419 seconds and 5 git commands to generate.