blob: 7d5f795cbf4d3597e1c2acf5631520f33b6982e1 [file] [log] [blame]
Brian Silverman86497922018-02-10 19:28:39 -05001/* Internal definitions for libdwfl.
2 Copyright (C) 2005-2015 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
7
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
11
12 or
13
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
17
18 or both in parallel, as here.
19
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.
24
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/>. */
28
29#ifndef _LIBDWFLP_H
30#define _LIBDWFLP_H 1
31
32#include <libdwfl.h>
33#include <libebl.h>
34#include <assert.h>
35#include <dirent.h>
36#include <errno.h>
37#include <stdbool.h>
38#include <stdlib.h>
39#include <string.h>
40
41#include "../libdw/libdwP.h" /* We need its INTDECLs. */
42#include "../libdwelf/libdwelfP.h"
43
44typedef struct Dwfl_Process Dwfl_Process;
45
46/* gettext helper macros. */
47#define _(Str) dgettext ("elfutils", Str)
48
49#define DWFL_ERRORS \
50 DWFL_ERROR (NOERROR, N_("no error")) \
51 DWFL_ERROR (UNKNOWN_ERROR, N_("unknown error")) \
52 DWFL_ERROR (NOMEM, N_("out of memory")) \
53 DWFL_ERROR (ERRNO, N_("See errno")) \
54 DWFL_ERROR (LIBELF, N_("See elf_errno")) \
55 DWFL_ERROR (LIBDW, N_("See dwarf_errno")) \
56 DWFL_ERROR (LIBEBL, N_("See ebl_errno (XXX missing)")) \
57 DWFL_ERROR (ZLIB, N_("gzip decompression failed")) \
58 DWFL_ERROR (BZLIB, N_("bzip2 decompression failed")) \
59 DWFL_ERROR (LZMA, N_("LZMA decompression failed")) \
60 DWFL_ERROR (UNKNOWN_MACHINE, N_("no support library found for machine")) \
61 DWFL_ERROR (NOREL, N_("Callbacks missing for ET_REL file")) \
62 DWFL_ERROR (BADRELTYPE, N_("Unsupported relocation type")) \
63 DWFL_ERROR (BADRELOFF, N_("r_offset is bogus")) \
64 DWFL_ERROR (BADSTROFF, N_("offset out of range")) \
65 DWFL_ERROR (RELUNDEF, N_("relocation refers to undefined symbol")) \
66 DWFL_ERROR (CB, N_("Callback returned failure")) \
67 DWFL_ERROR (NO_DWARF, N_("No DWARF information found")) \
68 DWFL_ERROR (NO_SYMTAB, N_("No symbol table found")) \
69 DWFL_ERROR (NO_PHDR, N_("No ELF program headers")) \
70 DWFL_ERROR (OVERLAP, N_("address range overlaps an existing module")) \
71 DWFL_ERROR (ADDR_OUTOFRANGE, N_("address out of range")) \
72 DWFL_ERROR (NO_MATCH, N_("no matching address range")) \
73 DWFL_ERROR (TRUNCATED, N_("image truncated")) \
74 DWFL_ERROR (ALREADY_ELF, N_("ELF file opened")) \
75 DWFL_ERROR (BADELF, N_("not a valid ELF file")) \
76 DWFL_ERROR (WEIRD_TYPE, N_("cannot handle DWARF type description")) \
77 DWFL_ERROR (WRONG_ID_ELF, N_("ELF file does not match build ID")) \
78 DWFL_ERROR (BAD_PRELINK, N_("corrupt .gnu.prelink_undo section data")) \
79 DWFL_ERROR (LIBEBL_BAD, N_("Internal error due to ebl")) \
80 DWFL_ERROR (CORE_MISSING, N_("Missing data in core file")) \
81 DWFL_ERROR (INVALID_REGISTER, N_("Invalid register")) \
82 DWFL_ERROR (PROCESS_MEMORY_READ, N_("Error reading process memory")) \
83 DWFL_ERROR (PROCESS_NO_ARCH, N_("Couldn't find architecture of any ELF")) \
84 DWFL_ERROR (PARSE_PROC, N_("Error parsing /proc filesystem")) \
85 DWFL_ERROR (INVALID_DWARF, N_("Invalid DWARF")) \
86 DWFL_ERROR (UNSUPPORTED_DWARF, N_("Unsupported DWARF")) \
87 DWFL_ERROR (NEXT_THREAD_FAIL, N_("Unable to find more threads")) \
88 DWFL_ERROR (ATTACH_STATE_CONFLICT, N_("Dwfl already has attached state")) \
89 DWFL_ERROR (NO_ATTACH_STATE, N_("Dwfl has no attached state")) \
90 DWFL_ERROR (NO_UNWIND, N_("Unwinding not supported for this architecture")) \
91 DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument")) \
92 DWFL_ERROR (NO_CORE_FILE, N_("Not an ET_CORE ELF file"))
93
94#define DWFL_ERROR(name, text) DWFL_E_##name,
95typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
96#undef DWFL_ERROR
97
98#define OTHER_ERROR(name) ((unsigned int) DWFL_E_##name << 16)
99#define DWFL_E(name, errno) (OTHER_ERROR (name) | (errno))
100
101extern int __libdwfl_canon_error (Dwfl_Error) internal_function;
102extern void __libdwfl_seterrno (Dwfl_Error) internal_function;
103
104/* Resources we might keep for the user about the core file that the
105 Dwfl might have been created from. Can currently only be set
106 through std-argp. */
107struct Dwfl_User_Core
108{
109 char *executable_for_core; /* --executable if --core was specified. */
110 Elf *core; /* non-NULL if we need to free it. */
111 int fd; /* close if >= 0. */
112};
113
114struct Dwfl
115{
116 const Dwfl_Callbacks *callbacks;
117
118 Dwfl_Module *modulelist; /* List in order used by full traversals. */
119
120 Dwfl_Process *process;
121 Dwfl_Error attacherr; /* Previous error attaching process. */
122
123 GElf_Addr offline_next_address;
124
125 GElf_Addr segment_align; /* Smallest granularity of segments. */
126
127 /* Binary search table in three parallel malloc'd arrays. */
128 size_t lookup_elts; /* Elements in use. */
129 size_t lookup_alloc; /* Elements allococated. */
130 GElf_Addr *lookup_addr; /* Start address of segment. */
131 Dwfl_Module **lookup_module; /* Module associated with segment, or null. */
132 int *lookup_segndx; /* User segment index, or -1. */
133
134 /* Cache from last dwfl_report_segment call. */
135 const void *lookup_tail_ident;
136 GElf_Off lookup_tail_vaddr;
137 GElf_Off lookup_tail_offset;
138 int lookup_tail_ndx;
139
140 struct Dwfl_User_Core *user_core;
141};
142
143#define OFFLINE_REDZONE 0x10000
144
145struct dwfl_file
146{
147 char *name;
148 int fd;
149 bool valid; /* The build ID note has been matched. */
150 bool relocated; /* Partial relocation of all sections done. */
151
152 Elf *elf;
153
154 /* This is the lowest p_vaddr in this ELF file, aligned to p_align.
155 For a file without phdrs, this is zero. */
156 GElf_Addr vaddr;
157
158 /* This is an address chosen for synchronization between the main file
159 and the debug file. See dwfl_module_getdwarf.c for how it's chosen. */
160 GElf_Addr address_sync;
161};
162
163struct Dwfl_Module
164{
165 Dwfl *dwfl;
166 struct Dwfl_Module *next; /* Link on Dwfl.modulelist. */
167
168 void *userdata;
169
170 char *name; /* Iterator name for this module. */
171 GElf_Addr low_addr, high_addr;
172
173 struct dwfl_file main, debug, aux_sym;
174 GElf_Addr main_bias;
175 Ebl *ebl;
176 GElf_Half e_type; /* GElf_Ehdr.e_type cache. */
177 Dwfl_Error elferr; /* Previous failure to open main file. */
178
179 struct dwfl_relocation *reloc_info; /* Relocatable sections. */
180
181 struct dwfl_file *symfile; /* Either main or debug. */
182 Elf_Data *symdata; /* Data in the ELF symbol table section. */
183 Elf_Data *aux_symdata; /* Data in the auxiliary ELF symbol table. */
184 size_t syments; /* sh_size / sh_entsize of that section. */
185 size_t aux_syments; /* sh_size / sh_entsize of aux_sym section. */
186 int first_global; /* Index of first global symbol of table. */
187 int aux_first_global; /* Index of first global of aux_sym table. */
188 Elf_Data *symstrdata; /* Data for its string table. */
189 Elf_Data *aux_symstrdata; /* Data for aux_sym string table. */
190 Elf_Data *symxndxdata; /* Data in the extended section index table. */
191 Elf_Data *aux_symxndxdata; /* Data in the extended auxiliary table. */
192
193 Dwarf *dw; /* libdw handle for its debugging info. */
194 Dwarf *alt; /* Dwarf used for dwarf_setalt, or NULL. */
195 int alt_fd; /* descriptor, only valid when alt != NULL. */
196 Elf *alt_elf; /* Elf for alt Dwarf. */
197
198 Dwfl_Error symerr; /* Previous failure to load symbols. */
199 Dwfl_Error dwerr; /* Previous failure to load DWARF. */
200
201 /* Known CU's in this module. */
202 struct dwfl_cu *first_cu, **cu;
203
204 void *lazy_cu_root; /* Table indexed by Dwarf_Off of CU. */
205
206 struct dwfl_arange *aranges; /* Mapping of addresses in module to CUs. */
207
208 void *build_id_bits; /* malloc'd copy of build ID bits. */
209 GElf_Addr build_id_vaddr; /* Address where they reside, 0 if unknown. */
210 int build_id_len; /* -1 for prior failure, 0 if unset. */
211
212 unsigned int ncu;
213 unsigned int lazycu; /* Possible users, deleted when none left. */
214 unsigned int naranges;
215
216 Dwarf_CFI *dwarf_cfi; /* Cached DWARF CFI for this module. */
217 Dwarf_CFI *eh_cfi; /* Cached EH CFI for this module. */
218
219 int segment; /* Index of first segment table entry. */
220 bool gc; /* Mark/sweep flag. */
221 bool is_executable; /* Use Dwfl::executable_for_core? */
222};
223
224/* This holds information common for all the threads/tasks/TIDs of one process
225 for backtraces. */
226
227struct Dwfl_Process
228{
229 struct Dwfl *dwfl;
230 pid_t pid;
231 const Dwfl_Thread_Callbacks *callbacks;
232 void *callbacks_arg;
233 struct ebl *ebl;
234 bool ebl_close:1;
235};
236
237/* See its typedef in libdwfl.h. */
238
239struct Dwfl_Thread
240{
241 Dwfl_Process *process;
242 pid_t tid;
243 /* The current frame being unwound. Initially it is the bottom frame.
244 Later the processed frames get freed and this pointer is updated. */
245 Dwfl_Frame *unwound;
246 void *callbacks_arg;
247};
248
249/* See its typedef in libdwfl.h. */
250
251struct Dwfl_Frame
252{
253 Dwfl_Thread *thread;
254 /* Previous (outer) frame. */
255 Dwfl_Frame *unwound;
256 bool signal_frame : 1;
257 bool initial_frame : 1;
258 enum
259 {
260 /* This structure is still being initialized or there was an error
261 initializing it. */
262 DWFL_FRAME_STATE_ERROR,
263 /* PC field is valid. */
264 DWFL_FRAME_STATE_PC_SET,
265 /* PC field is undefined, this means the next (inner) frame was the
266 outermost frame. */
267 DWFL_FRAME_STATE_PC_UNDEFINED
268 } pc_state;
269 /* Either initialized from appropriate REGS element or on some archs
270 initialized separately as the return address has no DWARF register. */
271 Dwarf_Addr pc;
272 /* (1 << X) bitmask where 0 <= X < ebl_frame_nregs. */
273 uint64_t regs_set[3];
274 /* REGS array size is ebl_frame_nregs.
275 REGS_SET tells which of the REGS are valid. */
276 Dwarf_Addr regs[];
277};
278
279/* Fetch value from Dwfl_Frame->regs indexed by DWARF REGNO.
280 No error code is set if the function returns FALSE. */
281bool __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno,
282 Dwarf_Addr *val)
283 internal_function;
284
285/* Store value to Dwfl_Frame->regs indexed by DWARF REGNO.
286 No error code is set if the function returns FALSE. */
287bool __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno,
288 Dwarf_Addr val)
289 internal_function;
290
291/* Information cached about each CU in Dwfl_Module.dw. */
292struct dwfl_cu
293{
294 /* This caches libdw information about the CU. It's also the
295 address passed back to users, so we take advantage of the
296 fact that it's placed first to cast back. */
297 Dwarf_Die die;
298
299 Dwfl_Module *mod; /* Pointer back to containing module. */
300
301 struct dwfl_cu *next; /* CU immediately following in the file. */
302
303 struct Dwfl_Lines *lines;
304};
305
306struct Dwfl_Lines
307{
308 struct dwfl_cu *cu;
309
310 /* This is what the opaque Dwfl_Line * pointers we pass to users are.
311 We need to recover pointers to our struct dwfl_cu and a record in
312 libdw's Dwarf_Line table. To minimize the memory used in addition
313 to libdw's Dwarf_Lines buffer, we just point to our own index in
314 this table, and have one pointer back to the CU. The indices here
315 match those in libdw's Dwarf_CU.lines->info table. */
316 struct Dwfl_Line
317 {
318 unsigned int idx; /* My index in the dwfl_cu.lines table. */
319 } idx[0];
320};
321
322static inline struct dwfl_cu *
323dwfl_linecu_inline (const Dwfl_Line *line)
324{
325 const struct Dwfl_Lines *lines = ((const void *) line
326 - offsetof (struct Dwfl_Lines,
327 idx[line->idx]));
328 return lines->cu;
329}
330#define dwfl_linecu dwfl_linecu_inline
331
332static inline GElf_Addr
333dwfl_adjusted_address (Dwfl_Module *mod, GElf_Addr addr)
334{
335 return addr + mod->main_bias;
336}
337
338static inline GElf_Addr
339dwfl_deadjust_address (Dwfl_Module *mod, GElf_Addr addr)
340{
341 return addr - mod->main_bias;
342}
343
344static inline Dwarf_Addr
345dwfl_adjusted_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
346{
347 return dwfl_adjusted_address (mod, (addr
348 - mod->debug.address_sync
349 + mod->main.address_sync));
350}
351
352static inline Dwarf_Addr
353dwfl_deadjust_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
354{
355 return (dwfl_deadjust_address (mod, addr)
356 - mod->main.address_sync
357 + mod->debug.address_sync);
358}
359
360static inline Dwarf_Addr
361dwfl_adjusted_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
362{
363 return dwfl_adjusted_address (mod, (addr
364 - mod->aux_sym.address_sync
365 + mod->main.address_sync));
366}
367
368static inline Dwarf_Addr
369dwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
370{
371 return (dwfl_deadjust_address (mod, addr)
372 - mod->main.address_sync
373 + mod->aux_sym.address_sync);
374}
375
376static inline GElf_Addr
377dwfl_adjusted_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
378{
379 if (symelf == mod->main.elf)
380 return dwfl_adjusted_address (mod, addr);
381 if (symelf == mod->debug.elf)
382 return dwfl_adjusted_dwarf_addr (mod, addr);
383 return dwfl_adjusted_aux_sym_addr (mod, addr);
384}
385
386static inline GElf_Addr
387dwfl_deadjust_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
388{
389 if (symelf == mod->main.elf)
390 return dwfl_deadjust_address (mod, addr);
391 if (symelf == mod->debug.elf)
392 return dwfl_deadjust_dwarf_addr (mod, addr);
393 return dwfl_deadjust_aux_sym_addr (mod, addr);
394}
395
396/* This describes a contiguous address range that lies in a single CU.
397 We condense runs of Dwarf_Arange entries for the same CU into this. */
398struct dwfl_arange
399{
400 struct dwfl_cu *cu;
401 size_t arange; /* Index in Dwarf_Aranges. */
402};
403
404
405/* Structure used for keeping track of ptrace attaching a thread.
406 Shared by linux-pid-attach and linux-proc-maps. If it has been setup
407 then get the instance through __libdwfl_get_pid_arg. */
408struct __libdwfl_pid_arg
409{
410 /* /proc/PID/task/. */
411 DIR *dir;
412 /* Elf for /proc/PID/exe. Set to NULL if it couldn't be opened. */
413 Elf *elf;
414 /* fd for /proc/PID/exe. Set to -1 if it couldn't be opened. */
415 int elf_fd;
416 /* It is 0 if not used. */
417 pid_t tid_attached;
418 /* Valid only if TID_ATTACHED is not zero. */
419 bool tid_was_stopped;
420 /* True if threads are ptrace stopped by caller. */
421 bool assume_ptrace_stopped;
422};
423
424/* If DWfl is not NULL and a Dwfl_Process has been setup that has
425 Dwfl_Thread_Callbacks set to pid_thread_callbacks, then return the
426 callbacks_arg, which will be a struct __libdwfl_pid_arg. Otherwise
427 returns NULL. */
428extern struct __libdwfl_pid_arg *__libdwfl_get_pid_arg (Dwfl *dwfl)
429 internal_function;
430
431/* Makes sure the given tid is attached. On success returns true and
432 sets tid_was_stopped. */
433extern bool __libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
434 internal_function;
435
436/* Detaches a tid that was attached through
437 __libdwfl_ptrace_attach. Must be given the tid_was_stopped as set
438 by __libdwfl_ptrace_attach. */
439extern void __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
440 internal_function;
441
442
443/* Internal wrapper for old dwfl_module_getsym and new dwfl_module_getsym_info.
444 adjust_st_value set to true returns adjusted SYM st_value, set to false
445 it will not adjust SYM at all, but does match against resolved *ADDR. */
446extern const char *__libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym,
447 GElf_Addr *addr, GElf_Word *shndxp,
448 Elf **elfp, Dwarf_Addr *biasp,
449 bool *resolved, bool adjust_st_value)
450 internal_function;
451
452/* Internal wrapper for old dwfl_module_addrsym and new dwfl_module_addrinfo.
453 adjust_st_value set to true returns adjusted SYM st_value, set to false
454 it will not adjust SYM at all, but does match against resolved values. */
455extern const char *__libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr,
456 GElf_Off *off, GElf_Sym *sym,
457 GElf_Word *shndxp, Elf **elfp,
458 Dwarf_Addr *bias,
459 bool adjust_st_value) internal_function;
460
461extern void __libdwfl_module_free (Dwfl_Module *mod) internal_function;
462
463/* Find the main ELF file, update MOD->elferr and/or MOD->main.elf. */
464extern void __libdwfl_getelf (Dwfl_Module *mod) internal_function;
465
466/* Process relocations in debugging sections in an ET_REL file.
467 FILE must be opened with ELF_C_READ_MMAP_PRIVATE or ELF_C_READ,
468 to make it possible to relocate the data in place (or ELF_C_RDWR or
469 ELF_C_RDWR_MMAP if you intend to modify the Elf file on disk). After
470 this, dwarf_begin_elf on FILE will read the relocated data.
471
472 When DEBUG is false, apply partial relocation to all sections. */
473extern Dwfl_Error __libdwfl_relocate (Dwfl_Module *mod, Elf *file, bool debug)
474 internal_function;
475
476/* Find the section index in mod->main.elf that contains the given
477 *ADDR. Adjusts *ADDR to be section relative on success, returns
478 SHN_UNDEF on failure. */
479extern size_t __libdwfl_find_section_ndx (Dwfl_Module *mod, Dwarf_Addr *addr)
480 internal_function;
481
482/* Process (simple) relocations in arbitrary section TSCN of an ET_REL file.
483 RELOCSCN is SHT_REL or SHT_RELA and TSCN is its sh_info target section. */
484extern Dwfl_Error __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
485 Elf_Scn *relocscn, Elf_Scn *tscn,
486 bool partial)
487 internal_function;
488
489/* Adjust *VALUE from section-relative to absolute.
490 MOD->dwfl->callbacks->section_address is called to determine the actual
491 address of a loaded section. */
492extern Dwfl_Error __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf,
493 size_t *shstrndx_cache,
494 Elf32_Word shndx,
495 GElf_Addr *value)
496 internal_function;
497
498/* Ensure that MOD->ebl is set up. */
499extern Dwfl_Error __libdwfl_module_getebl (Dwfl_Module *mod) internal_function;
500
501/* Install a new Dwarf_CFI in *SLOT (MOD->eh_cfi or MOD->dwarf_cfi). */
502extern Dwarf_CFI *__libdwfl_set_cfi (Dwfl_Module *mod, Dwarf_CFI **slot,
503 Dwarf_CFI *cfi)
504 internal_function;
505
506/* Iterate through all the CU's in the module. Start by passing a null
507 LASTCU, and then pass the last *CU returned. Success return with null
508 *CU no more CUs. */
509extern Dwfl_Error __libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
510 struct dwfl_cu **cu) internal_function;
511
512/* Find the CU by address. */
513extern Dwfl_Error __libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr,
514 struct dwfl_cu **cu) internal_function;
515
516/* Ensure that CU->lines (and CU->cu->lines) is set up. */
517extern Dwfl_Error __libdwfl_cu_getsrclines (struct dwfl_cu *cu)
518 internal_function;
519
520/* Look in ELF for an NT_GNU_BUILD_ID note. Store it to BUILD_ID_BITS,
521 its vaddr in ELF to BUILD_ID_VADDR (it is unrelocated, even if MOD is not
522 NULL) and store length to BUILD_ID_LEN. Returns -1 for errors, 1 if it was
523 stored and 0 if no note is found. MOD may be NULL, MOD must be non-NULL
524 only if ELF is ET_REL. */
525extern int __libdwfl_find_elf_build_id (Dwfl_Module *mod, Elf *elf,
526 const void **build_id_bits,
527 GElf_Addr *build_id_elfaddr,
528 int *build_id_len)
529 internal_function;
530
531/* Look in ELF for an NT_GNU_BUILD_ID note. If SET is true, store it
532 in MOD and return its length. If SET is false, instead compare it
533 to that stored in MOD and return 2 if they match, 1 if they do not.
534 Returns -1 for errors, 0 if no note is found. */
535extern int __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
536 internal_function;
537
538/* Open a main or debuginfo file by its build ID, returns the fd. */
539extern int __libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug,
540 char **file_name) internal_function;
541
542/* Same, but takes an explicit build_id, can also be used for alt debug. */
543extern int __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug,
544 char **file_name, const size_t id_len,
545 const uint8_t *id) internal_function;
546
547extern uint32_t __libdwfl_crc32 (uint32_t crc, unsigned char *buf, size_t len)
548 attribute_hidden;
549extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden;
550
551
552/* Given ELF and some parameters return TRUE if the *P return value parameters
553 have been successfully filled in. Any of the *P parameters can be NULL. */
554extern bool __libdwfl_elf_address_range (Elf *elf, GElf_Addr base,
555 bool add_p_vaddr, bool sanity,
556 GElf_Addr *vaddrp,
557 GElf_Addr *address_syncp,
558 GElf_Addr *startp, GElf_Addr *endp,
559 GElf_Addr *biasp, GElf_Half *e_typep)
560 internal_function;
561
562/* Meat of dwfl_report_elf, given elf_begin just called.
563 Consumes ELF on success, not on failure. */
564extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name,
565 const char *file_name, int fd,
566 Elf *elf, GElf_Addr base,
567 bool add_p_vaddr, bool sanity)
568 internal_function;
569
570/* Meat of dwfl_report_offline. */
571extern Dwfl_Module *__libdwfl_report_offline (Dwfl *dwfl, const char *name,
572 const char *file_name,
573 int fd, bool closefd,
574 int (*predicate) (const char *,
575 const char *))
576 internal_function;
577
578/* Free PROCESS. Unlink and free also any structures it references. */
579extern void __libdwfl_process_free (Dwfl_Process *process)
580 internal_function;
581
582/* Update STATE->unwound for the unwound frame.
583 On error STATE->unwound == NULL
584 or STATE->unwound->pc_state == DWFL_FRAME_STATE_ERROR;
585 in such case dwfl_errno () is set.
586 If STATE->unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED
587 then STATE was the last valid frame. */
588extern void __libdwfl_frame_unwind (Dwfl_Frame *state)
589 internal_function;
590
591/* Align segment START downwards or END upwards addresses according to DWFL. */
592extern GElf_Addr __libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start)
593 internal_function;
594extern GElf_Addr __libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end)
595 internal_function;
596
597/* Decompression wrappers: decompress whole file into memory. */
598extern Dwfl_Error __libdw_gunzip (int fd, off_t start_offset,
599 void *mapped, size_t mapped_size,
600 void **whole, size_t *whole_size)
601 internal_function;
602extern Dwfl_Error __libdw_bunzip2 (int fd, off_t start_offset,
603 void *mapped, size_t mapped_size,
604 void **whole, size_t *whole_size)
605 internal_function;
606extern Dwfl_Error __libdw_unlzma (int fd, off_t start_offset,
607 void *mapped, size_t mapped_size,
608 void **whole, size_t *whole_size)
609 internal_function;
610
611/* Skip the image header before a file image: updates *START_OFFSET. */
612extern Dwfl_Error __libdw_image_header (int fd, off_t *start_offset,
613 void *mapped, size_t mapped_size)
614 internal_function;
615
616/* Open Elf handle on *FDP. This handles decompression and checks
617 elf_kind. Succeed only for ELF_K_ELF, or also ELF_K_AR if ARCHIVE_OK.
618 Returns DWFL_E_NOERROR and sets *ELFP on success, resets *FDP to -1 if
619 it's no longer used. Resets *FDP on failure too iff CLOSE_ON_FAIL. */
620extern Dwfl_Error __libdw_open_file (int *fdp, Elf **elfp,
621 bool close_on_fail, bool archive_ok)
622 internal_function;
623
624/* Fetch PT_DYNAMIC P_VADDR from ELF and store it to *VADDRP. Return success.
625 *VADDRP is not modified if the function fails. */
626extern bool __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
627 internal_function;
628
629/* These are working nicely for --core, but are not ready to be
630 exported interfaces quite yet. */
631
632/* Type of callback function ...
633 */
634typedef bool Dwfl_Memory_Callback (Dwfl *dwfl, int segndx,
635 void **buffer, size_t *buffer_available,
636 GElf_Addr vaddr, size_t minread, void *arg);
637
638/* Type of callback function ...
639 */
640typedef bool Dwfl_Module_Callback (Dwfl_Module *mod, void **userdata,
641 const char *name, Dwarf_Addr base,
642 void **buffer, size_t *buffer_available,
643 GElf_Off cost, GElf_Off worthwhile,
644 GElf_Off whole, GElf_Off contiguous,
645 void *arg, Elf **elfp);
646
647/* One shared library (or executable) info from DT_DEBUG link map. */
648struct r_debug_info_module
649{
650 struct r_debug_info_module *next;
651 /* FD is -1 iff ELF is NULL. */
652 int fd;
653 Elf *elf;
654 GElf_Addr l_ld;
655 /* START and END are both zero if not valid. */
656 GElf_Addr start, end;
657 bool disk_file_has_build_id;
658 char name[0];
659};
660
661/* Information gathered from DT_DEBUG by dwfl_link_map_report hinted to
662 dwfl_segment_report_module. */
663struct r_debug_info
664{
665 struct r_debug_info_module *module;
666};
667
668/* ...
669 */
670extern int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
671 Dwfl_Memory_Callback *memory_callback,
672 void *memory_callback_arg,
673 Dwfl_Module_Callback *read_eagerly,
674 void *read_eagerly_arg,
675 const void *note_file,
676 size_t note_file_size,
677 const struct r_debug_info *r_debug_info);
678
679/* Report a module for entry in the dynamic linker's struct link_map list.
680 For each link_map entry, if an existing module resides at its address,
681 this just modifies that module's name and suggested file name. If
682 no such module exists, this calls dwfl_report_elf on the l_name string.
683
684 If AUXV is not null, it points to AUXV_SIZE bytes of auxiliary vector
685 data as contained in an NT_AUXV note or read from a /proc/pid/auxv
686 file. When this is available, it guides the search. If AUXV is null
687 or the memory it points to is not accessible, then this search can
688 only find where to begin if the correct executable file was
689 previously reported and preloaded as with dwfl_report_elf.
690
691 Fill in R_DEBUG_INFO if it is not NULL. It should be cleared by the
692 caller, this function does not touch fields it does not need to modify.
693 If R_DEBUG_INFO is not NULL then no modules get added to DWFL, caller
694 has to add them from filled in R_DEBUG_INFO.
695
696 Returns the number of modules found, or -1 for errors. */
697extern int dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
698 Dwfl_Memory_Callback *memory_callback,
699 void *memory_callback_arg,
700 struct r_debug_info *r_debug_info);
701
702
703/* Avoid PLT entries. */
704INTDECL (dwfl_begin)
705INTDECL (dwfl_errmsg)
706INTDECL (dwfl_errno)
707INTDECL (dwfl_addrmodule)
708INTDECL (dwfl_addrsegment)
709INTDECL (dwfl_addrdwarf)
710INTDECL (dwfl_addrdie)
711INTDECL (dwfl_core_file_attach)
712INTDECL (dwfl_core_file_report)
713INTDECL (dwfl_getmodules)
714INTDECL (dwfl_module_addrdie)
715INTDECL (dwfl_module_address_section)
716INTDECL (dwfl_module_addrinfo)
717INTDECL (dwfl_module_addrsym)
718INTDECL (dwfl_module_build_id)
719INTDECL (dwfl_module_getdwarf)
720INTDECL (dwfl_module_getelf)
721INTDECL (dwfl_module_getsym)
722INTDECL (dwfl_module_getsym_info)
723INTDECL (dwfl_module_getsymtab)
724INTDECL (dwfl_module_getsymtab_first_global)
725INTDECL (dwfl_module_getsrc)
726INTDECL (dwfl_module_report_build_id)
727INTDECL (dwfl_report_elf)
728INTDECL (dwfl_report_begin)
729INTDECL (dwfl_report_begin_add)
730INTDECL (dwfl_report_module)
731INTDECL (dwfl_report_segment)
732INTDECL (dwfl_report_offline)
733INTDECL (dwfl_report_end)
734INTDECL (dwfl_build_id_find_elf)
735INTDECL (dwfl_build_id_find_debuginfo)
736INTDECL (dwfl_standard_find_debuginfo)
737INTDECL (dwfl_link_map_report)
738INTDECL (dwfl_linux_kernel_find_elf)
739INTDECL (dwfl_linux_kernel_module_section_address)
740INTDECL (dwfl_linux_proc_attach)
741INTDECL (dwfl_linux_proc_report)
742INTDECL (dwfl_linux_proc_maps_report)
743INTDECL (dwfl_linux_proc_find_elf)
744INTDECL (dwfl_linux_kernel_report_kernel)
745INTDECL (dwfl_linux_kernel_report_modules)
746INTDECL (dwfl_linux_kernel_report_offline)
747INTDECL (dwfl_offline_section_address)
748INTDECL (dwfl_module_relocate_address)
749INTDECL (dwfl_module_dwarf_cfi)
750INTDECL (dwfl_module_eh_cfi)
751INTDECL (dwfl_attach_state)
752INTDECL (dwfl_pid)
753INTDECL (dwfl_thread_dwfl)
754INTDECL (dwfl_thread_tid)
755INTDECL (dwfl_frame_thread)
756INTDECL (dwfl_thread_state_registers)
757INTDECL (dwfl_thread_state_register_pc)
758INTDECL (dwfl_getthread_frames)
759INTDECL (dwfl_getthreads)
760INTDECL (dwfl_thread_getframes)
761INTDECL (dwfl_frame_pc)
762
763/* Leading arguments standard to callbacks passed a Dwfl_Module. */
764#define MODCB_ARGS(mod) (mod), &(mod)->userdata, (mod)->name, (mod)->low_addr
765#define CBFAIL (errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB);
766
767
768/* The default used by dwfl_standard_find_debuginfo. */
769#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug"
770
771
772#endif /* libdwflP.h */