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