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 *
dwfl_linecu_inline(const Dwfl_Line * line)326 dwfl_linecu_inline (const Dwfl_Line *line)
327 {
328 const struct Dwfl_Lines *lines = ((const void *) line
329 - offsetof (struct Dwfl_Lines,
330 idx[line->idx]));
331 return lines->cu;
332 }
333 #define dwfl_linecu dwfl_linecu_inline
334
335 static inline GElf_Addr
dwfl_adjusted_address(Dwfl_Module * mod,GElf_Addr addr)336 dwfl_adjusted_address (Dwfl_Module *mod, GElf_Addr addr)
337 {
338 return addr + mod->main_bias;
339 }
340
341 static inline GElf_Addr
dwfl_deadjust_address(Dwfl_Module * mod,GElf_Addr addr)342 dwfl_deadjust_address (Dwfl_Module *mod, GElf_Addr addr)
343 {
344 return addr - mod->main_bias;
345 }
346
347 static inline Dwarf_Addr
dwfl_adjusted_dwarf_addr(Dwfl_Module * mod,Dwarf_Addr addr)348 dwfl_adjusted_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
349 {
350 return dwfl_adjusted_address (mod, (addr
351 - mod->debug.address_sync
352 + mod->main.address_sync));
353 }
354
355 static inline Dwarf_Addr
dwfl_deadjust_dwarf_addr(Dwfl_Module * mod,Dwarf_Addr addr)356 dwfl_deadjust_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
357 {
358 return (dwfl_deadjust_address (mod, addr)
359 - mod->main.address_sync
360 + mod->debug.address_sync);
361 }
362
363 static inline Dwarf_Addr
dwfl_adjusted_aux_sym_addr(Dwfl_Module * mod,Dwarf_Addr addr)364 dwfl_adjusted_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
365 {
366 return dwfl_adjusted_address (mod, (addr
367 - mod->aux_sym.address_sync
368 + mod->main.address_sync));
369 }
370
371 static inline Dwarf_Addr
dwfl_deadjust_aux_sym_addr(Dwfl_Module * mod,Dwarf_Addr addr)372 dwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
373 {
374 return (dwfl_deadjust_address (mod, addr)
375 - mod->main.address_sync
376 + mod->aux_sym.address_sync);
377 }
378
379 static inline GElf_Addr
dwfl_adjusted_st_value(Dwfl_Module * mod,Elf * symelf,GElf_Addr addr)380 dwfl_adjusted_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
381 {
382 if (symelf == mod->main.elf)
383 return dwfl_adjusted_address (mod, addr);
384 if (symelf == mod->debug.elf)
385 return dwfl_adjusted_dwarf_addr (mod, addr);
386 return dwfl_adjusted_aux_sym_addr (mod, addr);
387 }
388
389 static inline GElf_Addr
dwfl_deadjust_st_value(Dwfl_Module * mod,Elf * symelf,GElf_Addr addr)390 dwfl_deadjust_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
391 {
392 if (symelf == mod->main.elf)
393 return dwfl_deadjust_address (mod, addr);
394 if (symelf == mod->debug.elf)
395 return dwfl_deadjust_dwarf_addr (mod, addr);
396 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 */
796