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