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