1 /* Get Dwarf Frame state for target PID or core file.
2 Copyright (C) 2013, 2014 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/>. */
36 /* Set STATE->pc_set from STATE->regs according to the backend. Return true on
37 success, false on error. */
39 state_fetch_pc (Dwfl_Frame
*state
)
41 switch (state
->pc_state
)
43 case DWFL_FRAME_STATE_PC_SET
:
45 case DWFL_FRAME_STATE_PC_UNDEFINED
:
47 case DWFL_FRAME_STATE_ERROR
:
49 Ebl
*ebl
= state
->thread
->process
->ebl
;
51 if (ebl_abi_cfi (ebl
, &abi_info
) != 0)
53 __libdwfl_seterrno (DWFL_E_LIBEBL
);
56 unsigned ra
= abi_info
.return_address_register
;
57 /* dwarf_frame_state_reg_is_set is not applied here. */
58 if (ra
>= ebl_frame_nregs (ebl
))
60 __libdwfl_seterrno (DWFL_E_LIBEBL_BAD
);
63 state
->pc
= state
->regs
[ra
] + ebl_ra_offset (ebl
);
64 state
->pc_state
= DWFL_FRAME_STATE_PC_SET
;
71 /* Do not call it on your own, to be used by thread_* functions only. */
74 free_states (Dwfl_Frame
*state
)
78 Dwfl_Frame
*next
= state
->unwound
;
85 state_alloc (Dwfl_Thread
*thread
)
87 assert (thread
->unwound
== NULL
);
88 Ebl
*ebl
= thread
->process
->ebl
;
89 size_t nregs
= ebl_frame_nregs (ebl
);
92 assert (nregs
< sizeof (((Dwfl_Frame
*) NULL
)->regs_set
) * 8);
93 Dwfl_Frame
*state
= malloc (sizeof (*state
) + sizeof (*state
->regs
) * nregs
);
96 state
->thread
= thread
;
97 state
->signal_frame
= false;
98 state
->initial_frame
= true;
99 state
->pc_state
= DWFL_FRAME_STATE_ERROR
;
100 memset (state
->regs_set
, 0, sizeof (state
->regs_set
));
101 thread
->unwound
= state
;
102 state
->unwound
= NULL
;
108 __libdwfl_process_free (Dwfl_Process
*process
)
110 Dwfl
*dwfl
= process
->dwfl
;
111 if (process
->callbacks
->detach
!= NULL
)
112 process
->callbacks
->detach (dwfl
, process
->callbacks_arg
);
113 assert (dwfl
->process
== process
);
114 dwfl
->process
= NULL
;
115 if (process
->ebl_close
)
116 ebl_closebackend (process
->ebl
);
118 dwfl
->attacherr
= DWFL_E_NOERROR
;
121 /* Allocate new Dwfl_Process for DWFL. */
123 process_alloc (Dwfl
*dwfl
)
125 Dwfl_Process
*process
= malloc (sizeof (*process
));
128 process
->dwfl
= dwfl
;
129 dwfl
->process
= process
;
133 dwfl_attach_state (Dwfl
*dwfl
, Elf
*elf
, pid_t pid
,
134 const Dwfl_Thread_Callbacks
*thread_callbacks
, void *arg
)
136 if (dwfl
->process
!= NULL
)
138 __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT
);
142 /* Reset any previous error, we are just going to try again. */
143 dwfl
->attacherr
= DWFL_E_NOERROR
;
144 /* thread_callbacks is declared NN */
145 if (thread_callbacks
->next_thread
== NULL
146 || thread_callbacks
->set_initial_registers
== NULL
)
148 dwfl
->attacherr
= DWFL_E_INVALID_ARGUMENT
;
150 dwfl
->attacherr
= __libdwfl_canon_error (dwfl
->attacherr
);
151 __libdwfl_seterrno (dwfl
->attacherr
);
159 ebl
= ebl_openbackend (elf
);
165 for (Dwfl_Module
*mod
= dwfl
->modulelist
; mod
!= NULL
; mod
= mod
->next
)
167 /* Reading of the vDSO or (deleted) modules may fail as
168 /proc/PID/mem is unreadable without PTRACE_ATTACH and
169 we may not be PTRACE_ATTACH-ed now. MOD would not be
170 re-read later to unwind it when we are already
171 PTRACE_ATTACH-ed to PID. This happens when this function
172 is called from dwfl_linux_proc_attach with elf == NULL.
173 __libdwfl_module_getebl will call __libdwfl_getelf which
174 will call the find_elf callback. */
175 if (strncmp (mod
->name
, "[vdso: ", 7) == 0
176 || strcmp (strrchr (mod
->name
, ' ') ?: "",
179 Dwfl_Error error
= __libdwfl_module_getebl (mod
);
180 if (error
!= DWFL_E_NOERROR
)
189 /* Not identified EBL from any of the modules. */
190 dwfl
->attacherr
= DWFL_E_PROCESS_NO_ARCH
;
193 process_alloc (dwfl
);
194 Dwfl_Process
*process
= dwfl
->process
;
198 ebl_closebackend (ebl
);
199 dwfl
->attacherr
= DWFL_E_NOMEM
;
203 process
->ebl_close
= ebl_close
;
205 process
->callbacks
= thread_callbacks
;
206 process
->callbacks_arg
= arg
;
209 INTDEF(dwfl_attach_state
)
212 dwfl_pid (Dwfl
*dwfl
)
214 if (dwfl
->attacherr
!= DWFL_E_NOERROR
)
216 __libdwfl_seterrno (dwfl
->attacherr
);
220 if (dwfl
->process
== NULL
)
222 __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE
);
225 return dwfl
->process
->pid
;
230 dwfl_thread_dwfl (Dwfl_Thread
*thread
)
232 return thread
->process
->dwfl
;
234 INTDEF(dwfl_thread_dwfl
)
237 dwfl_thread_tid (Dwfl_Thread
*thread
)
241 INTDEF(dwfl_thread_tid
)
244 dwfl_frame_thread (Dwfl_Frame
*state
)
246 return state
->thread
;
248 INTDEF(dwfl_frame_thread
)
251 dwfl_getthreads (Dwfl
*dwfl
, int (*callback
) (Dwfl_Thread
*thread
, void *arg
),
254 if (dwfl
->attacherr
!= DWFL_E_NOERROR
)
256 __libdwfl_seterrno (dwfl
->attacherr
);
260 Dwfl_Process
*process
= dwfl
->process
;
263 __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE
);
268 thread
.process
= process
;
269 thread
.unwound
= NULL
;
270 thread
.callbacks_arg
= NULL
;
273 thread
.tid
= process
->callbacks
->next_thread (dwfl
,
274 process
->callbacks_arg
,
275 &thread
.callbacks_arg
);
280 __libdwfl_seterrno (DWFL_E_NOERROR
);
283 int err
= callback (&thread
, arg
);
284 if (err
!= DWARF_CB_OK
)
286 assert (thread
.unwound
== NULL
);
290 INTDEF(dwfl_getthreads
)
296 int (*callback
) (Dwfl_Thread
*thread
, void *arg
);
302 get_one_thread_cb (Dwfl_Thread
*thread
, void *arg
)
304 struct one_arg
*oa
= (struct one_arg
*) arg
;
305 if (! oa
->seen
&& INTUSE(dwfl_thread_tid
) (thread
) == oa
->tid
)
308 oa
->ret
= oa
->callback (thread
, oa
->arg
);
309 return DWARF_CB_ABORT
;
315 /* Note not currently exported, will be when there are more Dwfl_Thread
316 properties to query. Use dwfl_getthread_frames for now directly. */
318 getthread (Dwfl
*dwfl
, pid_t tid
,
319 int (*callback
) (Dwfl_Thread
*thread
, void *arg
),
322 if (dwfl
->attacherr
!= DWFL_E_NOERROR
)
324 __libdwfl_seterrno (dwfl
->attacherr
);
328 Dwfl_Process
*process
= dwfl
->process
;
331 __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE
);
335 if (process
->callbacks
->get_thread
!= NULL
)
338 thread
.process
= process
;
339 thread
.unwound
= NULL
;
340 thread
.callbacks_arg
= NULL
;
342 if (process
->callbacks
->get_thread (dwfl
, tid
, process
->callbacks_arg
,
343 &thread
.callbacks_arg
))
346 return callback (&thread
, arg
);
352 struct one_arg oa
= { .tid
= tid
, .callback
= callback
,
353 .arg
= arg
, .seen
= false };
354 int err
= INTUSE(dwfl_getthreads
) (dwfl
, get_one_thread_cb
, &oa
);
356 if (err
== DWARF_CB_ABORT
&& oa
.seen
)
359 if (err
== DWARF_CB_OK
&& ! oa
.seen
)
362 __libdwfl_seterrno (DWFL_E_ERRNO
);
371 int (*callback
) (Dwfl_Frame
*frame
, void *arg
);
376 get_one_thread_frames_cb (Dwfl_Thread
*thread
, void *arg
)
378 struct one_thread
*ot
= (struct one_thread
*) arg
;
379 return INTUSE(dwfl_thread_getframes
) (thread
, ot
->callback
, ot
->arg
);
383 dwfl_getthread_frames (Dwfl
*dwfl
, pid_t tid
,
384 int (*callback
) (Dwfl_Frame
*frame
, void *arg
),
387 struct one_thread ot
= { .callback
= callback
, .arg
= arg
};
388 return getthread (dwfl
, tid
, get_one_thread_frames_cb
, &ot
);
390 INTDEF(dwfl_getthread_frames
)
393 dwfl_thread_getframes (Dwfl_Thread
*thread
,
394 int (*callback
) (Dwfl_Frame
*state
, void *arg
),
397 Ebl
*ebl
= thread
->process
->ebl
;
398 if (ebl_frame_nregs (ebl
) == 0)
400 __libdwfl_seterrno (DWFL_E_NO_UNWIND
);
403 if (state_alloc (thread
) == NULL
)
405 __libdwfl_seterrno (DWFL_E_NOMEM
);
408 Dwfl_Process
*process
= thread
->process
;
409 if (! process
->callbacks
->set_initial_registers (thread
,
410 thread
->callbacks_arg
))
412 free_states (thread
->unwound
);
413 thread
->unwound
= NULL
;
416 Dwfl_Frame
*state
= thread
->unwound
;
417 thread
->unwound
= NULL
;
418 if (! state_fetch_pc (state
))
420 if (process
->callbacks
->thread_detach
)
421 process
->callbacks
->thread_detach (thread
, thread
->callbacks_arg
);
427 int err
= callback (state
, arg
);
428 if (err
!= DWARF_CB_OK
)
430 if (process
->callbacks
->thread_detach
)
431 process
->callbacks
->thread_detach (thread
, thread
->callbacks_arg
);
435 __libdwfl_frame_unwind (state
);
436 Dwfl_Frame
*next
= state
->unwound
;
437 /* The old frame is no longer needed. */
441 while (state
&& state
->pc_state
== DWFL_FRAME_STATE_PC_SET
);
443 Dwfl_Error err
= dwfl_errno ();
444 if (process
->callbacks
->thread_detach
)
445 process
->callbacks
->thread_detach (thread
, thread
->callbacks_arg
);
446 if (state
== NULL
|| state
->pc_state
== DWFL_FRAME_STATE_ERROR
)
449 __libdwfl_seterrno (err
);
452 assert (state
->pc_state
== DWFL_FRAME_STATE_PC_UNDEFINED
);
456 INTDEF(dwfl_thread_getframes
)