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