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