1 /* Get Dwarf Frame state for target PID or core file.
2 Copyright (C) 2013 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
18 or both in parallel, as here.
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
30 #include <sys/ptrace.h>
33 /* Set STATE->pc_set from STATE->regs according to the backend. Return true on
34 success, false on error. */
36 state_fetch_pc (Dwfl_Frame *state)
38 switch (state->pc_state)
40 case DWFL_FRAME_STATE_PC_SET:
42 case DWFL_FRAME_STATE_PC_UNDEFINED:
44 case DWFL_FRAME_STATE_ERROR:
46 Ebl *ebl = state->thread->process->ebl;
48 if (ebl_abi_cfi (ebl, &abi_info) != 0)
50 __libdwfl_seterrno (DWFL_E_LIBEBL);
53 unsigned ra = abi_info.return_address_register;
54 /* dwarf_frame_state_reg_is_set is not applied here. */
55 if (ra >= ebl_frame_nregs (ebl))
57 __libdwfl_seterrno (DWFL_E_LIBEBL_BAD);
60 state->pc = state->regs[ra];
61 state->pc_state = DWFL_FRAME_STATE_PC_SET;
68 /* Do not call it on your own, to be used by thread_* functions only. */
71 state_free (Dwfl_Frame *state)
73 Dwfl_Thread *thread = state->thread;
74 assert (thread->unwound == state);
75 thread->unwound = state->unwound;
80 thread_free_all_states (Dwfl_Thread *thread)
82 while (thread->unwound)
83 state_free (thread->unwound);
87 state_alloc (Dwfl_Thread *thread)
89 assert (thread->unwound == NULL);
90 Ebl *ebl = thread->process->ebl;
91 size_t nregs = ebl_frame_nregs (ebl);
94 assert (nregs < sizeof (((Dwfl_Frame *) NULL)->regs_set) * 8);
95 Dwfl_Frame *state = malloc (sizeof (*state) + sizeof (*state->regs) * nregs);
98 state->thread = thread;
99 state->signal_frame = false;
100 state->initial_frame = true;
101 state->pc_state = DWFL_FRAME_STATE_ERROR;
102 memset (state->regs_set, 0, sizeof (state->regs_set));
103 thread->unwound = state;
104 state->unwound = NULL;
110 __libdwfl_process_free (Dwfl_Process *process)
112 Dwfl *dwfl = process->dwfl;
113 if (process->callbacks->detach != NULL)
114 process->callbacks->detach (dwfl, process->callbacks_arg);
115 assert (dwfl->process == process);
116 dwfl->process = NULL;
117 if (process->ebl_close)
118 ebl_closebackend (process->ebl);
122 /* Allocate new Dwfl_Process for DWFL. */
124 process_alloc (Dwfl *dwfl)
126 Dwfl_Process *process = malloc (sizeof (*process));
129 process->dwfl = dwfl;
130 dwfl->process = process;
134 dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
135 const Dwfl_Thread_Callbacks *thread_callbacks, void *arg)
137 if (thread_callbacks == NULL || thread_callbacks->next_thread == NULL
138 || thread_callbacks->set_initial_registers == NULL)
140 __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
143 if (dwfl->process != NULL)
145 __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
152 ebl = ebl_openbackend (elf);
158 for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
160 /* Reading of the vDSO module may fail as /proc/PID/mem is unreadable
161 without PTRACE_ATTACH and we may not be PTRACE_ATTACH-ed now.
162 MOD would not be re-read later to unwind it when we are already
163 PTRACE_ATTACH-ed to PID. */
164 if (strncmp (mod->name, "[vdso: ", 7) == 0)
166 Dwfl_Error error = __libdwfl_module_getebl (mod);
167 if (error != DWFL_E_NOERROR)
176 /* Not identified EBL from any of the modules. */
177 __libdwfl_seterrno (DWFL_E_PROCESS_NO_ARCH);
180 process_alloc (dwfl);
181 Dwfl_Process *process = dwfl->process;
185 ebl_closebackend (ebl);
186 __libdwfl_seterrno (DWFL_E_NOMEM);
190 process->ebl_close = ebl_close;
192 process->callbacks = thread_callbacks;
193 process->callbacks_arg = arg;
196 INTDEF(dwfl_attach_state)
199 dwfl_pid (Dwfl *dwfl)
201 if (dwfl->process == NULL)
203 __libdwfl_seterrno (dwfl->process_attach_error);
206 return dwfl->process->pid;
211 dwfl_thread_dwfl (Dwfl_Thread *thread)
213 return thread->process->dwfl;
215 INTDEF(dwfl_thread_dwfl)
218 dwfl_thread_tid (Dwfl_Thread *thread)
222 INTDEF(dwfl_thread_tid)
225 dwfl_frame_thread (Dwfl_Frame *state)
227 return state->thread;
229 INTDEF(dwfl_frame_thread)
232 dwfl_getthreads (Dwfl *dwfl, int (*callback) (Dwfl_Thread *thread, void *arg),
235 Dwfl_Process *process = dwfl->process;
238 __libdwfl_seterrno (dwfl->process_attach_error);
243 thread.process = process;
244 thread.unwound = NULL;
245 thread.callbacks_arg = NULL;
248 thread.tid = process->callbacks->next_thread (dwfl,
249 process->callbacks_arg,
250 &thread.callbacks_arg);
253 Dwfl_Error saved_errno = dwfl_errno ();
254 thread_free_all_states (&thread);
255 __libdwfl_seterrno (saved_errno);
260 thread_free_all_states (&thread);
261 __libdwfl_seterrno (DWFL_E_NOERROR);
264 int err = callback (&thread, arg);
265 if (err != DWARF_CB_OK)
267 thread_free_all_states (&thread);
270 assert (thread.unwound == NULL);
274 INTDEF(dwfl_getthreads)
277 dwfl_thread_getframes (Dwfl_Thread *thread,
278 int (*callback) (Dwfl_Frame *state, void *arg),
281 if (thread->unwound != NULL)
283 /* We had to be called from inside CALLBACK. */
284 __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
287 Ebl *ebl = thread->process->ebl;
288 if (ebl_frame_nregs (ebl) == 0)
290 __libdwfl_seterrno (DWFL_E_NO_UNWIND);
293 if (state_alloc (thread) == NULL)
295 __libdwfl_seterrno (DWFL_E_NOMEM);
298 Dwfl_Process *process = thread->process;
299 if (! process->callbacks->set_initial_registers (thread,
300 thread->callbacks_arg))
302 thread_free_all_states (thread);
305 if (! state_fetch_pc (thread->unwound))
307 if (process->callbacks->thread_detach)
308 process->callbacks->thread_detach (thread, thread->callbacks_arg);
309 thread_free_all_states (thread);
316 state = thread->unwound;
317 int err = callback (state, arg);
318 if (err != DWARF_CB_OK)
320 if (process->callbacks->thread_detach)
321 process->callbacks->thread_detach (thread, thread->callbacks_arg);
322 thread_free_all_states (thread);
325 __libdwfl_frame_unwind (state);
326 /* The old frame is no longer needed. */
327 state_free (thread->unwound);
328 state = thread->unwound;
330 while (state && state->pc_state == DWFL_FRAME_STATE_PC_SET);
332 Dwfl_Error err = dwfl_errno ();
333 if (process->callbacks->thread_detach)
334 process->callbacks->thread_detach (thread, thread->callbacks_arg);
335 if (state == NULL || state->pc_state == DWFL_FRAME_STATE_ERROR)
337 thread_free_all_states (thread);
338 __libdwfl_seterrno (err);
341 assert (state->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
342 thread_free_all_states (thread);
345 INTDEF(dwfl_thread_getframes)